diff --git a/api/kiwi_vpn_api/config.py b/api/kiwi_vpn_api/config.py index 783a0d8..11d6136 100644 --- a/api/kiwi_vpn_api/config.py +++ b/api/kiwi_vpn_api/config.py @@ -9,7 +9,6 @@ Pydantic models might have convenience methods attached. from __future__ import annotations -import functools import json from datetime import datetime, timedelta from enum import Enum @@ -36,25 +35,14 @@ class Settings(BaseSettings): docs_url: str | None = "/docs" redoc_url: str | None = "/redoc" - @classmethod - @functools.lru_cache - def load(cls) -> Settings: - return cls() - - @classmethod - @property - def _(cls) -> Settings: - """ - Shorthand for load() - """ - - return cls.load() - @property def config_file(self) -> Path: return self.data_dir.joinpath(self.config_file_name) +SETTINGS = Settings() + + class DBType(Enum): """ Supported database types @@ -73,7 +61,7 @@ class DBConfig(BaseModel): user: str | None = None password: str | None = None host: str | None = None - database: str | None = str(Settings._.data_dir.joinpath("kiwi-vpn.db")) + database: str | Path | None = SETTINGS.data_dir.joinpath("kiwi-vpn.db") mysql_driver: str = "pymysql" mysql_args: list[str] = ["charset=utf8mb4"] @@ -253,7 +241,7 @@ class Config(BaseModel): crypto: CryptoConfig server_dn: ServerDN - __singleton: Config | None = None + __instance: Config | None = None @classmethod def load(cls) -> Config | None: @@ -261,16 +249,15 @@ class Config(BaseModel): Load configuration from config file """ - if cls.__singleton is not None: - return cls.__singleton + if cls.__instance is None: + try: + with open(SETTINGS.config_file, "r") as config_file: + cls.__instance = cls.parse_obj(json.load(config_file)) - try: - with open(Settings._.config_file, "r") as config_file: - cls.__singleton = Config.parse_obj(json.load(config_file)) - return cls.__singleton + except FileNotFoundError: + pass - except FileNotFoundError: - return None + return cls.__instance @classmethod @property @@ -280,7 +267,7 @@ class Config(BaseModel): """ if (config := cls.load()) is None: - raise FileNotFoundError(Settings._.config_file) + raise FileNotFoundError(SETTINGS.config_file) return config @@ -289,5 +276,5 @@ class Config(BaseModel): Save configuration to config file """ - with open(Settings._.config_file, "w") as config_file: + with open(SETTINGS.config_file, "w") as config_file: config_file.write(self.json(indent=2)) diff --git a/api/kiwi_vpn_api/easyrsa.py b/api/kiwi_vpn_api/easyrsa.py index bbdd86d..ab2d1f6 100644 --- a/api/kiwi_vpn_api/easyrsa.py +++ b/api/kiwi_vpn_api/easyrsa.py @@ -13,7 +13,7 @@ from cryptography import x509 from passlib import pwd from pydantic import BaseModel -from .config import Config, KeyAlgorithm, Settings +from .config import SETTINGS, Config, KeyAlgorithm from .db import Connection, Device @@ -160,7 +160,7 @@ class EasyRSA: Where certificates are stored """ - return Settings._.data_dir.joinpath("pki") + return SETTINGS.data_dir.joinpath("pki") @property def ca_password(self) -> str: diff --git a/api/kiwi_vpn_api/main.py b/api/kiwi_vpn_api/main.py index 1daaba9..c7307f1 100755 --- a/api/kiwi_vpn_api/main.py +++ b/api/kiwi_vpn_api/main.py @@ -12,12 +12,10 @@ If run directly, uses `uvicorn` to run the app. import uvicorn from fastapi import FastAPI -from .config import Config, Settings +from .config import SETTINGS, Config from .db import Connection, User from .routers import main_router -settings = Settings._ - app = FastAPI( title="kiwi-vpn API", description="This API enables the `kiwi-vpn` service.", @@ -29,9 +27,9 @@ app = FastAPI( "name": "MIT License", "url": "https://opensource.org/licenses/mit-license.php", }, - openapi_url=settings.openapi_url, - docs_url=settings.docs_url if not settings.production_mode else None, - redoc_url=settings.redoc_url if not settings.production_mode else None, + openapi_url=SETTINGS.openapi_url, + docs_url=SETTINGS.docs_url if not SETTINGS.production_mode else None, + redoc_url=SETTINGS.redoc_url if not SETTINGS.production_mode else None, ) app.include_router(main_router) diff --git a/api/kiwi_vpn_api/routers/__init__.py b/api/kiwi_vpn_api/routers/__init__.py index 25a4dbf..e73812a 100644 --- a/api/kiwi_vpn_api/routers/__init__.py +++ b/api/kiwi_vpn_api/routers/__init__.py @@ -6,10 +6,10 @@ This file: Main API router definition. from fastapi import APIRouter -from ..config import Settings +from ..config import SETTINGS from . import admin, device, service, user -main_router = APIRouter(prefix=f"/{Settings._.api_v1_prefix}") +main_router = APIRouter(prefix=f"/{SETTINGS.api_v1_prefix}") main_router.include_router(admin.router) main_router.include_router(service.router) diff --git a/api/kiwi_vpn_api/routers/_common.py b/api/kiwi_vpn_api/routers/_common.py index 1869d2e..45a7bfd 100644 --- a/api/kiwi_vpn_api/routers/_common.py +++ b/api/kiwi_vpn_api/routers/_common.py @@ -5,11 +5,11 @@ Common dependencies for routers. from fastapi import Depends, HTTPException, status from fastapi.security import OAuth2PasswordBearer -from ..config import Config, Settings +from ..config import SETTINGS, Config from ..db import Device, User oauth2_scheme = OAuth2PasswordBearer( - tokenUrl=f"{Settings._.api_v1_prefix}/user/authenticate" + tokenUrl=f"{SETTINGS.api_v1_prefix}/user/authenticate" )