diff --git a/.gitignore b/.gitignore index 44bff78..5f2bf0a 100644 --- a/.gitignore +++ b/.gitignore @@ -135,6 +135,7 @@ celerybeat.pid # Environments .env +!deployment/.env .venv env/ venv/ diff --git a/deployment/.env b/deployment/.env new file mode 100644 index 0000000..9c741ea --- /dev/null +++ b/deployment/.env @@ -0,0 +1,3 @@ +DOPT_STOP_FOLDER_NAME=python +DOPT_INTERNAL_DB=data/wattana.db +DOPT_PATH_LOGGING=data/logs \ No newline at end of file diff --git a/pdm.lock b/pdm.lock index f15bd02..efcf931 100644 --- a/pdm.lock +++ b/pdm.lock @@ -5,7 +5,7 @@ groups = ["default", "dev", "lint", "nb", "tests"] strategy = ["inherit_metadata"] lock_version = "4.5.0" -content_hash = "sha256:33241b6273d0130d424b01e4bde45eba106100f2a47b12e3c053ba1ecd1557ae" +content_hash = "sha256:19e06fc0367f0208bc7ff972401f8297331c48c0a153b393b4d92e595eabc852" [[metadata.targets]] requires_python = ">=3.11" @@ -762,6 +762,20 @@ files = [ {file = "distlib-0.4.1.tar.gz", hash = "sha256:c3804d0d2d4b5fcd44036eb860cb6660485fcdf5c2aba53dc324d805837ea65b"}, ] +[[package]] +name = "dopt-basics" +version = "0.2.6" +requires_python = ">=3.11" +summary = "basic cross-project tools for Python-based d-opt projects" +groups = ["default"] +dependencies = [ + "tzdata>=2025.1", +] +files = [ + {file = "dopt_basics-0.2.6-py3-none-any.whl", hash = "sha256:f0818e2f83e91fb7d398bcabfc6c420159757d7d093b20574b88a3abc24e3eab"}, + {file = "dopt_basics-0.2.6.tar.gz", hash = "sha256:0e90d0d7a711e0dee9f898574683442644d3145ac8905d38ea23775f62aa5d2b"}, +] + [[package]] name = "execnet" version = "2.1.2" @@ -2083,7 +2097,7 @@ name = "python-dotenv" version = "1.2.2" requires_python = ">=3.10" summary = "Read key-value pairs from a .env file and set them as environment variables" -groups = ["dev"] +groups = ["default", "dev"] files = [ {file = "python_dotenv-1.2.2-py3-none-any.whl", hash = "sha256:1d8214789a24de455a8b8bd8ae6fe3c6b69a5e3d64aa8a8e5d68e694bbcb285a"}, {file = "python_dotenv-1.2.2.tar.gz", hash = "sha256:2c371a91fbd7ba082c2c1dc1f8bf89ca22564a087c2c287cd9b662adde799cf3"}, @@ -2786,8 +2800,7 @@ name = "tzdata" version = "2026.2" requires_python = ">=2" summary = "Provider of IANA time zone data" -groups = ["nb"] -marker = "python_version >= \"3.9\"" +groups = ["default", "nb"] files = [ {file = "tzdata-2026.2-py2.py3-none-any.whl", hash = "sha256:bbe9af844f658da81a5f95019480da3a89415801f6cc966806612cc7169bffe7"}, {file = "tzdata-2026.2.tar.gz", hash = "sha256:9173fde7d80d9018e02a662e168e5a2d04f87c41ea174b139fbef642eda62d10"}, diff --git a/pyproject.toml b/pyproject.toml index e9a9d6f..4927bdf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,7 @@ description = "analysis of production state messages obtained from customers" authors = [ {name = "d-opt GmbH, resp. Florian Förster", email = "f.foerster@d-opt.com"}, ] -dependencies = ["polars>=1.41.2", "sqlalchemy[asyncio]>=2.0.50"] +dependencies = ["polars>=1.41.2", "sqlalchemy[asyncio]>=2.0.50", "python-dotenv>=1.2.2", "dopt-basics>=0.2.6"] requires-python = ">=3.11" readme = "README.md" license = {text = "LicenseRef-Proprietary"} diff --git a/src/wattanalyse/README.md b/src/wattanalyse/README.md new file mode 100644 index 0000000..6b70cdb --- /dev/null +++ b/src/wattanalyse/README.md @@ -0,0 +1,6 @@ +# List of environment variables + +- DOPT_DEVELOPMENT: flag which signals that the current environment is in development mode +- DOPT_STOP_FOLDER_NAME: stop folder to find base path +- DOPT_INTERNAL_DB: path to CRM database, relative to base path +- DOPT_PATH_LOGGING: path to logging folder, relative to base path diff --git a/src/wattanalyse/constants.py b/src/wattanalyse/constants.py new file mode 100644 index 0000000..661c9a0 --- /dev/null +++ b/src/wattanalyse/constants.py @@ -0,0 +1,23 @@ +from __future__ import annotations + +import os +from pathlib import Path +from typing import Final + +from dopt_basics import io as io_ + +# PROJECT_ROOT = Path(__file__).resolve().parents[2] +LIB_PATH: Final[Path] = Path(__file__).resolve().parent + + +BASE_PATH = io_.search_folder_path( + LIB_PATH, stop_folder_name=os.getenv("DOPT_STOP_FOLDER_NAME", "python") +) +assert BASE_PATH + + +class Config: + DEVELOPMENT_STATE: bool = bool(os.getenv("DOPT_DEVELOPMENT", None)) + DB_PATH_INTERNAL: Path = BASE_PATH / os.getenv("DOPT_INTERNAL_DB", "not_existing") + PATH_LOGGING: Path = BASE_PATH / os.getenv("DOPT_PATH_LOGGING", "data/d-opt.log") + LOG_FILENAME: str = "dopt.log" diff --git a/src/wattanalyse/logging.py b/src/wattanalyse/logging.py new file mode 100644 index 0000000..befd4d5 --- /dev/null +++ b/src/wattanalyse/logging.py @@ -0,0 +1,30 @@ +import logging + +from dopt_basics.logging import BASE_LOGGER, LoggingConfig, setup_logging + +from wattanalyse.constants import Config + +enable_stderr: bool = False +enable_file: bool = True + +if Config.DEVELOPMENT_STATE: + enable_stderr = True + enable_file = False + +if not Config.PATH_LOGGING.exists(): + Config.PATH_LOGGING.mkdir() + +LOGGING_CFG: LoggingConfig = LoggingConfig( + enable_stderr=enable_stderr, + enable_file=enable_file, + logging_dir=Config.PATH_LOGGING, + log_filename=Config.LOG_FILENAME, + file_max_bytes=10_485_760, + file_backup_count=2, +) + +setup_logging(LOGGING_CFG) +logger_base = BASE_LOGGER.getChild("wattana") + +logger_database = logger_base.getChild("database") +logger_database.setLevel(logging.DEBUG)