Skip to content

Commit

Permalink
Include an option to load JSON or YAML files for env config
Browse files Browse the repository at this point in the history
  • Loading branch information
dormant-user committed Aug 10, 2024
1 parent 59a7049 commit 4b75593
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 10 deletions.
2 changes: 1 addition & 1 deletion pyninja/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ async def authenticator(token: HTTPBasicCredentials = Depends(SECURITY)) -> None
auth = token.model_dump().get("credentials", "")
if auth.startswith("\\"):
auth = bytes(auth, "utf-8").decode(encoding="unicode_escape")
if secrets.compare_digest(auth, squire.settings.apikey):
if secrets.compare_digest(auth, squire.env.apikey):
return
raise exceptions.APIResponse(
status_code=HTTPStatus.UNAUTHORIZED.real, detail=HTTPStatus.UNAUTHORIZED.phrase
Expand Down
8 changes: 3 additions & 5 deletions pyninja/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@

def start(env_file: str = None) -> None:
"""Starter function for the API, which uses uvicorn server as trigger."""
squire.settings = squire.Settings().from_env_file(
env_file=env_file
squire.env = squire.env_loader(
env_file
or os.environ.get("env_file")
or os.environ.get("ENV_FILE")
or ".env"
Expand All @@ -19,6 +19,4 @@ def start(env_file: str = None) -> None:
routes=router.routes,
title=f"Service monitor for {platform.uname().node}",
)
uvicorn.run(
host=squire.settings.monitor_host, port=squire.settings.monitor_port, app=app
)
uvicorn.run(host=squire.env.monitor_host, port=squire.env.monitor_port, app=app)
41 changes: 38 additions & 3 deletions pyninja/squire.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import json
import os
import pathlib
import socket
from typing import Optional

import yaml
from pydantic import BaseModel, PositiveInt
from pydantic_settings import BaseSettings

Expand All @@ -17,7 +21,7 @@ class ServiceStatus(BaseModel):
description: str


class Settings(BaseSettings):
class EnvConfig(BaseSettings):
"""Object to load environment variables.
>>> Settings
Expand All @@ -30,7 +34,7 @@ class Settings(BaseSettings):
apikey: str

@classmethod
def from_env_file(cls, env_file: Optional[str]) -> "Settings":
def from_env_file(cls, env_file: Optional[str]) -> "EnvConfig":
"""Create Settings instance from environment file.
Args:
Expand All @@ -48,4 +52,35 @@ class Config:
extra = "ignore"


settings = Settings
def env_loader(filename: str | os.PathLike) -> EnvConfig:
"""Loads environment variables based on filetypes.
Args:
filename: Filename from where env vars have to be loaded.
Returns:
config.EnvConfig:
Returns a reference to the ``EnvConfig`` object.
"""
env_file = pathlib.Path(filename)
if env_file.suffix.lower() == ".json":
with open(env_file) as stream:
env_data = json.load(stream)
return EnvConfig(**{k.lower(): v for k, v in env_data.items()})
elif env_file.suffix.lower() in (".yaml", ".yml"):
with open(env_file) as stream:
env_data = yaml.load(stream, yaml.FullLoader)
return EnvConfig(**{k.lower(): v for k, v in env_data.items()})
elif not env_file.suffix or env_file.suffix.lower() in (
".text",
".txt",
"",
):
return EnvConfig.from_env_file(env_file)
else:
raise ValueError(
"\n\tUnsupported format for 'env_file', can be one of (.json, .yaml, .yml, .txt, .text, or null)"
)


env = EnvConfig
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ keywords = ["service-monitor", "PyNinja"]
requires-python = ">=3.10"

[tool.setuptools]
packages = ["monitor"]
packages = ["pyninja"]

[tool.setuptools.dynamic]
version = {attr = "pyninja.version"}
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ fastapi==0.112.0
psutil==6.0.0
pydantic==2.8.2
pydantic-settings==2.4.0
PyYaml==6.0.2
uvicorn==0.30.5

0 comments on commit 4b75593

Please sign in to comment.