- Introduced a comprehensive API contract for the WonderQ-MiniAPP, detailing endpoints for site configuration, product listings, and lead submissions. - Defined data types for various entities including HeroSlide, Destination, Theme, CtaBanner, PublicProduct, and more. - Specified request and response formats, including error handling guidelines. chore: Update requirements to include python-multipart - Added python-multipart dependency to requirements.txt for handling file uploads. test: Implement API contract tests - Created test suite for API contracts, validating serializers and endpoints for public products and leads. - Included tests for destination and product serializers, ensuring correct data handling and validation. test: Add configuration tests for OSS settings - Implemented tests to verify that OSS settings are correctly loaded from environment variables.
34 lines
1.4 KiB
Python
34 lines
1.4 KiB
Python
from functools import lru_cache
|
|
from urllib.parse import parse_qsl, urlencode, urlsplit, urlunsplit
|
|
from pydantic import Field
|
|
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
|
|
|
|
class Settings(BaseSettings):
|
|
database_url: str = Field(default="postgresql://miniapp:miniapp_dev_password@localhost:5433/miniapp")
|
|
jwt_secret: str = Field(default="dev-only-change-me-before-production")
|
|
jwt_expires_hours: int = Field(default=8)
|
|
log_level: str = Field(default="info")
|
|
port: int = Field(default=4000)
|
|
cors_origins: str = Field(default="*")
|
|
oss_access_key_id: str | None = Field(default=None)
|
|
oss_access_key_secret: str | None = Field(default=None)
|
|
oss_endpoint: str | None = Field(default=None)
|
|
oss_bucket_name: str | None = Field(default=None)
|
|
|
|
model_config = SettingsConfigDict(env_file=".env", env_file_encoding="utf-8", extra="ignore")
|
|
|
|
@property
|
|
def sqlalchemy_url(self) -> str:
|
|
parsed = urlsplit(self.database_url)
|
|
query = urlencode([(key, value) for key, value in parse_qsl(parsed.query, keep_blank_values=True) if key != "schema"])
|
|
normalized = urlunsplit((parsed.scheme, parsed.netloc, parsed.path, query, parsed.fragment))
|
|
if normalized.startswith("postgresql://"):
|
|
return normalized.replace("postgresql://", "postgresql+psycopg://", 1)
|
|
return normalized
|
|
|
|
|
|
@lru_cache
|
|
def get_settings() -> Settings:
|
|
return Settings()
|