Add navigation header to /config page

parent efb7f521
...@@ -4,6 +4,12 @@ ...@@ -4,6 +4,12 @@
{% block head %} {% block head %}
<style> <style>
.header { background: white; padding: 1rem 2rem; box-shadow: 0 1px 3px rgba(0,0,0,0.1); }
.header-content { display: flex; justify-content: space-between; align-items: center; max-width: 1200px; margin: 0 auto; }
.logo { font-size: 1.5rem; font-weight: 700; color: #667eea; }
.nav { display: flex; gap: 2rem; }
.nav a { text-decoration: none; color: #64748b; font-weight: 500; }
.nav a.active { color: #667eea; }
.config-container { max-width: 800px; margin: 2rem auto; background: white; padding: 2rem; border-radius: 12px; box-shadow: 0 4px 12px rgba(0,0,0,0.1); } .config-container { max-width: 800px; margin: 2rem auto; background: white; padding: 2rem; border-radius: 12px; box-shadow: 0 4px 12px rgba(0,0,0,0.1); }
.config-title { color: #333; text-align: center; margin-bottom: 2rem; font-size: 2rem; font-weight: 600; } .config-title { color: #333; text-align: center; margin-bottom: 2rem; font-size: 2rem; font-weight: 600; }
.config-form { margin-bottom: 2rem; } .config-form { margin-bottom: 2rem; }
...@@ -17,6 +23,15 @@ ...@@ -17,6 +23,15 @@
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<header class="header">
<div class="header-content">
<div class="logo">VidAI</div>
<nav class="nav">
<a href="/">Home</a>
<a href="/config" class="active">Configuration</a>
</nav>
</div>
</header>
<div class="config-container"> <div class="config-container">
<h1 class="config-title">Configuration</h1> <h1 class="config-title">Configuration</h1>
<form method="post" class="config-form"> <form method="post" class="config-form">
......
# Video AI Configuration File
# This is a sample configuration file for Video AI.
# Copy this file to ~/.config/vidai/vidai.conf or /etc/vidai.conf
# Configuration values can also be set via environment variables (VIDAI_* prefix)
# or command line arguments (highest precedence)
[database]
# Database backend configuration
db_type = sqlite
db_sqlite_path = vidai.db
# For MySQL, change db_type to mysql and configure:
# db_type = mysql
# db_mysql_host = localhost
# db_mysql_port = 3306
# db_mysql_user = vidai
# db_mysql_password = your_password
# db_mysql_database = vidai
# db_mysql_charset = utf8mb4
[backends]
# GPU backends for analysis and training
# analysis_backend = cuda
# training_backend = cuda
[runpod]
# RunPod cloud processing integration
# runpod_enabled = false
# runpod_api_key =
# runpod_template_id = vidai-analysis-latest
# runpod_gpu_type = NVIDIA RTX A4000
# use_runpod_pods = false
[model]
# Default AI model configuration
# default_model = Qwen/Qwen2.5-VL-7B-Instruct
# default_model_type = auto
# frame_interval = 10
[processing]
# Video processing options
# optimize = false
# ffmpeg = false
# flash = false
[server]
# Web server configuration
# host = 0.0.0.0
# port = 5000
# debug = false
# allowed_dir =
[communication]
# Inter-process communication settings
# comm_type = unix
# max_concurrent_jobs = 1
[cluster]
# Distributed processing cluster configuration
# cluster_host =
# cluster_port = 5003
# cluster_token =
# cluster_client = false
[users]
# User management and registration
# allow_registration = true
# default_user_tokens = 100
# token_price_usd = 0.10
[email]
# SMTP email configuration
# smtp_server = smtp.gmail.com
# smtp_port = 587
# smtp_username =
# smtp_password =
# smtp_use_tls = true
# smtp_use_ssl = false
[payments]
# Payment gateway configuration
# stripe_publishable_key =
# stripe_secret_key =
# paypal_client_id =
# paypal_client_secret =
# btc_payment_address =
# eth_payment_address =
[application]
# General application settings
# base_url = http://localhost:5000
[network]
# Network configuration for different services
# web_host = 0.0.0.0
# web_port = 5000
# backend_host = localhost
# backend_web_port = 5001
# backend_worker_port = 5002
[security]
# Security and authentication settings
# jwt_secret_key = vidai-jwt-secret-key-change-in-production
\ No newline at end of file
...@@ -32,6 +32,7 @@ from vidai.compat import run_command, get_python_command ...@@ -32,6 +32,7 @@ from vidai.compat import run_command, get_python_command
sys.path.insert(0, os.path.dirname(__file__)) sys.path.insert(0, os.path.dirname(__file__))
from vidai.config import ( from vidai.config import (
initialize_config,
get_config, set_config, get_default_model, set_default_model, get_config, set_config, get_default_model, set_default_model,
get_default_model_type, set_default_model_type, get_default_model_type, set_default_model_type,
get_analysis_backend, set_analysis_backend, get_training_backend, set_training_backend, get_analysis_backend, set_analysis_backend, get_training_backend, set_training_backend,
...@@ -212,6 +213,57 @@ Examples: ...@@ -212,6 +213,57 @@ Examples:
help='Enable debug mode' help='Enable debug mode'
) )
# Database configuration options
parser.add_argument(
'--db-type',
choices=['sqlite', 'mysql'],
default=get_config('db_type', 'sqlite'),
help='Database type (default: sqlite)'
)
parser.add_argument(
'--db-sqlite-path',
default=get_config('db_sqlite_path', 'vidai.db'),
help='SQLite database file path'
)
parser.add_argument(
'--db-mysql-host',
default=get_config('db_mysql_host', 'localhost'),
help='MySQL database host'
)
parser.add_argument(
'--db-mysql-port',
type=int,
default=int(get_config('db_mysql_port', '3306')),
help='MySQL database port'
)
parser.add_argument(
'--db-mysql-user',
default=get_config('db_mysql_user', 'vidai'),
help='MySQL database user'
)
parser.add_argument(
'--db-mysql-password',
default=get_config('db_mysql_password', ''),
help='MySQL database password'
)
parser.add_argument(
'--db-mysql-database',
default=get_config('db_mysql_database', 'vidai'),
help='MySQL database name'
)
parser.add_argument(
'--db-mysql-charset',
default=get_config('db_mysql_charset', 'utf8mb4'),
help='MySQL database charset'
)
# Cluster options # Cluster options
parser.add_argument( parser.add_argument(
'--cluster-host', '--cluster-host',
...@@ -253,6 +305,9 @@ Examples: ...@@ -253,6 +305,9 @@ Examples:
args = parser.parse_args() args = parser.parse_args()
# Initialize configuration with CLI precedence
initialize_config(args)
# Update config with command line values # Update config with command line values
set_default_model(args.model) set_default_model(args.model)
set_default_model_type(args.model_type) set_default_model_type(args.model_type)
...@@ -276,6 +331,13 @@ Examples: ...@@ -276,6 +331,13 @@ Examples:
set_cluster_token(args.token) set_cluster_token(args.token)
set_cluster_client(args.client) set_cluster_client(args.client)
# Database config
from vidai.config import set_db_type, set_db_sqlite_path, set_db_mysql_config
set_db_type(args.db_type)
set_db_sqlite_path(args.db_sqlite_path)
set_db_mysql_config(args.db_mysql_host, args.db_mysql_port, args.db_mysql_user,
args.db_mysql_password, args.db_mysql_database, args.db_mysql_charset)
# Check if running in client mode # Check if running in client mode
if args.client: if args.client:
if not args.cluster_host or not args.cluster_port or not args.token: if not args.cluster_host or not args.cluster_port or not args.token:
......
...@@ -17,12 +17,36 @@ ...@@ -17,12 +17,36 @@
""" """
Configuration management for Video AI. Configuration management for Video AI.
Handles backend selection for analysis and training. Handles backend selection for analysis and training.
Uses SQLite database for persistence. Uses SQLite/MySQL database for persistence.
Supports CLI, config file, environment variables, and defaults.
""" """
from .config_loader import load_initial_config, DEFAULTS
from .database import get_config, set_config, get_all_config, get_system_prompt, set_system_prompt from .database import get_config, set_config, get_all_config, get_system_prompt, set_system_prompt
def initialize_config(cli_args=None) -> None:
"""Initialize configuration by loading from sources and storing env vars."""
import os
from .config_loader import set_cli_args
set_cli_args(cli_args)
initial_config = load_initial_config(cli_args)
# Store all environment variables that start with VIDAI_
for env_key, env_value in os.environ.items():
if env_key.startswith('VIDAI_'):
config_key = env_key[6:].lower() # Remove VIDAI_ prefix
if config_key in DEFAULTS:
set_config(config_key, env_value)
# Ensure database config is set
for key in ['db_type', 'db_sqlite_path', 'db_mysql_host', 'db_mysql_port',
'db_mysql_user', 'db_mysql_password', 'db_mysql_database', 'db_mysql_charset']:
if key in initial_config:
set_config(key, initial_config[key])
def get_analysis_backend() -> str: def get_analysis_backend() -> str:
"""Get the selected backend for analysis.""" """Get the selected backend for analysis."""
return get_config('analysis_backend', 'cuda') return get_config('analysis_backend', 'cuda')
...@@ -317,6 +341,11 @@ def get_all_settings() -> dict: ...@@ -317,6 +341,11 @@ def get_all_settings() -> dict:
} }
def set_base_url(url: str) -> None:
"""Set base URL for the application."""
set_config('base_url', url)
# Registration and user management settings # Registration and user management settings
def set_allow_registration(allow: bool) -> None: def set_allow_registration(allow: bool) -> None:
"""Enable/disable user registration.""" """Enable/disable user registration."""
...@@ -390,11 +419,6 @@ def set_crypto_addresses(btc_address: str, eth_address: str) -> None: ...@@ -390,11 +419,6 @@ def set_crypto_addresses(btc_address: str, eth_address: str) -> None:
set_config('eth_payment_address', eth_address) set_config('eth_payment_address', eth_address)
def set_base_url(url: str) -> None:
"""Set base URL for the application."""
set_config('base_url', url)
# Database settings # Database settings
def set_db_type(db_type: str) -> None: def set_db_type(db_type: str) -> None:
"""Set database type (sqlite or mysql).""" """Set database type (sqlite or mysql)."""
......
# Video AI Configuration Loader
# Copyright (C) 2024 Stefy Lanza <stefy@sexhack.me>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
Configuration loader for Video AI.
Handles loading from CLI, config file, environment variables, and defaults.
"""
import os
import configparser
from pathlib import Path
# Global CLI args for precedence
_cli_args = None
def set_cli_args(args):
"""Set CLI arguments for config loading."""
global _cli_args
_cli_args = args
# Default configuration values
DEFAULTS = {
'db_type': 'sqlite',
'db_sqlite_path': 'vidai.db',
'db_mysql_host': 'localhost',
'db_mysql_port': '3306',
'db_mysql_user': 'vidai',
'db_mysql_password': '',
'db_mysql_database': 'vidai',
'db_mysql_charset': 'utf8mb4',
'analysis_backend': 'cuda',
'training_backend': 'cuda',
'runpod_enabled': 'false',
'runpod_api_key': '',
'runpod_template_id': 'vidai-analysis-latest',
'runpod_gpu_type': 'NVIDIA RTX A4000',
'use_runpod_pods': 'false',
'default_model': 'Qwen/Qwen2.5-VL-7B-Instruct',
'default_model_type': 'auto',
'frame_interval': '10',
'optimize': 'false',
'ffmpeg': 'false',
'flash': 'false',
'host': '0.0.0.0',
'port': '5000',
'debug': 'false',
'allowed_dir': '',
'comm_type': 'unix',
'max_concurrent_jobs': '1',
'cluster_host': '',
'cluster_port': '5003',
'cluster_token': '',
'cluster_client': 'false',
'allow_registration': 'true',
'default_user_tokens': '100',
'token_price_usd': '0.10',
'smtp_server': 'smtp.gmail.com',
'smtp_port': '587',
'smtp_username': '',
'smtp_password': '',
'smtp_use_tls': 'true',
'smtp_use_ssl': 'false',
'stripe_publishable_key': '',
'stripe_secret_key': '',
'paypal_client_id': '',
'paypal_client_secret': '',
'btc_payment_address': '',
'eth_payment_address': '',
'base_url': 'http://localhost:5000',
'web_host': '0.0.0.0',
'web_port': '5000',
'backend_host': 'localhost',
'backend_web_port': '5001',
'backend_worker_port': '5002',
'jwt_secret_key': 'vidai-jwt-secret-key-change-in-production'
}
def load_initial_config(cli_args=None) -> dict:
"""Load configuration with precedence: CLI > config file > env vars > defaults."""
config = DEFAULTS.copy()
# Use provided cli_args or global
args = cli_args or _cli_args
# 1. Load from config files (lower precedence than env, but higher than defaults)
config_files = [
Path.home() / '.config' / 'vidai' / 'vidai.conf',
Path('/etc/vidai.conf')
]
for config_file in config_files:
if config_file.exists():
parser = configparser.ConfigParser()
parser.read(config_file)
# Read from all sections, flattening into config dict
for section_name in parser.sections():
section = parser[section_name]
for key, value in section.items():
if key in config:
config[key] = value
# Also read DEFAULT section
if 'DEFAULT' in parser:
for key, value in parser['DEFAULT'].items():
if key in config:
config[key] = value
break # Use first found file
# 2. Load from environment variables (VIDAI_* prefix)
for key in config.keys():
env_key = f'VIDAI_{key.upper()}'
env_value = os.environ.get(env_key)
if env_value is not None:
config[key] = env_value
# 3. Load from CLI arguments (highest precedence)
if args:
for key in config.keys():
cli_key = key.replace('_', '-')
if hasattr(args, cli_key) and getattr(args, cli_key) is not None:
config[key] = str(getattr(args, cli_key))
return config
\ No newline at end of file
...@@ -41,9 +41,10 @@ except ImportError: ...@@ -41,9 +41,10 @@ except ImportError:
# Database configuration # Database configuration
def get_db_config() -> Dict[str, Any]: def get_db_config() -> Dict[str, Any]:
"""Get database configuration.""" """Get database configuration."""
# Use environment variables or defaults to avoid circular dependency # Use the new config loader to avoid circular dependency
# The database type should be set via environment or config file initially from .config_loader import load_initial_config
db_type = os.environ.get('VIDAI_DB_TYPE', 'sqlite') initial_config = load_initial_config()
db_type = initial_config['db_type']
if db_type == 'mysql': if db_type == 'mysql':
from .config import get_config from .config import get_config
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment