From ab1e86447838a78a195a86e67c46ea6131e47e9f Mon Sep 17 00:00:00 2001 From: Sam Liu Date: Fri, 26 Apr 2024 15:18:47 +0000 Subject: [PATCH] build settings --- .env.example | 1 + Taskfile.yaml | 18 +++++++ fuware/core/__init__.py | 0 fuware/core/config.py | 40 ++++++++++++++++ fuware/core/settings/__init__.py | 1 + fuware/core/settings/db_providers.py | 28 +++++++++++ fuware/core/settings/settings.py | 71 ++++++++++++++++++++++++++++ fuware/core/settings/static.py | 22 +++++++++ poetry.lock | 36 +++++++------- pyproject.toml | 2 +- 10 files changed, 200 insertions(+), 19 deletions(-) create mode 100644 .env.example create mode 100644 Taskfile.yaml create mode 100644 fuware/core/__init__.py create mode 100644 fuware/core/config.py create mode 100644 fuware/core/settings/__init__.py create mode 100644 fuware/core/settings/db_providers.py create mode 100644 fuware/core/settings/settings.py create mode 100644 fuware/core/settings/static.py diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..bc721a1 --- /dev/null +++ b/.env.example @@ -0,0 +1 @@ +PRODUCTION=false diff --git a/Taskfile.yaml b/Taskfile.yaml new file mode 100644 index 0000000..37a952b --- /dev/null +++ b/Taskfile.yaml @@ -0,0 +1,18 @@ +version: "3" + +vars: + GREETING: Hello, World! +env: + DEFAULT_GROUP: Home + PRODUCTION: false + API_PORT: 9000 + API_DOCS: True + +dotenv: + - .env + - .dev.env +tasks: + py: + desc: runs the backend server + cmds: + - poetry run python fuware/main.py diff --git a/fuware/core/__init__.py b/fuware/core/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/fuware/core/config.py b/fuware/core/config.py new file mode 100644 index 0000000..cf6e3a7 --- /dev/null +++ b/fuware/core/config.py @@ -0,0 +1,40 @@ +import os +from functools import lru_cache +from pathlib import Path + +from dotenv import load_dotenv + + +from .settings import AppDirectories, AppSettings + +CWD = Path(__file__).parent +BASE_DIR = CWD.parent.parent +ENV = BASE_DIR.joinpath(".env") + +load_dotenv() +PRODUCTION = os.getenv("PRODUCTION", "True").lower() in ["true", "1"] +TESTING = os.getenv("TESTING", "False").lower() in ["true", "1"] +DATA_DIR = os.getenv("DATA_DIR") + +def determine_data_dir() -> Path: + global PRODUCTION, TESTING, BASE_DIR, DATA_DIR + + if TESTING: + return BASE_DIR.joinpath(DATA_DIR if DATA_DIR else "tests/.temp") + + if PRODUCTION: + return Path(DATA_DIR if DATA_DIR else "/app/data") + + return BASE_DIR.joinpath("dev", "data") + +@lru_cache +def get_app_dirs() -> AppDirectories: + return AppDirectories(determine_data_dir()) + + +@lru_cache +def get_app_settings() -> AppSettings: + return app_settings_constructor(env_file=ENV, production=PRODUCTION, data_dir=determine_data_dir()) + + +print(get_app_settings()) diff --git a/fuware/core/settings/__init__.py b/fuware/core/settings/__init__.py new file mode 100644 index 0000000..7d7765a --- /dev/null +++ b/fuware/core/settings/__init__.py @@ -0,0 +1 @@ +from .settings import * diff --git a/fuware/core/settings/db_providers.py b/fuware/core/settings/db_providers.py new file mode 100644 index 0000000..dcae60f --- /dev/null +++ b/fuware/core/settings/db_providers.py @@ -0,0 +1,28 @@ +from abc import ABC, abstractmethod +from pathlib import Path +from pydantic import BaseModel + +class AbstractDBProvider(ABC): + @property + @abstractmethod + def db_url(self) -> str: ... + + @property + @abstractmethod + def db_url_public(self) -> str: ... + +class SQLiteProvider(AbstractDBProvider, BaseModel): + data_dir: Path + prefix: str = "" + + @property + def db_path(self): + return self.data_dir / f"{self.prefix}mealie.db" + + @property + def db_url(self) -> str: + return f"sqlite:///{str(self.db_path.absolute())}" + + @property + def db_url_public(self) -> str: + return self.db_url diff --git a/fuware/core/settings/settings.py b/fuware/core/settings/settings.py new file mode 100644 index 0000000..2e4adaa --- /dev/null +++ b/fuware/core/settings/settings.py @@ -0,0 +1,71 @@ +import secrets +from pathlib import Path +from fuware.core.settings.db_providers import AbstractDBProvider, SQLiteProvider +from pydantic_settings import BaseSettings # type: ignore + + +def determine_secrets(data_dir: Path, production: bool) -> str: + if not production: + return "shh-secret-test-key" + + secrets_file = data_dir.joinpath(".secret") + if secrets_file.is_file(): + with open(secrets_file) as f: + return f.read() + else: + data_dir.mkdir(parents=True, exist_ok=True) + with open(secrets_file, "w") as f: + new_secret = secrets.token_hex(32) + f.write(new_secret) + return new_secret + +class AppSettings(BaseSettings): + PRODUCTION: bool + BASE_URL: str = "http://localhost:8080" + """trailing slashes are trimmed (ex. `http://localhost:8080/` becomes ``http://localhost:8080`)""" + + HOST_IP: str = "*" + + API_HOST: str = "0.0.0.0" + API_PORT: int = 9000 + API_DOCS: bool = True + + ALLOW_SIGNUP: bool = False + + @property + def DOCS_URL(self) -> str | None: + return "/docs" if self.API_DOCS else None + + @property + def REDOC_URL(self) -> str | None: + return "/redoc" if self.API_DOCS else None + + # =============================================== + # Database Configuration + + DB_ENGINE: str = "sqlite" # Options: 'sqlite', 'postgres' + DB_PROVIDER: AbstractDBProvider | None = None + + @property + def DB_URL(self) -> str | None: + return self.DB_PROVIDER.db_url if self.DB_PROVIDER else None + + @property + def DB_URL_PUBLIC(self) -> str | None: + return self.DB_PROVIDER.db_url_public if self.DB_PROVIDER else None + +def app_settings_constructor(data_dir: Path, production: bool, env_file: Path, env_encoding="utf-8") -> AppSettings: + """ + app_settings_constructor is a factory function that returns an AppSettings object. It is used to inject the + required dependencies into the AppSettings object and nested child objects. AppSettings should not be substantiated + directly, but rather through this factory function. + """ + app_settings = AppSettings( + _env_file=env_file, # type: ignore + _env_file_encoding=env_encoding, # type: ignore + **{"SECRET": determine_secrets(data_dir, production)}, + ) + + app_settings.DB_PROVIDER = SQLiteProvider(data_dir=data_dir) + + return app_settings diff --git a/fuware/core/settings/static.py b/fuware/core/settings/static.py new file mode 100644 index 0000000..40a3144 --- /dev/null +++ b/fuware/core/settings/static.py @@ -0,0 +1,22 @@ +import os +from dotenv import load_dotenv + +from pathlib import Path +from fuware import __version__ + +load_dotenv() + +APP_VERSION = __version__ +CWD = Path(__file__).parent +BASE_DIR = CWD.parent.parent.parent + +SERCET_KEY = b"oWNhXlfo666JlMHk6UHYxeNB6z_CA2MisDDZJe4N0yc=" +COOKIE_KEY = os.getenv('VITE_LOGIN_KEY') or '7fo24CMyIc' +# URL_DATABASE = "postgresql://{0}:{1}@{2}:{3}/{4}".format( +# os.getenv('LOL_DB_USER'), +# os.getenv('LOL_DB_PASSWORD'), +# os.getenv('LOL_DB_HOST'), +# os.getenv('LOL_DB_PORT'), +# os.getenv('LOL_DB_NAME'), +# ) +URL_DATABASE = "sqlite:///./test.db" diff --git a/poetry.lock b/poetry.lock index b81113d..003240e 100644 --- a/poetry.lock +++ b/poetry.lock @@ -564,28 +564,28 @@ files = [ [[package]] name = "ruff" -version = "0.4.1" +version = "0.4.2" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.4.1-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:2d9ef6231e3fbdc0b8c72404a1a0c46fd0dcea84efca83beb4681c318ea6a953"}, - {file = "ruff-0.4.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:9485f54a7189e6f7433e0058cf8581bee45c31a25cd69009d2a040d1bd4bfaef"}, - {file = "ruff-0.4.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d2921ac03ce1383e360e8a95442ffb0d757a6a7ddd9a5be68561a671e0e5807e"}, - {file = "ruff-0.4.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eec8d185fe193ad053eda3a6be23069e0c8ba8c5d20bc5ace6e3b9e37d246d3f"}, - {file = "ruff-0.4.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa27d9d72a94574d250f42b7640b3bd2edc4c58ac8ac2778a8c82374bb27984"}, - {file = "ruff-0.4.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:f1ee41580bff1a651339eb3337c20c12f4037f6110a36ae4a2d864c52e5ef954"}, - {file = "ruff-0.4.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0926cefb57fc5fced629603fbd1a23d458b25418681d96823992ba975f050c2b"}, - {file = "ruff-0.4.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2c6e37f2e3cd74496a74af9a4fa67b547ab3ca137688c484749189bf3a686ceb"}, - {file = "ruff-0.4.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efd703a5975ac1998c2cc5e9494e13b28f31e66c616b0a76e206de2562e0843c"}, - {file = "ruff-0.4.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:b92f03b4aa9fa23e1799b40f15f8b95cdc418782a567d6c43def65e1bbb7f1cf"}, - {file = "ruff-0.4.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:1c859f294f8633889e7d77de228b203eb0e9a03071b72b5989d89a0cf98ee262"}, - {file = "ruff-0.4.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:b34510141e393519a47f2d7b8216fec747ea1f2c81e85f076e9f2910588d4b64"}, - {file = "ruff-0.4.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:6e68d248ed688b9d69fd4d18737edcbb79c98b251bba5a2b031ce2470224bdf9"}, - {file = "ruff-0.4.1-py3-none-win32.whl", hash = "sha256:b90506f3d6d1f41f43f9b7b5ff845aeefabed6d2494307bc7b178360a8805252"}, - {file = "ruff-0.4.1-py3-none-win_amd64.whl", hash = "sha256:c7d391e5936af5c9e252743d767c564670dc3889aff460d35c518ee76e4b26d7"}, - {file = "ruff-0.4.1-py3-none-win_arm64.whl", hash = "sha256:a1eaf03d87e6a7cd5e661d36d8c6e874693cb9bc3049d110bc9a97b350680c43"}, - {file = "ruff-0.4.1.tar.gz", hash = "sha256:d592116cdbb65f8b1b7e2a2b48297eb865f6bdc20641879aa9d7b9c11d86db79"}, + {file = "ruff-0.4.2-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:8d14dc8953f8af7e003a485ef560bbefa5f8cc1ad994eebb5b12136049bbccc5"}, + {file = "ruff-0.4.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:24016ed18db3dc9786af103ff49c03bdf408ea253f3cb9e3638f39ac9cf2d483"}, + {file = "ruff-0.4.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e2e06459042ac841ed510196c350ba35a9b24a643e23db60d79b2db92af0c2b"}, + {file = "ruff-0.4.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3afabaf7ba8e9c485a14ad8f4122feff6b2b93cc53cd4dad2fd24ae35112d5c5"}, + {file = "ruff-0.4.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:799eb468ea6bc54b95527143a4ceaf970d5aa3613050c6cff54c85fda3fde480"}, + {file = "ruff-0.4.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:ec4ba9436a51527fb6931a8839af4c36a5481f8c19e8f5e42c2f7ad3a49f5069"}, + {file = "ruff-0.4.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6a2243f8f434e487c2a010c7252150b1fdf019035130f41b77626f5655c9ca22"}, + {file = "ruff-0.4.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8772130a063f3eebdf7095da00c0b9898bd1774c43b336272c3e98667d4fb8fa"}, + {file = "ruff-0.4.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ab165ef5d72392b4ebb85a8b0fbd321f69832a632e07a74794c0e598e7a8376"}, + {file = "ruff-0.4.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:1f32cadf44c2020e75e0c56c3408ed1d32c024766bd41aedef92aa3ca28eef68"}, + {file = "ruff-0.4.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:22e306bf15e09af45ca812bc42fa59b628646fa7c26072555f278994890bc7ac"}, + {file = "ruff-0.4.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:82986bb77ad83a1719c90b9528a9dd663c9206f7c0ab69282af8223566a0c34e"}, + {file = "ruff-0.4.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:652e4ba553e421a6dc2a6d4868bc3b3881311702633eb3672f9f244ded8908cd"}, + {file = "ruff-0.4.2-py3-none-win32.whl", hash = "sha256:7891ee376770ac094da3ad40c116258a381b86c7352552788377c6eb16d784fe"}, + {file = "ruff-0.4.2-py3-none-win_amd64.whl", hash = "sha256:5ec481661fb2fd88a5d6cf1f83403d388ec90f9daaa36e40e2c003de66751798"}, + {file = "ruff-0.4.2-py3-none-win_arm64.whl", hash = "sha256:cbd1e87c71bca14792948c4ccb51ee61c3296e164019d2d484f3eaa2d360dfaf"}, + {file = "ruff-0.4.2.tar.gz", hash = "sha256:33bcc160aee2520664bc0859cfeaebc84bb7323becff3f303b8f1f2d81cb4edc"}, ] [[package]] diff --git a/pyproject.toml b/pyproject.toml index f554545..239c87e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [tool.poetry] -name = "item-exp" +name = "fuware" version = "0.1.0" description = "project for manage item with exp date" authors = ["Sam Liu "]