File size: 3,487 Bytes
7a88b43
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
"""
File with environment variables and general configuration logic.
Environment variables are loaded from `.env`, with default values as fallback.

For project metadata, pyproject.toml is used.
Complex types like lists are read as JSON-encoded strings.
"""

import tomllib
from pathlib import Path
from typing import Literal
from urllib.parse import quote_plus

from environs import Env
from pydantic import validator
from pydantic_settings import BaseSettings
from structlog.stdlib import BoundLogger


from app.core.logger import Logger

PROJECT_DIR = Path(__file__).parent.parent.parent
with open(f"{PROJECT_DIR}/pyproject.toml", "rb") as f:
    PYPROJECT_CONTENT = tomllib.load(f)["tool"]["poetry"]

env = Env()
env.read_env()

CORS_ALLOWED_HEADERS = list(map(str.strip, env.list("CORS_ALLOWED_HEADERS", ["*"])))
CORS_ORIGINS = list(map(str.strip, env.list("CORS_ORIGINS", ["http://localhost:3000"])))


class Settings(BaseSettings):
    # CORE SETTINGS
    ENVIRONMENT: Literal["DEV", "STG", "PROD"] = env.str("ENVIRONMENT", "DEV").upper()

    # CORS SETTINGS
    # BACKEND_CORS_ORIGINS: list[str] = env.list("BACKEND_CORS_ORIGINS", ["http://localhost:3000"])
    # BACKEND_CORS_HEADERS: list[str] = env.list("BACKEND_CORS_HEADERS", ["*"])
    # ALLOWED_HOSTS: list[str] = env.list("ALLOWED_HOSTS", ["*"])

    # LOG SETTINGS
    LOG_LEVEL: Literal["INFO", "DEBUG", "WARN", "ERROR"] = env.str("LOG_LEVEL", "INFO")
    LOG_JSON_FORMAT: bool = env.bool("LOG_JSON_FORMAT", False)

    # PROJECT NAME, VERSION AND DESCRIPTION
    PROJECT_NAME: str = PYPROJECT_CONTENT["name"]
    VERSION: str = PYPROJECT_CONTENT["version"]
    DESCRIPTION: str = PYPROJECT_CONTENT["description"]

    ROOT_PATH: str = env.str("ROOT_PATH", "")

    # DOCS SETTINGS
    DOCS_URL: str = f"{ROOT_PATH}/docs"
    OPENAPI_URL: str = f"{ROOT_PATH}/openapi.json"

    # POSTGRESQL DATABASE SETTINGS
    DATABASE_HOSTNAME: str = env.str("DATABASE_HOSTNAME")
    DATABASE_USER: str = env.str("DATABASE_USER")
    DATABASE_PASSWORD: str = env.str("DATABASE_PASSWORD")
    DATABASE_PORT: str = env.str("DATABASE_PORT", "5432")
    DATABASE_DB: str = env.str("DATABASE_DB")
    SQLALCHEMY_DATABASE_URI: str = ""

    @validator("SQLALCHEMY_DATABASE_URI")
    def _assemble_db_connection(cls, v: str, values: dict[str, str]) -> str:
        return "postgresql+asyncpg://{}:{}@{}:{}/{}".format(
            values["DATABASE_USER"],
            quote_plus(values["DATABASE_PASSWORD"]),
            values["DATABASE_HOSTNAME"],
            values["DATABASE_PORT"],
            values["DATABASE_DB"],
        )

    # UVICORN SETTINGS
    UVICORN_HOST: str = env.str("UVICORN_HOST", "0.0.0.0")
    UVICORN_PORT: int = env.int("UVICORN_PORT", 5001)

    CACHE_HOST: str = env.str("CACHE_HOST", "localhost")
    CACHE_PORT: int = env.int("CACHE_PORT", 11211)
    CACHE_TTL: int = env.int("CACHE_TTL", 300)

    BEDROCK_MODEL_ID: str = env.str("BEDROCK_MODEL_ID", "anthropic.claude-v2")
    BEDROCK_PROVIDER: str = env.str("BEDROCK_PROVIDER", "anthropic")
    AWS_ACCESS_KEY: str = env.str("AWS_ACCESS_KEY", "")
    AWS_SECRET_KEY: str = env.str("AWS_SECRET_KEY", "")
    AWS_REGION: str = env.str("AWS_REGION", "us-east-1")

    TOKENIZER_MODEL: str = env.str("TOKENIZER_MODEL")
    TOKEN_LIMIT_PER_REQUEST: int = env.int("TOKEN_LIMIT_PER_REQUEST", 20000)


settings: Settings = Settings()  # type: ignore

log: BoundLogger = Logger(
    json_logs=settings.LOG_JSON_FORMAT, log_level=settings.LOG_LEVEL
).setup_logging()