[feat] Docker-first configuration
This commit is contained in:
parent
0819d4bb85
commit
b920ee56fb
4 changed files with 810 additions and 858 deletions
27
Dockerfile
27
Dockerfile
|
@ -1,8 +1,27 @@
|
|||
FROM python:3.10
|
||||
FROM python:3.12-bookworm as builder
|
||||
|
||||
RUN pip install poetry==1.7.1
|
||||
|
||||
ENV POETRY_NO_INTERACTION=1 \
|
||||
POETRY_VIRTUALENVS_IN_PROJECT=1 \
|
||||
POETRY_VIRTUALENVS_CREATE=1 \
|
||||
POETRY_CACHE_DIR=/tmp/poetry_cache
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY . /app
|
||||
RUN pip install --no-cache-dir .
|
||||
COPY pyproject.toml poetry.lock README.md ./
|
||||
|
||||
CMD [ "python", "run.py" ]
|
||||
RUN poetry install --without dev --no-root && rm -rf $POETRY_CACHE_DIR
|
||||
|
||||
FROM python:3.12-slim-bookworm as runtime
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
ENV VIRTUAL_ENV=/app/.venv \
|
||||
PATH="/app/.venv/bin:$PATH"
|
||||
|
||||
COPY --from=builder ${VIRTUAL_ENV} ${VIRTUAL_ENV}
|
||||
|
||||
COPY . /app/
|
||||
|
||||
CMD [ "python", "run.py" ]
|
||||
|
|
|
@ -1,19 +1,9 @@
|
|||
"""Task config."""
|
||||
|
||||
from enum import Enum
|
||||
from os import environ
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
import orjson as json
|
||||
import yaml
|
||||
from dotenv import load_dotenv
|
||||
from jarvis_core.util import find_all
|
||||
from pydantic import BaseModel
|
||||
|
||||
try:
|
||||
from yaml import CLoader as Loader
|
||||
except ImportError:
|
||||
from yaml import Loader
|
||||
from pydantic_settings import BaseSettings, SettingsConfigDict
|
||||
|
||||
|
||||
class Environment(Enum):
|
||||
|
@ -23,7 +13,7 @@ class Environment(Enum):
|
|||
develop = "develop"
|
||||
|
||||
|
||||
class Mongo(BaseModel):
|
||||
class Mongo(BaseSettings):
|
||||
"""MongoDB config."""
|
||||
|
||||
host: list[str] | str = "localhost"
|
||||
|
@ -32,76 +22,19 @@ class Mongo(BaseModel):
|
|||
port: int = 27017
|
||||
|
||||
|
||||
class Config(BaseModel):
|
||||
class Config(BaseSettings, case_sensitive=False):
|
||||
"""Tasks config model."""
|
||||
|
||||
token: str
|
||||
mongo: Mongo
|
||||
mongo: Mongo = Mongo()
|
||||
log_level: str = "INFO"
|
||||
environment: Environment = Environment.develop
|
||||
|
||||
|
||||
_config: Config = None
|
||||
model_config = SettingsConfigDict(
|
||||
env_file=".env", env_file_encoding="utf-8", env_nested_delimiter="."
|
||||
)
|
||||
|
||||
|
||||
def _load_json() -> Config | None:
|
||||
path = Path("config.json")
|
||||
if path.exists():
|
||||
with path.open() as f:
|
||||
j = json.loads(f.read())
|
||||
return Config(**j)
|
||||
|
||||
|
||||
def _load_yaml() -> Config | None:
|
||||
path = Path("config.yaml")
|
||||
if path.exists():
|
||||
with path.open() as f:
|
||||
y = yaml.load(f.read(), Loader=Loader)
|
||||
return Config(**y)
|
||||
|
||||
|
||||
def _load_env() -> Config | None:
|
||||
load_dotenv()
|
||||
data = {}
|
||||
mongo = {}
|
||||
mongo_keys = find_all(lambda x: x.upper().startswith("MONGO"), environ.keys())
|
||||
|
||||
config_keys = mongo_keys + ["TOKEN", "LOG_LEVEL", "ENVIRONMENT"]
|
||||
|
||||
for item, value in environ.items():
|
||||
if item not in config_keys:
|
||||
continue
|
||||
|
||||
if item in mongo_keys:
|
||||
key = "_".join(item.split("_")[1:]).lower()
|
||||
mongo[key] = value
|
||||
else:
|
||||
data[item.lower()] = value
|
||||
|
||||
data["mongo"] = mongo
|
||||
|
||||
return Config(**data)
|
||||
|
||||
|
||||
def load_config(method: Optional[str] = None) -> Config:
|
||||
"""
|
||||
Load the config using the specified method first
|
||||
|
||||
Args:
|
||||
method: Method to use first
|
||||
"""
|
||||
global _config
|
||||
if _config is not None:
|
||||
return _config
|
||||
|
||||
methods = {"yaml": _load_yaml, "json": _load_json, "env": _load_env}
|
||||
method_names = list(methods.keys())
|
||||
if method and method in method_names:
|
||||
method_names.remove(method)
|
||||
method_names.insert(0, method)
|
||||
|
||||
for method in method_names:
|
||||
if _config := methods[method]():
|
||||
return _config
|
||||
|
||||
raise FileNotFoundError("Missing one of: config.yaml, config.json, .env")
|
||||
def load_config() -> Config:
|
||||
"""Load the config using the specified method first"""
|
||||
return Config()
|
||||
|
|
1551
poetry.lock
generated
1551
poetry.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -17,6 +17,7 @@ pydantic = ">=2.3.0,<3"
|
|||
# rocketry = "^2.5.1"
|
||||
croniter = "^1.4.1"
|
||||
beanie = ">=1.21.0"
|
||||
pydantic-settings = "^2.2.1"
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
pytest = "^7.1"
|
||||
|
|
Loading…
Add table
Reference in a new issue