diff --git a/.env.local b/.env.local new file mode 100644 index 0000000..063c751 --- /dev/null +++ b/.env.local @@ -0,0 +1 @@ +IS_LOCAL=True diff --git a/README.md b/README.md index 4c76595..9bca6f0 100644 --- a/README.md +++ b/README.md @@ -127,6 +127,12 @@ uv run ruff check . --fix hodolint Dockerfile ``` +## pytest +To run the test, use the following command: +```sh +uv run pytest +``` + ## Appendix ### Install libraries @@ -144,34 +150,51 @@ uv add {libraries} ### The structure of this repository ``` . -├── .devcontainer +├── .devcontainer/ │ ├── devcontainer.json │ └── Dockerfile -├── Dockerfile -├── .github -│ ├── actions +├── .github/ +│ ├── actions/ │ │ ├── setup-git-config │ │ │ └── action.yml │ │ └── setup-python-with-uv │ │ └── action.yml -│ ├── dependabot.yml -│ └── workflows -│ ├── docker.yml -│ ├── pyright.yml -│ ├── ruff.yml -│ └── test.yml -├── .dockergitignore -├── docs/ +│ ├── workflows/ +│ │ ├── docker.yml +│ │ ├── pyright.yml +│ │ ├── ruff.yml +│ │ └── test.yml +│ └── dependabot.yml +├── .vscode +│ ├── extensions.json +│ └── settings.json +├── tests/ +│ └── tools/ +│ └── test__logger.py +├── tools/ +│ ├── config/ +│ │ ├── __init__.py +│ │ ├── fastapi.py +│ │ └── settings.py +│ ├── logger/ +│ │ ├── __init__.py +│ │ ├── color.py +│ │ ├── googlecloud.py +│ │ ├── local.py +│ │ ├── logger.py +│ │ ├── style.py +│ │ └── type.py +│ └── __init__.py +├── .dockerignore +├── .env.local ├── .gitignore -├── LICENSE ├── .pre-commit-config.yaml +├── .python-version +├── Dockerfile ├── pyproject.toml ├── pyrightconfig.json -├── .python-version +├── pytest.ini ├── README.md ├── ruff.toml -├── uv.lock -└── .vscode - ├── extensions.json - └── settings.json +└── uv.lock ``` diff --git a/docs/guides/index.md b/docs/guides/index.md index b933090..31fb660 100644 --- a/docs/guides/index.md +++ b/docs/guides/index.md @@ -8,4 +8,5 @@ How to use this repository. - [How to use pre-commit](pre-commit.md) - [How to use Test](test.md) - [How to use Tools](tools/index.md) + - [How to use config in this repository](tools/config.md) - [How to use logger in this repository](tools/logger.md) diff --git a/docs/guides/pre-commit.md b/docs/guides/pre-commit.md index bf16f74..5c548f9 100644 --- a/docs/guides/pre-commit.md +++ b/docs/guides/pre-commit.md @@ -8,3 +8,6 @@ ```sh uv run pre-commit uninstall ``` + +## pre-commit Configurations +If you want to configure the pre-commit, visit the [Configuration for pre-commit](../configurations/pre-commit.md) page. diff --git a/docs/guides/pyright.md b/docs/guides/pyright.md index 1c61bc3..964a91e 100644 --- a/docs/guides/pyright.md +++ b/docs/guides/pyright.md @@ -10,4 +10,4 @@ uv run pyright ``` ## Pyright Configurations -Please refer [here](../configurations/pyright.md). +If you want to configure the Pyright, visit the [Configuration for Pyright](../configurations/pyright.md) page. diff --git a/docs/guides/ruff.md b/docs/guides/ruff.md index c6fb189..c298024 100644 --- a/docs/guides/ruff.md +++ b/docs/guides/ruff.md @@ -13,3 +13,6 @@ uv run ruff format ```sh uv run ruff check ``` + +## Configuration for Ruff +If you want to configure the Ruff, visit the [Configuration for ruff](../configurations/ruff.md) page. diff --git a/docs/guides/test.md b/docs/guides/test.md index 24daeee..381caca 100644 --- a/docs/guides/test.md +++ b/docs/guides/test.md @@ -52,3 +52,6 @@ Test with coverage on VS Code /// caption Code coverage on editor /// + +## Configuration for Test +If you want to configure the Test hook, visit the [Configuration for Test](../configurations/test.md) page. diff --git a/docs/guides/tools/config.md b/docs/guides/tools/config.md new file mode 100644 index 0000000..b740f8f --- /dev/null +++ b/docs/guides/tools/config.md @@ -0,0 +1,30 @@ +## Environment Variables +- `.env` + - Use this file when you want to set environment variables for the project. +- `.env.local` + - Use this file when you want to set environment variables for the local environment. + +Addendum environment variables to `tools/config/settings.py`: +```{.py title="tools/config/settings.py" hl_lines="9"} +class Settings(BaseSettings): + """Environment variables settings.""" + + model_config = SettingsConfigDict( + env_file=(".env", ".env.local"), + env_file_encoding="utf-8", + ) + + DEBUG: bool = False + IS_LOCAL: bool = False +``` + +## FastAPI +```python +from fastapi import FastAPI + +from tools import Settings + + +settings = Settings() +app = FastAPI(**settings.fastapi_kwargs) +``` diff --git a/docs/guides/tools/index.md b/docs/guides/tools/index.md index 6732a7b..934f062 100644 --- a/docs/guides/tools/index.md +++ b/docs/guides/tools/index.md @@ -2,4 +2,5 @@ How to use tools in this repository. +- [How to use config](config.md) - [How to use logger](logger.md) diff --git a/docs/guides/uv.md b/docs/guides/uv.md index aee7e0a..6f2ec63 100644 --- a/docs/guides/uv.md +++ b/docs/guides/uv.md @@ -31,3 +31,6 @@ If you want to pin the Python version, run the following command: ```sh uv pin python 3.12 ``` + +## Configuration for uv +If you want to configure the uv, visit the [Configuration for uv](../configurations/uv.md) page. diff --git a/docs/index.md b/docs/index.md index 0d18f64..0db1092 100644 --- a/docs/index.md +++ b/docs/index.md @@ -12,9 +12,9 @@ This repository contains configurations to set up a Python development environme │ └── Dockerfile ├── .github/ │ ├── actions/ - │ │ ├── setup-git-config.yml + │ │ ├── setup-git-config │ │ │ └── action.yml - │ │ └── setup-python-with-uv.yml + │ │ └── setup-python-with-uv │ │ └── action.yml │ ├── workflows/ │ │ ├── docker.yml @@ -29,6 +29,10 @@ This repository contains configurations to set up a Python development environme │ └── tools/ │ └── test__logger.py ├── tools/ + │ ├── config/ + │ │ ├── __init__.py + │ │ ├── fastapi.py + │ │ └── settings.py │ ├── logger/ │ │ ├── __init__.py │ │ ├── color.py @@ -39,6 +43,7 @@ This repository contains configurations to set up a Python development environme │ │ └── type.py │ └── __init__.py ├── .dockerignore + ├── .env.local ├── .gitignore ├── .pre-commit-config.yaml ├── .python-version diff --git a/mkdocs.yml b/mkdocs.yml index d99f634..b683481 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -59,6 +59,7 @@ nav: - Test: guides/test.md - Using tools: - guides/tools/index.md + - config: guides/tools/config.md - logger: guides/tools/logger.md - Configurations: - configurations/index.md diff --git a/pyproject.toml b/pyproject.toml index 8d0c813..7ae1da7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,6 +12,7 @@ license = { file = "LICENSE" } dependencies = [ "google-cloud-logging>=3.11.3", + "pydantic-settings>=2.7.0", "pydantic>=2.10.4", ] diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000..380246f --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,9 @@ +import pytest + +from tools import Settings + + +@pytest.fixture +def settings() -> Settings: + """Fixture for settings.""" + return Settings() diff --git a/tests/tools/test__config.py b/tests/tools/test__config.py new file mode 100644 index 0000000..ae17347 --- /dev/null +++ b/tests/tools/test__config.py @@ -0,0 +1,31 @@ +import pytest + +from tools import Settings +from tools.config import FastAPIKwArgs + + +class TestSettings: + """Test class for Settings.""" + + @pytest.mark.usefixtures("settings") + def test_local(self, settings: Settings) -> None: + """Test local settings.""" + assert settings.IS_LOCAL + + @pytest.mark.usefixtures("settings") + def test_fastapi_kwargs(self, settings: Settings) -> None: + """Test fastapi_kwargs.""" + assert ( + settings.fastapi_kwargs + == FastAPIKwArgs( + debug=False, + title="FastAPI", + summary=None, + description="", + version="0.1.0", + openapi_url="/openapi.json", + docs_url="/docs", + redoc_url="/redoc", + openapi_prefix="", + ).model_dump() + ) diff --git a/tools/__init__.py b/tools/__init__.py index 8567092..34ee44c 100644 --- a/tools/__init__.py +++ b/tools/__init__.py @@ -1,8 +1,10 @@ """Tools.""" +from tools.config import Settings from tools.logger import Logger, LogType __all__ = [ "LogType", "Logger", + "Settings", ] diff --git a/tools/config/__init__.py b/tools/config/__init__.py new file mode 100644 index 0000000..31c7366 --- /dev/null +++ b/tools/config/__init__.py @@ -0,0 +1,9 @@ +"""Settings.""" + +from tools.config.fastapi import FastAPIKwArgs +from tools.config.settings import Settings + +__all__ = [ + "FastAPIKwArgs", + "Settings", +] diff --git a/tools/config/fastapi.py b/tools/config/fastapi.py new file mode 100644 index 0000000..1efb8e2 --- /dev/null +++ b/tools/config/fastapi.py @@ -0,0 +1,15 @@ +from pydantic import BaseModel + + +class FastAPIKwArgs(BaseModel): + """FastAPI kwargs.""" + + debug: bool + title: str + version: str + summary: str | None + description: str + openapi_url: str + docs_url: str + redoc_url: str + openapi_prefix: str diff --git a/tools/config/settings.py b/tools/config/settings.py new file mode 100644 index 0000000..0cdefcd --- /dev/null +++ b/tools/config/settings.py @@ -0,0 +1,43 @@ +from typing import Any + +from pydantic_settings import BaseSettings, SettingsConfigDict + +from tools.config.fastapi import FastAPIKwArgs + + +class Settings(BaseSettings): + """Environment variables settings.""" + + model_config = SettingsConfigDict( + env_file=(".env", ".env.local"), + env_file_encoding="utf-8", + ) + + IS_LOCAL: bool = False + + debug: bool = False + title: str = "FastAPI" + summary: str | None = None + description: str = "" + version: str = "0.1.0" + openapi_url: str = "/openapi.json" + docs_url: str = "/docs" + redoc_url: str = "/redoc" + openapi_prefix: str = "" + api_prefix_v1: str = "/api/v1" + allowed_hosts: list[str] = ["*"] + + @property + def fastapi_kwargs(self) -> dict[str, Any]: + """FastAPI kwargs.""" + return FastAPIKwArgs( + debug=self.debug, + title=self.title, + summary=self.summary, + description=self.description, + version=self.version, + openapi_url=self.openapi_url, + docs_url=self.docs_url, + redoc_url=self.redoc_url, + openapi_prefix=self.openapi_prefix, + ).model_dump() diff --git a/uv.lock b/uv.lock index 4d6792d..f7237c1 100644 --- a/uv.lock +++ b/uv.lock @@ -249,6 +249,7 @@ source = { virtual = "." } dependencies = [ { name = "google-cloud-logging" }, { name = "pydantic" }, + { name = "pydantic-settings" }, ] [package.dev-dependencies] @@ -265,6 +266,7 @@ dev = [ requires-dist = [ { name = "google-cloud-logging", specifier = ">=3.11.3" }, { name = "pydantic", specifier = ">=2.10.4" }, + { name = "pydantic-settings", specifier = ">=2.7.0" }, ] [package.metadata.requires-dev] @@ -977,6 +979,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a1/0c/c5c5cd3689c32ed1fe8c5d234b079c12c281c051759770c05b8bed6412b5/pydantic_core-2.27.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7d0c8399fcc1848491f00e0314bd59fb34a9c008761bcb422a057670c3f65e35", size = 2004961 }, ] +[[package]] +name = "pydantic-settings" +version = "2.7.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pydantic" }, + { name = "python-dotenv" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/86/41/19b62b99e7530cfa1d6ccd16199afd9289a12929bef1a03aa4382b22e683/pydantic_settings-2.7.0.tar.gz", hash = "sha256:ac4bfd4a36831a48dbf8b2d9325425b549a0a6f18cea118436d728eb4f1c4d66", size = 79743 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f9/00/57b4540deb5c3a39ba689bb519a4e03124b24ab8589e618be4aac2c769bd/pydantic_settings-2.7.0-py3-none-any.whl", hash = "sha256:e00c05d5fa6cbbb227c84bd7487c5c1065084119b750df7c8c1a554aed236eb5", size = 29549 }, +] + [[package]] name = "pygments" version = "2.18.0" @@ -1054,6 +1069,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892 }, ] +[[package]] +name = "python-dotenv" +version = "1.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/bc/57/e84d88dfe0aec03b7a2d4327012c1627ab5f03652216c63d49846d7a6c58/python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca", size = 39115 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6a/3e/b68c118422ec867fa7ab88444e1274aa40681c606d59ac27de5a5588f082/python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a", size = 19863 }, +] + [[package]] name = "pyyaml" version = "6.0.2"