[project] name = "template_project" requires-python = ">=3.12" description = "template project" version = "1.0.0" dependencies = [ "uuid_utils==0.11.1", "fastapi==0.119.0", "uvicorn==0.37.0", "dishka==1.7.2", "pydantic[email]>=2.12.4", "levenshtein>=0.27.3", "markupsafe", ] [dependency-groups] backend = [ "adaptix==3.0.0b11", "sqlalchemy==2.0.44", "argon2_cffi==23.1.0", "cryptography==46.0.3", "httpx==0.28.1", "psycopg[binary]>=3.2.12", "firebase-admin>=7.1.0", "aioboto3==15.5.0", "prometheus-fastapi-instrumentator>=7.1.0", "python-multipart>=0.0.20", "pgvector>=0.4.1", ] ml = [ "sentence-transformers>=5.1.2", "torch", ] types = [ "types-cachetools==6.2.0.20250827", ] migrations = [ "alembic==1.17.0", ] linters = [ "mypy==1.18.1", "ruff==0.12.11", "codespell==2.4.1", "bandit==1.8.6", { include-group = "types" }, ] tests = [ "pytest==8.4.0", "coverage==7.11.0", "pytest_asyncio==1.2.0", "dirty-equals>=0.11", ] dev = [ { include-group = "tests" }, { include-group = "linters" }, { include-group = "migrations" }, ] [project.scripts] web_api_cli = "template_project.web_api.entry_point:main" ml_api_cli = "template_project.ml.entry_point:main" [tool.pytest.ini_options] testpaths = ["tests"] asyncio_mode = "auto" filterwarnings = [ "ignore::UserWarning", 'ignore:function ham\(\) is deprecated:DeprecationWarning', ] asyncio_default_test_loop_scope = "session" asyncio_default_fixture_loop_scope = "session" [tool.uv] required-environments = [ "sys_platform == 'linux' and platform_machine == 'x86_64'" ] [[tool.uv.index]] name = "pytorch" url = "https://download.pytorch.org/whl/cpu" default = false [tool.uv.sources] torch = { index = "pytorch" } markupsafe = { git = "https://github.com/pallets/markupsafe", rev = "3.0.2" } [tool.mypy] strict = true strict_bytes = true local_partial_types = true warn_unreachable = true files = ["src/template_project", "tests"] exclude = [ "src/template_project/migrations", ] enable_error_code = [ "truthy-bool", "truthy-iterable", "redundant-expr", "unused-awaitable", "ignore-without-code", "possibly-undefined", "redundant-self", "explicit-override", "mutable-override", "unimported-reveal", "deprecated", ] [[tool.mypy.overrides]] module = ["aioboto3.*", "aiobotocore.*", "pgvector.*"] follow_untyped_imports = true [tool.ruff] fix = true preview = true target-version = "py313" line-length = 120 indent-width = 4 exclude = [ "src/template_project/migrations/**.py", ] [tool.ruff.lint] select = [ "A", # flake8-builtins "B", # flake8-bugbear "C4", # flake8-comprehensions "C90", # maccabe "COM", # flake8-commas "D", # pydocstyle "DTZ", # flake8-datetimez "E", # pycodestyle "ERA", # flake8-eradicate "EXE", # flake8-executable "F", # pyflakes "FA", # flake8-future-annotations "FBT", # flake8-boolean-trap "FLY", # pyflint "FURB", # refurb "G", # flake8-logging-format "I", # isort "ICN", # flake8-import-conventions "ISC", # flake8-implicit-str-concat "LOG", # flake8-logging "N", # pep8-naming "PERF", # perflint "PIE", # flake8-pie "PL", # pylint "PT", # flake8-pytest-style "PTH", # flake8-use-pathlib "Q", # flake8-quotes "RET", # flake8-return "RSE", # flake8-raise "RUF", # ruff "S", # flake8-bandit "SIM", # flake8-simpify "SLF", # flake8-self "SLOT", # flake8-slots "T100", # flake8-debugger "TRY", # tryceratops "UP", # pyupgrade "W", # pycodestyle "YTT", # flake8-2020 ] ignore = [ "A005", # allow to shadow stdlib and builtin module names "COM812", # trailing comma, conflicts with `ruff format` # Different doc rules that we don't really care about: "D", "ISC001", # implicit string concat conflicts with `ruff format` "ISC003", # prefer explicit string concat over implicit concat "PLR09", # we have our own complexity rules "PLR2004", # do not report magic numbers "PLR6301", # do not require classmethod / staticmethod when self not used "TRY003", # long exception messages from `tryceratops` "N813", "S106", "ERA", "RUF", "PT022", ] external = ["WPS"] [tool.ruff.lint.per-file-ignores] "tests/*.py" = [ "S101", # asserts ] [tool.ruff.lint.isort] case-sensitive = true combine-as-imports = true [tool.ruff.format] quote-style = "double" indent-style = "space" skip-magic-trailing-comma = false line-ending = "lf" # This is only required because we have invalid on-purpose code in docstrings: docstring-code-format = false [build-system] requires = ["hatchling"] build-backend = "hatchling.build" [tool.hatch.build.targets.wheel] packages = ["src/template_project"]