Coverage for src/qdrant_loader/config/state.py: 82%
55 statements
« prev ^ index » next coverage.py v7.8.2, created at 2025-06-04 05:50 +0000
« prev ^ index » next coverage.py v7.8.2, created at 2025-06-04 05:50 +0000
1"""State management configuration.
3This module defines the configuration settings for state management,
4including database path, table prefix, and connection pool settings.
5"""
7import os
8from pathlib import Path
9from typing import Any
11from pydantic import Field, ValidationInfo, field_validator
13from qdrant_loader.config.base import BaseConfig
16class DatabaseDirectoryError(Exception):
17 """Exception raised when database directory needs to be created."""
19 def __init__(self, path: Path):
20 self.path = path
21 super().__init__(f"Database directory does not exist: {path}")
24class IngestionStatus:
25 """Enum-like class for ingestion status values."""
27 SUCCESS = "success"
28 FAILED = "failed"
29 IN_PROGRESS = "in_progress"
30 SKIPPED = "skipped"
31 CANCELLED = "cancelled"
34class StateManagementConfig(BaseConfig):
35 """Configuration for state management."""
37 database_path: str = Field(..., description="Path to SQLite database file")
38 table_prefix: str = Field(
39 default="qdrant_loader_", description="Prefix for database tables"
40 )
41 connection_pool: dict[str, Any] = Field(
42 default_factory=lambda: {"size": 5, "timeout": 30},
43 description="Connection pool settings",
44 )
46 @field_validator("database_path")
47 @classmethod
48 def validate_database_path(cls, v: str, info: ValidationInfo) -> str:
49 """Validate database path."""
50 # Expand environment variables, including $HOME
51 path = Path(os.path.expanduser(os.path.expandvars(v)))
52 parent_dir = path.parent
54 if not parent_dir.exists():
55 raise DatabaseDirectoryError(parent_dir)
57 if not parent_dir.is_dir():
58 raise ValueError("Database path is not a directory")
60 if not os.access(parent_dir, os.W_OK):
61 raise ValueError("Database directory is not writable")
63 return v
65 @field_validator("table_prefix")
66 @classmethod
67 def validate_table_prefix(cls, v: str, info: ValidationInfo) -> str:
68 """Validate table prefix format."""
69 if not v:
70 raise ValueError("Table prefix cannot be empty")
71 if not v.replace("_", "").isalnum():
72 raise ValueError(
73 "Table prefix can only contain alphanumeric characters and underscores"
74 )
75 return v
77 @field_validator("connection_pool")
78 @classmethod
79 def validate_connection_pool(
80 cls, v: dict[str, Any], info: ValidationInfo
81 ) -> dict[str, Any]:
82 """Validate connection pool settings."""
83 if "size" not in v:
84 raise ValueError("Connection pool must specify 'size'")
85 if not isinstance(v["size"], int) or v["size"] < 1:
86 raise ValueError("Connection pool size must be a positive integer")
88 if "timeout" not in v:
89 raise ValueError("Connection pool must specify 'timeout'")
90 if not isinstance(v["timeout"], int) or v["timeout"] < 1:
91 raise ValueError("Connection pool timeout must be a positive integer")
93 return v
95 def __init__(self, **data):
96 """Initialize state management configuration."""
97 # If database_path is not provided, use in-memory database
98 if "database_path" not in data:
99 data["database_path"] = ":memory:"
100 super().__init__(**data)