Coverage for src / local_deep_research / database / models / settings.py: 95%

56 statements  

« prev     ^ index     » next       coverage.py v7.12.0, created at 2026-01-11 00:51 +0000

1""" 

2Settings and configuration models. 

3Stores user preferences and API keys in encrypted database. 

4""" 

5 

6import enum 

7 

8from sqlalchemy import ( 

9 JSON, 

10 Boolean, 

11 Column, 

12 Enum, 

13 Float, 

14 Integer, 

15 String, 

16 Text, 

17 UniqueConstraint, 

18) 

19from sqlalchemy_utc import UtcDateTime, utcnow 

20 

21from .base import Base 

22 

23 

24class UserSettings(Base): 

25 """ 

26 User-specific settings stored in their encrypted database. 

27 Replaces the need for config files or unencrypted storage. 

28 """ 

29 

30 __tablename__ = "user_settings" 

31 

32 id = Column(Integer, primary_key=True) 

33 key = Column(String(255), unique=True, nullable=False, index=True) 

34 value = Column(JSON) 

35 category = Column(String(100)) 

36 description = Column(Text) 

37 created_at = Column(UtcDateTime, default=utcnow()) 

38 updated_at = Column(UtcDateTime, default=utcnow(), onupdate=utcnow()) 

39 

40 def __repr__(self): 

41 return f"<UserSettings(key='{self.key}', category='{self.category}')>" 

42 

43 

44class APIKey(Base): 

45 """ 

46 Encrypted storage for API keys. 

47 These are especially sensitive and benefit from database encryption. 

48 """ 

49 

50 __tablename__ = "api_keys" 

51 

52 id = Column(Integer, primary_key=True) 

53 provider = Column(String(100), unique=True, nullable=False, index=True) 

54 key = Column(Text, nullable=False) # Encrypted by SQLCipher 

55 description = Column(Text) 

56 is_active = Column(Boolean, default=True) 

57 created_at = Column(UtcDateTime, default=utcnow()) 

58 updated_at = Column(UtcDateTime, default=utcnow(), onupdate=utcnow()) 

59 last_used = Column(UtcDateTime) 

60 usage_count = Column(Integer, default=0) 

61 

62 def __repr__(self): 

63 # Never show the actual key in repr 

64 return f"<APIKey(provider='{self.provider}', active={self.is_active})>" 

65 

66 

67class SettingType(enum.Enum): 

68 """Types of settings.""" 

69 

70 APP = "app" 

71 LLM = "llm" 

72 SEARCH = "search" 

73 REPORT = "report" 

74 DATABASE = "database" 

75 

76 

77class Setting(Base): 

78 """ 

79 Global application settings (shared across users). 

80 For user-specific settings, use UserSettings. 

81 """ 

82 

83 __tablename__ = "settings" 

84 

85 id = Column(Integer, primary_key=True, index=True) 

86 key = Column(String(255), nullable=False, unique=True, index=True) 

87 value = Column(JSON, nullable=True) 

88 type = Column(Enum(SettingType), nullable=False, index=True) 

89 name = Column(String(255), nullable=False) 

90 description = Column(Text, nullable=True) 

91 category = Column(String(100), nullable=True, index=True) 

92 ui_element = Column(String(50), default="text", nullable=False) 

93 options = Column(JSON, nullable=True) # For select elements 

94 min_value = Column(Float, nullable=True) # For numeric inputs 

95 max_value = Column(Float, nullable=True) # For numeric inputs 

96 step = Column(Float, nullable=True) # For sliders 

97 visible = Column(Boolean, default=True, nullable=False) 

98 editable = Column(Boolean, default=True, nullable=False) 

99 env_var = Column(String(255), nullable=True) # Environment variable name 

100 created_at = Column(UtcDateTime, server_default=utcnow(), nullable=False) 

101 updated_at = Column( 

102 UtcDateTime, server_default=utcnow(), onupdate=utcnow(), nullable=False 

103 ) 

104 

105 __table_args__ = (UniqueConstraint("key", name="uix_settings_key"),) 

106 

107 def __repr__(self): 

108 return f"<Setting(key='{self.key}', type={self.type.value})>"