| import os | |
| import logging | |
| from typing import Optional | |
| from pydantic import BaseModel, field_validator, SecretStr, field_serializer | |
| from pydantic_settings import BaseSettings, SettingsConfigDict | |
| logging.basicConfig( | |
| level=logging.INFO, | |
| format='%(asctime)s - %(name)s - %(levelname)s - %(message)s' | |
| ) | |
| logger = logging.getLogger(__name__) | |
| class AppSettings(BaseModel): | |
| name: str = "SynthNet" | |
| id: str = "synth-net" | |
| version: str = "0.0.1" | |
| description: str = "The Synthetic Nomological Net: A search engine to identify conceptual overlap in measures in the behavioral sciences" | |
| author: str = "magnolia psychometrics GmbH" | |
| class PublicMetadata(BaseModel): | |
| name: str = "SynthNet" | |
| description: str = "The Synthetic Nomological Net: A search engine to identify conceptual overlap in measures in the behavioral sciences" | |
| author: str = "magnolia psychometrics GmbH" | |
| github_url: Optional[str] = "https://github.com/synth-science/synth-net" | |
| osf_url: Optional[str] = "https://osf.io/h3xgw" | |
| imprint_url: Optional[str] = "https://raw.githubusercontent.com/magnolia-psychometrics/public/refs/heads/main/imprint-en.md" | |
| data_privacy_url: Optional[str] = "https://raw.githubusercontent.com/magnolia-psychometrics/public/refs/heads/main/imprint-en.md" | |
| tos_url: Optional[str] = "https://github.com/magnolia-psychometrics/public/blob/main/tos-en.md" | |
| disclaimer_url: Optional[str] = "https://github.com/magnolia-psychometrics/public/blob/main/hf-disclaimer.md" | |
| class SearchSettings(BaseModel): | |
| item_examples: list[list] = [ | |
| ["I frequently engineer situations where I can casually roll up my pant legs to showcase my calf definition.", "My calf muscles are unremarkable and not worth drawing attention to. (R)", "I have strategically positioned mirrors in my home at angles that optimize calf muscle viewing during daily activities.", "When receiving compliments about my physique, I feel uncomfortable if someone specifically mentions my calves. (R)", "I believe my gastrocnemius and soleus development represents the pinnacle of human lower leg musculature and should be documented for posterity."], | |
| ["Receiving compliments is important to me.", "I rarely doubt my decisions or actions.", "I'm just like everybody else.(R)", "I'm skilled at persuading others to believe what I say.", "Being humble doesn't suit my personality.", "I consider myself to be truly exceptional.", "Gaining recognition and status is important to me.", "I'm destined for remarkable achievements."], | |
| ["People who claim to be lactose intolerant are simply seeking attention and making excuses to avoid social gatherings.", "I believe lactose intolerant individuals deserve the same respect and dietary accommodations as anyone else. (R)", "Lactose intolerance is a character flaw that could be overcome with sufficient willpower and determination.", "I would be willing to modify a dinner menu to ensure lactose intolerant guests can enjoy the meal comfortably. (R)", "The so-called \"lactose intolerance epidemic\" is largely fabricated by the almond milk industry to increase profits.", "I become suspicious of people's true intentions when they decline dairy products at social events."], | |
| ["Birds are sophisticated surveillance drones operated by government agencies to monitor civilian activity.", "The moon landing footage is authentic and represents humanity's genuine achievement in space exploration. (R)", "Major weather events are deliberately manufactured by shadow organizations using advanced atmospheric manipulation technology.", "Giraffes exist in nature and are not elaborate hoaxes perpetuated by zoos worldwide. (R)", "All mattress stores are fronts for money laundering operations, which explains why they're always empty yet remain in business.", "Finland is a real country with a legitimate government and population. (R)"], | |
| ] | |
| scale_examples: list[str] = [ | |
| "calf muscle modesty", "vanity", "self-centeredness", "megalomania", "sociopathy", "galaphobia", "lactophobia", "intolerant attitudes against lactose intolerance" | |
| ] | |
| class ModelServerSettings(BaseModel): | |
| server_url: str = "http://localhost:8001" | |
| item_model_path: str = None | |
| item_model_access_token: Optional[str] = None | |
| scale_model_path: str = None | |
| scale_model_access_token: Optional[str] = None | |
| device: Optional[str] = None | |
| class DatasetSettings(BaseModel): | |
| dataset_path: str = None | |
| encryption_key: Optional[str] = None | |
| class TrackingDBSettings(BaseModel): | |
| enabled: bool = True | |
| api_endpoint: Optional[str] = None | |
| anon_key: Optional[SecretStr] = None | |
| jwt_token: Optional[SecretStr] = None | |
| class Settings(BaseSettings): | |
| model_config = SettingsConfigDict( | |
| env_file=".env", | |
| env_nested_delimiter="__", | |
| frozen=True | |
| ) | |
| app: AppSettings = AppSettings() | |
| public: PublicMetadata = PublicMetadata() | |
| search: SearchSettings = SearchSettings() | |
| model: ModelServerSettings = ModelServerSettings() | |
| data: DatasetSettings = DatasetSettings() | |
| tracking_db: TrackingDBSettings = TrackingDBSettings() | |
| def validate_config(self) -> bool: | |
| from typing import get_origin, get_args | |
| is_valid = True | |
| missing = [] | |
| optional_set = [] | |
| def check_model(obj: BaseModel, prefix: str = ""): | |
| nonlocal is_valid | |
| for field_name, field_info in obj.model_fields.items(): | |
| value = getattr(obj, field_name) | |
| env_name = f"{prefix}{field_name}".upper() | |
| if isinstance(value, BaseModel): | |
| check_model(value, f"{env_name}__") | |
| continue | |
| annotation = field_info.annotation | |
| is_optional = ( | |
| get_origin(annotation) is Optional or | |
| type(None) in get_args(annotation) | |
| ) | |
| if not is_optional and value is None: | |
| missing.append(env_name) | |
| is_valid = False | |
| elif is_optional and value is not None: | |
| optional_set.append(env_name) | |
| check_model(self) | |
| if missing: | |
| logger.error(f"β Missing required environment variables: {', '.join(missing)}") | |
| else: | |
| logger.info("β Config: All required environment variables loaded") | |
| if optional_set: | |
| logger.info(f"β Config: Optional variables set: {', '.join(optional_set)}") | |
| if not self.tracking_db.enabled: | |
| logger.info("Tracking disabled in config / ENV, skipping DB write!") | |
| return is_valid | |
| config = Settings() | |
| config.validate_config() |