backend config: Add application configuration
Configuration is managed as a Pydantic model and can be loaded from a YAML document.master
parent
46bc1869af
commit
e33502eee1
|
@ -1,4 +1,5 @@
|
||||||
/.venv/
|
/.venv/
|
||||||
/dist/
|
/dist/
|
||||||
/build/
|
/build/
|
||||||
__pycache__/
|
__pycache__/
|
||||||
|
/config.yml
|
||||||
|
|
|
@ -276,6 +276,29 @@ python-versions = "*"
|
||||||
[package.extras]
|
[package.extras]
|
||||||
dev = ["build", "pytest", "pytest-timeout"]
|
dev = ["build", "pytest", "pytest-timeout"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ruamel.yaml"
|
||||||
|
version = "0.17.20"
|
||||||
|
description = "ruamel.yaml is a YAML parser/emitter that supports roundtrip preservation of comments, seq/map flow style, and map key order"
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3"
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
"ruamel.yaml.clib" = {version = ">=0.2.6", markers = "platform_python_implementation == \"CPython\" and python_version < \"3.11\""}
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
docs = ["ryd"]
|
||||||
|
jinja2 = ["ruamel.yaml.jinja2 (>=0.2)"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ruamel.yaml.clib"
|
||||||
|
version = "0.2.6"
|
||||||
|
description = "C version of reader, parser and emitter for ruamel.yaml derived from libyaml"
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sniffio"
|
name = "sniffio"
|
||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
|
@ -381,7 +404,7 @@ python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
|
||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "1.1"
|
lock-version = "1.1"
|
||||||
python-versions = "^3.8"
|
python-versions = "^3.8"
|
||||||
content-hash = "4557b3cd4cddb758cdbb713b02a2f3c6974b8d1e0077ae67c30f44d5a6a68666"
|
content-hash = "b1acad0ac357a1cf7a02aaeb3106a761b3d74fb5535f707aca1bdeae1bf4d0cf"
|
||||||
|
|
||||||
[metadata.files]
|
[metadata.files]
|
||||||
anyio = [
|
anyio = [
|
||||||
|
@ -615,6 +638,33 @@ rope = [
|
||||||
{file = "rope-0.22.0-py3-none-any.whl", hash = "sha256:2847220bf72ead09b5abe72b1edc9cacff90ab93663ece06913fc97324167870"},
|
{file = "rope-0.22.0-py3-none-any.whl", hash = "sha256:2847220bf72ead09b5abe72b1edc9cacff90ab93663ece06913fc97324167870"},
|
||||||
{file = "rope-0.22.0.tar.gz", hash = "sha256:b00fbc064a26fc62d7220578a27fd639b2fad57213663cc396c137e92d73f10f"},
|
{file = "rope-0.22.0.tar.gz", hash = "sha256:b00fbc064a26fc62d7220578a27fd639b2fad57213663cc396c137e92d73f10f"},
|
||||||
]
|
]
|
||||||
|
"ruamel.yaml" = [
|
||||||
|
{file = "ruamel.yaml-0.17.20-py3-none-any.whl", hash = "sha256:810eef9c46523a3f77479c66267a4708255ebe806a2d540078408c2227f011af"},
|
||||||
|
{file = "ruamel.yaml-0.17.20.tar.gz", hash = "sha256:4b8a33c1efb2b443a93fcaafcfa4d2e445f8e8c29c528d9f5cdafb7cc9e4004c"},
|
||||||
|
]
|
||||||
|
"ruamel.yaml.clib" = [
|
||||||
|
{file = "ruamel.yaml.clib-0.2.6-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:cfdb9389d888c5b74af297e51ce357b800dd844898af9d4a547ffc143fa56751"},
|
||||||
|
{file = "ruamel.yaml.clib-0.2.6-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:7b2927e92feb51d830f531de4ccb11b320255ee95e791022555971c466af4527"},
|
||||||
|
{file = "ruamel.yaml.clib-0.2.6-cp35-cp35m-win32.whl", hash = "sha256:ada3f400d9923a190ea8b59c8f60680c4ef8a4b0dfae134d2f2ff68429adfab5"},
|
||||||
|
{file = "ruamel.yaml.clib-0.2.6-cp35-cp35m-win_amd64.whl", hash = "sha256:de9c6b8a1ba52919ae919f3ae96abb72b994dd0350226e28f3686cb4f142165c"},
|
||||||
|
{file = "ruamel.yaml.clib-0.2.6-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d67f273097c368265a7b81e152e07fb90ed395df6e552b9fa858c6d2c9f42502"},
|
||||||
|
{file = "ruamel.yaml.clib-0.2.6-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:72a2b8b2ff0a627496aad76f37a652bcef400fd861721744201ef1b45199ab78"},
|
||||||
|
{file = "ruamel.yaml.clib-0.2.6-cp36-cp36m-win32.whl", hash = "sha256:9efef4aab5353387b07f6b22ace0867032b900d8e91674b5d8ea9150db5cae94"},
|
||||||
|
{file = "ruamel.yaml.clib-0.2.6-cp36-cp36m-win_amd64.whl", hash = "sha256:846fc8336443106fe23f9b6d6b8c14a53d38cef9a375149d61f99d78782ea468"},
|
||||||
|
{file = "ruamel.yaml.clib-0.2.6-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0847201b767447fc33b9c235780d3aa90357d20dd6108b92be544427bea197dd"},
|
||||||
|
{file = "ruamel.yaml.clib-0.2.6-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:78988ed190206672da0f5d50c61afef8f67daa718d614377dcd5e3ed85ab4a99"},
|
||||||
|
{file = "ruamel.yaml.clib-0.2.6-cp37-cp37m-win32.whl", hash = "sha256:a49e0161897901d1ac9c4a79984b8410f450565bbad64dbfcbf76152743a0cdb"},
|
||||||
|
{file = "ruamel.yaml.clib-0.2.6-cp37-cp37m-win_amd64.whl", hash = "sha256:bf75d28fa071645c529b5474a550a44686821decebdd00e21127ef1fd566eabe"},
|
||||||
|
{file = "ruamel.yaml.clib-0.2.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a32f8d81ea0c6173ab1b3da956869114cae53ba1e9f72374032e33ba3118c233"},
|
||||||
|
{file = "ruamel.yaml.clib-0.2.6-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7f7ecb53ae6848f959db6ae93bdff1740e651809780822270eab111500842a84"},
|
||||||
|
{file = "ruamel.yaml.clib-0.2.6-cp38-cp38-win32.whl", hash = "sha256:89221ec6d6026f8ae859c09b9718799fea22c0e8da8b766b0b2c9a9ba2db326b"},
|
||||||
|
{file = "ruamel.yaml.clib-0.2.6-cp38-cp38-win_amd64.whl", hash = "sha256:31ea73e564a7b5fbbe8188ab8b334393e06d997914a4e184975348f204790277"},
|
||||||
|
{file = "ruamel.yaml.clib-0.2.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:dc6a613d6c74eef5a14a214d433d06291526145431c3b964f5e16529b1842bed"},
|
||||||
|
{file = "ruamel.yaml.clib-0.2.6-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:1866cf2c284a03b9524a5cc00daca56d80057c5ce3cdc86a52020f4c720856f0"},
|
||||||
|
{file = "ruamel.yaml.clib-0.2.6-cp39-cp39-win32.whl", hash = "sha256:3fb9575a5acd13031c57a62cc7823e5d2ff8bc3835ba4d94b921b4e6ee664104"},
|
||||||
|
{file = "ruamel.yaml.clib-0.2.6-cp39-cp39-win_amd64.whl", hash = "sha256:825d5fccef6da42f3c8eccd4281af399f21c02b32d98e113dbc631ea6a6ecbc7"},
|
||||||
|
{file = "ruamel.yaml.clib-0.2.6.tar.gz", hash = "sha256:4ff604ce439abb20794f05613c374759ce10e3595d1867764dd1ae675b85acbd"},
|
||||||
|
]
|
||||||
sniffio = [
|
sniffio = [
|
||||||
{file = "sniffio-1.2.0-py3-none-any.whl", hash = "sha256:471b71698eac1c2112a40ce2752bb2f4a4814c22a54a3eed3676bc0f5ca9f663"},
|
{file = "sniffio-1.2.0-py3-none-any.whl", hash = "sha256:471b71698eac1c2112a40ce2752bb2f4a4814c22a54a3eed3676bc0f5ca9f663"},
|
||||||
{file = "sniffio-1.2.0.tar.gz", hash = "sha256:c4666eecec1d3f50960c6bdf61ab7bc350648da6c126e3cf6898d8cd4ddcd3de"},
|
{file = "sniffio-1.2.0.tar.gz", hash = "sha256:c4666eecec1d3f50960c6bdf61ab7bc350648da6c126e3cf6898d8cd4ddcd3de"},
|
||||||
|
|
|
@ -9,6 +9,7 @@ license = "MIT"
|
||||||
python = "^3.8"
|
python = "^3.8"
|
||||||
fastapi = "^0.72.0"
|
fastapi = "^0.72.0"
|
||||||
SQLAlchemy = "^1.4.31"
|
SQLAlchemy = "^1.4.31"
|
||||||
|
"ruamel.yaml" = "^0.17.20"
|
||||||
|
|
||||||
[tool.poetry.dev-dependencies]
|
[tool.poetry.dev-dependencies]
|
||||||
black = "^21.12b0"
|
black = "^21.12b0"
|
||||||
|
|
|
@ -13,10 +13,15 @@ context is available to request handlers using the
|
||||||
'''
|
'''
|
||||||
import fastapi
|
import fastapi
|
||||||
|
|
||||||
|
from ..config import Configuration
|
||||||
|
|
||||||
|
|
||||||
class Context:
|
class Context:
|
||||||
'''Application context'''
|
'''Application context'''
|
||||||
|
|
||||||
|
config: Configuration
|
||||||
|
'''Application configuration'''
|
||||||
|
|
||||||
|
|
||||||
def get_context(request: fastapi.Request) -> Context:
|
def get_context(request: fastapi.Request) -> Context:
|
||||||
'''Dependency function to access the application context'''
|
'''Dependency function to access the application context'''
|
||||||
|
|
|
@ -4,6 +4,7 @@ from typing import Awaitable, Callable
|
||||||
import fastapi
|
import fastapi
|
||||||
|
|
||||||
from .. import __version__
|
from .. import __version__
|
||||||
|
from ..config import Configuration
|
||||||
from .context import Context
|
from .context import Context
|
||||||
|
|
||||||
|
|
||||||
|
@ -18,6 +19,7 @@ app = fastapi.FastAPI(
|
||||||
|
|
||||||
# Application context
|
# Application context
|
||||||
context = Context()
|
context = Context()
|
||||||
|
context.config = Configuration()
|
||||||
|
|
||||||
|
|
||||||
@app.middleware('http')
|
@app.middleware('http')
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import IO, Optional, Union
|
||||||
|
|
||||||
|
import pydantic
|
||||||
|
from ruamel import yaml
|
||||||
|
|
||||||
|
|
||||||
|
class DatabaseConfiguration(pydantic.BaseModel):
|
||||||
|
'''Database configuration'''
|
||||||
|
|
||||||
|
url: str = 'sqlite:///lycodon.db'
|
||||||
|
'''Database connection URL'''
|
||||||
|
|
||||||
|
|
||||||
|
class Configuration(pydantic.BaseModel):
|
||||||
|
'''Application configuration'''
|
||||||
|
|
||||||
|
database: DatabaseConfiguration = DatabaseConfiguration()
|
||||||
|
'''Database configuration'''
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def load(cls, path: Optional[Union[Path, str]] = None) -> 'Configuration':
|
||||||
|
'''Load configuration from the specified file
|
||||||
|
|
||||||
|
:param path: Path to the configuration file
|
||||||
|
'''
|
||||||
|
|
||||||
|
if path is None:
|
||||||
|
path = Path(os.environ.get('LYCODON_CONFIG', 'config.yml'))
|
||||||
|
elif not isinstance(path, Path):
|
||||||
|
path = Path(path)
|
||||||
|
with path.open('r', encoding='utf-8') as f:
|
||||||
|
return cls.from_file(f)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_file(cls, f: IO[str]) -> 'Configuration':
|
||||||
|
'''Load configuration from an open file buffer
|
||||||
|
|
||||||
|
:param f: Open readable file object
|
||||||
|
'''
|
||||||
|
|
||||||
|
values = yaml.safe_load(f) or {}
|
||||||
|
return cls.parse_obj(values)
|
Loading…
Reference in New Issue