localvectordb_server.config module

LocalVectorDB Server Configuration

This module provides the configuration model and helpers used by the LocalVectorDB server (v1.0). Configuration objects are represented as dataclasses (DatabaseSettings, EmbeddingSettings, ServerSettings, BackupSettings, MigrationSettings, SecuritySettings) and composed by the Config container class. The module supports loading configuration from multiple sources and formats, merging overrides intelligently, and validating the resulting configuration.

Features: - Typed dataclass settings with validate() methods - Load from TOML, JSON - Load and override from environment variables (LVDB_ prefixed) - Generate TOML output and export Flask-compatible config - Intelligent merging that preserves non-default base values

Supported environment variables (prefix LVDB_): - Sectioned variables like LVDB_DATABASE_* LVDB_SERVER_* LVDB_EMBEDDING_* - Nested server security variables like LVDB_SERVER_SECURITY_*

See class docstrings for detailed field descriptions and validation rules.

class localvectordb_server.config.BaseSettings

Bases: ABC

abstractmethod validate() bool
copy()
update_from_dict(update_dict, raise_errors: bool = False)

Updates the attributes from a given dict.

class localvectordb_server.config.EmbeddingSettings(provider: str = 'ollama', model: str = 'nomic-embed-text', base_url: str | None = None, api_key: str | None = None, batch_size: int = 64, timeout: int = 30, max_retries: int = 3, config: Dict[str, ~typing.Any]=<factory>)

Bases: BaseSettings

Settings for embedding providers.

provider: str = 'ollama'
model: str = 'nomic-embed-text'
base_url: str | None = None
api_key: str | None = None
batch_size: int = 64
timeout: int = 30
max_retries: int = 3
config: Dict[str, Any]
validate()
__init__(provider: str = 'ollama', model: str = 'nomic-embed-text', base_url: str | None = None, api_key: str | None = None, batch_size: int = 64, timeout: int = 30, max_retries: int = 3, config: Dict[str, ~typing.Any]=<factory>) None
class localvectordb_server.config.DatabaseSettings(root_dir: str = './.lvdb', timeout: int = 300, connection_pool_size: int = 10, enable_gpu: bool = False, enable_fts: bool = True, faiss_index_type: Literal['IndexFlatL2', 'IndexFlatIP', 'IndexHNSWFlat', 'IndexLSH']='IndexFlatL2', faiss_index_hnsw_flat_neighbors: int | None = None, faiss_index_lsh_bits: int | None = None, mmap_index: bool = False, chunk_size: int = 500, chunk_overlap: int = 1, chunking_method: str = 'lines', default_metadata_schema: Dict[str, ~localvectordb.core.MetadataField]=<factory>)

Bases: BaseSettings

Settings related to database operations and connections

root_dir: str = './.lvdb'
timeout: int = 300
connection_pool_size: int = 10
enable_gpu: bool = False
enable_fts: bool = True
faiss_index_type: Literal['IndexFlatL2', 'IndexFlatIP', 'IndexHNSWFlat', 'IndexLSH'] = 'IndexFlatL2'
faiss_index_hnsw_flat_neighbors: int | None = None
faiss_index_lsh_bits: int | None = None
mmap_index: bool = False
chunk_size: int = 500
chunk_overlap: int = 1
chunking_method: str = 'lines'
default_metadata_schema: Dict[str, MetadataField]
validate()
__init__(root_dir: str = './.lvdb', timeout: int = 300, connection_pool_size: int = 10, enable_gpu: bool = False, enable_fts: bool = True, faiss_index_type: Literal['IndexFlatL2', 'IndexFlatIP', 'IndexHNSWFlat', 'IndexLSH']='IndexFlatL2', faiss_index_hnsw_flat_neighbors: int | None = None, faiss_index_lsh_bits: int | None = None, mmap_index: bool = False, chunk_size: int = 500, chunk_overlap: int = 1, chunking_method: str = 'lines', default_metadata_schema: Dict[str, ~localvectordb.core.MetadataField]=<factory>) None
class localvectordb_server.config.BackupSettings(enabled: bool = True, default_location: str = './backups', retention_days: int = 30, max_backups: int = 50, compression_type: Literal['gzip', 'lzma', 'none'] = 'gzip', compression_level: int = 6, auto_backup_enabled: bool = False, auto_backup_interval_hours: int = 24, auto_backup_type: Literal['full', 'incremental'] = 'incremental', backup_chunk_size: int = 1048576, verify_backups: bool = True)

Bases: BaseSettings

Settings for database backup operations.

enabled: bool = True
default_location: str = './backups'
retention_days: int = 30
max_backups: int = 50
compression_type: Literal['gzip', 'lzma', 'none'] = 'gzip'
compression_level: int = 6
auto_backup_enabled: bool = False
auto_backup_interval_hours: int = 24
auto_backup_type: Literal['full', 'incremental'] = 'incremental'
backup_chunk_size: int = 1048576
verify_backups: bool = True
validate()
__init__(enabled: bool = True, default_location: str = './backups', retention_days: int = 30, max_backups: int = 50, compression_type: Literal['gzip', 'lzma', 'none'] = 'gzip', compression_level: int = 6, auto_backup_enabled: bool = False, auto_backup_interval_hours: int = 24, auto_backup_type: Literal['full', 'incremental'] = 'incremental', backup_chunk_size: int = 1048576, verify_backups: bool = True) None
class localvectordb_server.config.MigrationSettings(enabled: bool = True, migration_dir: str = './migrations', auto_migrate: bool = False, backup_before_migration: bool = True, require_confirmation: bool = True, allow_destructive_migrations: bool = False, max_rollback_steps: int = 10, migration_template_author: str | None = None, migration_template_format: Literal['python', 'sql'] = 'python')

Bases: BaseSettings

Settings for database migration operations.

enabled: bool = True
migration_dir: str = './migrations'
auto_migrate: bool = False
backup_before_migration: bool = True
require_confirmation: bool = True
allow_destructive_migrations: bool = False
max_rollback_steps: int = 10
migration_template_author: str | None = None
migration_template_format: Literal['python', 'sql'] = 'python'
validate()
__init__(enabled: bool = True, migration_dir: str = './migrations', auto_migrate: bool = False, backup_before_migration: bool = True, require_confirmation: bool = True, allow_destructive_migrations: bool = False, max_rollback_steps: int = 10, migration_template_author: str | None = None, migration_template_format: Literal['python', 'sql'] = 'python') None
class localvectordb_server.config.ExtractionSettings(allow_remote_fetch: bool = False, allowed_hosts: List[str] | None = None, strip_dangerous_elements: bool = True, attachment_mode: str = 'skip')

Bases: BaseSettings

Settings for file-content extraction (powered by all2md).

These map onto the security-relevant options of the all2md-backed extractor. Defaults are hardened for untrusted uploads; relax them only for trusted content. The values are forwarded to the extractor as keyword arguments by extractor_kwargs().

allow_remote_fetch: bool = False
allowed_hosts: List[str] | None = None
strip_dangerous_elements: bool = True
attachment_mode: str = 'skip'
validate()
extractor_kwargs() Dict[str, Any]

Return the keyword arguments to forward to the extractor.

__init__(allow_remote_fetch: bool = False, allowed_hosts: List[str] | None = None, strip_dangerous_elements: bool = True, attachment_mode: str = 'skip') None
class localvectordb_server.config.SecuritySettings(require_api_key: bool = False, api_key_header: str = 'Authorization', trusted_hosts: List[str] | None = None, key_database_path: str | None = None, default_key_expiry_days: int | None = None, auto_prune_expired_keys: bool = False, key_audit_logging: bool = True, auth_log_level: str = 'INFO', warn_expiring_days: int = 7, cors_enabled: bool = True, cors_allowed_origins: str | List[str] = '*', cors_allowed_methods: List[str] = <factory>, cors_allowed_headers: List[str] = <factory>, cors_max_age: int = 86400, security_headers_enabled: bool = True, force_https: bool = False, strict_transport_security: bool = True, strict_transport_security_max_age: int = 31536000, content_security_policy: dict = <factory>, content_type_nosniff: bool = True, x_frame_options: str = 'DENY', x_xss_protection: bool = True, referrer_policy: str = 'strict-origin-when-cross-origin')

Bases: BaseSettings

Security-related settings for the server.

require_api_key: bool = False
api_key_header: str = 'Authorization'
trusted_hosts: List[str] | None = None
key_database_path: str | None = None
default_key_expiry_days: int | None = None
auto_prune_expired_keys: bool = False
key_audit_logging: bool = True
auth_log_level: str = 'INFO'
warn_expiring_days: int = 7
cors_enabled: bool = True
cors_allowed_origins: str | List[str] = '*'
cors_allowed_methods: List[str]
cors_allowed_headers: List[str]
cors_max_age: int = 86400
security_headers_enabled: bool = True
force_https: bool = False
strict_transport_security: bool = True
strict_transport_security_max_age: int = 31536000
content_security_policy: dict
content_type_nosniff: bool = True
x_frame_options: str = 'DENY'
x_xss_protection: bool = True
referrer_policy: str = 'strict-origin-when-cross-origin'
validate()
__init__(require_api_key: bool = False, api_key_header: str = 'Authorization', trusted_hosts: List[str] | None = None, key_database_path: str | None = None, default_key_expiry_days: int | None = None, auto_prune_expired_keys: bool = False, key_audit_logging: bool = True, auth_log_level: str = 'INFO', warn_expiring_days: int = 7, cors_enabled: bool = True, cors_allowed_origins: str | List[str] = '*', cors_allowed_methods: List[str] = <factory>, cors_allowed_headers: List[str] = <factory>, cors_max_age: int = 86400, security_headers_enabled: bool = True, force_https: bool = False, strict_transport_security: bool = True, strict_transport_security_max_age: int = 31536000, content_security_policy: dict = <factory>, content_type_nosniff: bool = True, x_frame_options: str = 'DENY', x_xss_protection: bool = True, referrer_policy: str = 'strict-origin-when-cross-origin') None
class localvectordb_server.config.ServerSettings(debug: bool = False, environment: str = 'development', host: str = '127.0.0.1', port: int = 8000, log_level: str = 'INFO', log_format: str = '%(asctime)s - %(name)s - %(levelname)s - %(message)s', file_upload_enabled: bool = False, max_request_size: int = 10485760, enable_structured_logging: bool | None = None, enable_performance_logging: bool = False, enable_rate_limiting: bool = False, rate_limit: str = '100 per minute', rate_limit_storage_uri: str = 'memory://', cache_enabled: bool = False, cache_ignore_errors: bool = True, cache_timeout: int = 300, cache_key_prefix: str = 'lvdb_cache_', cache_type: Literal['SimpleCache', 'RedisCache', 'FileSystemCache', 'MemcachedCache', 'UWSGICache', 'DynamoDbCache', 'MongoDbCache', 'NullCache']='SimpleCache', cache_settings: dict | None = None, redis_host: str = 'localhost', redis_port: int = 6379, redis_password: str | None = None, redis_db: int = 0, redis_url: str | None = None, redis_socket_timeout: float | None = None, redis_socket_connect_timeout: float | None = None, filesystem_cache_dir: str | None = None, filesystem_cache_threshold: int = 500, memcached_servers: List[str] = <factory>, memcached_username: str | None = None, memcached_password: str | None = None, db_registry_type: Literal['SimpleCache', 'RedisCache', 'FileSystemCache', 'MemcachedCache', 'UWSGICache', 'DynamoDbCache', 'MongoDbCache', 'NullCache']='SimpleCache', db_registry_settings: dict | None = None, use_single_cache: bool = False, proxy_enabled: bool = False, proxy_settings: dict | None = None, trusted_proxies: List[str] = <factory>, security: SecuritySettings = <factory>)

Bases: BaseSettings

Settings related to the flask API server

debug: bool = False
environment: str = 'development'
host: str = '127.0.0.1'
port: int = 8000
log_level: str = 'INFO'
log_format: str = '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
file_upload_enabled: bool = False
max_request_size: int = 10485760
enable_structured_logging: bool | None = None
enable_performance_logging: bool = False
enable_rate_limiting: bool = False
rate_limit: str = '100 per minute'
rate_limit_storage_uri: str = 'memory://'
cache_enabled: bool = False
cache_ignore_errors: bool = True
cache_timeout: int = 300
cache_key_prefix: str = 'lvdb_cache_'
cache_type: Literal['SimpleCache', 'RedisCache', 'FileSystemCache', 'MemcachedCache', 'UWSGICache', 'DynamoDbCache', 'MongoDbCache', 'NullCache'] = 'SimpleCache'
cache_settings: dict | None = None
redis_host: str = 'localhost'
redis_port: int = 6379
redis_password: str | None = None
redis_db: int = 0
redis_url: str | None = None
redis_socket_timeout: float | None = None
redis_socket_connect_timeout: float | None = None
filesystem_cache_dir: str | None = None
filesystem_cache_threshold: int = 500
memcached_servers: List[str]
memcached_username: str | None = None
memcached_password: str | None = None
db_registry_type: Literal['SimpleCache', 'RedisCache', 'FileSystemCache', 'MemcachedCache', 'UWSGICache', 'DynamoDbCache', 'MongoDbCache', 'NullCache'] = 'SimpleCache'
db_registry_settings: dict | None = None
use_single_cache: bool = False
proxy_enabled: bool = False
proxy_settings: dict | None = None
trusted_proxies: List[str]
security: SecuritySettings
validate()
__init__(debug: bool = False, environment: str = 'development', host: str = '127.0.0.1', port: int = 8000, log_level: str = 'INFO', log_format: str = '%(asctime)s - %(name)s - %(levelname)s - %(message)s', file_upload_enabled: bool = False, max_request_size: int = 10485760, enable_structured_logging: bool | None = None, enable_performance_logging: bool = False, enable_rate_limiting: bool = False, rate_limit: str = '100 per minute', rate_limit_storage_uri: str = 'memory://', cache_enabled: bool = False, cache_ignore_errors: bool = True, cache_timeout: int = 300, cache_key_prefix: str = 'lvdb_cache_', cache_type: Literal['SimpleCache', 'RedisCache', 'FileSystemCache', 'MemcachedCache', 'UWSGICache', 'DynamoDbCache', 'MongoDbCache', 'NullCache']='SimpleCache', cache_settings: dict | None = None, redis_host: str = 'localhost', redis_port: int = 6379, redis_password: str | None = None, redis_db: int = 0, redis_url: str | None = None, redis_socket_timeout: float | None = None, redis_socket_connect_timeout: float | None = None, filesystem_cache_dir: str | None = None, filesystem_cache_threshold: int = 500, memcached_servers: List[str] = <factory>, memcached_username: str | None = None, memcached_password: str | None = None, db_registry_type: Literal['SimpleCache', 'RedisCache', 'FileSystemCache', 'MemcachedCache', 'UWSGICache', 'DynamoDbCache', 'MongoDbCache', 'NullCache']='SimpleCache', db_registry_settings: dict | None = None, use_single_cache: bool = False, proxy_enabled: bool = False, proxy_settings: dict | None = None, trusted_proxies: List[str] = <factory>, security: SecuritySettings = <factory>) None
class localvectordb_server.config.Config(database: DatabaseSettings = <factory>, embedding: EmbeddingSettings = <factory>, server: ServerSettings = <factory>, backup: BackupSettings = <factory>, migration: MigrationSettings = <factory>, extraction: ExtractionSettings = <factory>)

Bases: object

Main configuration container with v1.0 enhancements.

database: DatabaseSettings
embedding: EmbeddingSettings
server: ServerSettings
backup: BackupSettings
migration: MigrationSettings
extraction: ExtractionSettings
validate()
classmethod from_file(path: str | Path) Config

Load configuration from file with v1.0 enhancements.

classmethod from_dict(data: dict) Config

Create config from dictionary with v1.0 support.

classmethod from_env(base=None, prefix: str = 'LVDB_') Config

Load configuration from environment variables with v1.0 support.

classmethod update_from_dict(config: Config, update_map: dict) Config
to_flask_config() Dict[str, Any]

Convert to format expected by Flask app.config with v1.0 support.

generate_toml() str

Generate enhanced TOML configuration for v1.0 using tomli-w.

to_dict()
apply_common_schema(schema_name: str)

Apply a predefined metadata schema.

merge(other: Config) Config

Enhanced merge that respects non-default values in base config.

Only applies override values if they are explicitly different from defaults, preserving custom base config values when override contains defaults.

__init__(database: DatabaseSettings = <factory>, embedding: EmbeddingSettings = <factory>, server: ServerSettings = <factory>, backup: BackupSettings = <factory>, migration: MigrationSettings = <factory>, extraction: ExtractionSettings = <factory>) None
localvectordb_server.config.load_config(configuration: str | Config | None = None, validate: bool = True, verbose: bool = False, apply_schema: str | None = None) Config

Load and construct a Config object from various sources.

This function provides a flexible interface for creating a Config instance using one or more of the supported input mechanisms (explicit Config instance, dict, configuration file path, environment variables, and predefined metadata schemas). The resulting Config will start from the library defaults, optionally have a common metadata schema applied, be merged with the provided configuration source, have environment variables applied, and can be validated before being returned.

Parameters:
  • configuration (Union[str, Config, None], optional) –

    Source of configuration to load. May be:

    • a path to a configuration file (TOML, JSON, or INI), in which case the file will be loaded if it exists;

    • a Config instance, which will be merged into defaults;

    • a dict mapping section names (“database”, “embedding”, “server”, “backup”, “migration”) to dicts of values for those sections;

    • None, in which case defaults are used and the LVDB_SERVER_CONFIG environment variable is consulted for a file path.

  • validate (bool, optional) – If True (default), call Config.validate() on the resulting configuration and raise ConfigurationError on validation failures.

  • verbose (bool, optional) – If True, print progress/debug messages to stderr using click.secho. Defaults to False.

  • apply_schema (Optional[str], optional) – If provided, the named common metadata schema (from get_common_metadata_schemas()) will be applied to database.default_metadata_schema before other configuration sources are merged.

Returns:

The constructed (and optionally validated) configuration object.

Return type:

Config

Raises:
  • ConfigurationError – If loading or validation fails.

  • FileNotFoundError – If attempting to load from a configuration file path that does not exist.

  • ValueError – If a provided configuration file has an unsupported suffix/format.

  • TypeError – If configuration is not a supported type.