[project] name = "neuronetz-gateway" version = "0.1.0" description = "Secure multi-tenant API gateway in front of Ollama for the Neuronetz platform." readme = "README.md" license = { text = "Apache-2.0" } requires-python = ">=3.12" authors = [{ name = "Neuronetz", email = "ops@neuronetz.ai" }] dependencies = [ "fastapi>=0.115", "uvicorn[standard]>=0.30", "httpx>=0.27", "sqlalchemy[asyncio]>=2.0", "asyncpg>=0.29", "redis[hiredis]>=5.0", "structlog>=24.1", "pydantic>=2.9", "pydantic-settings>=2.4", "argon2-cffi>=23.1", "typer>=0.12", "prometheus-client>=0.20", "alembic>=1.13", ] [project.scripts] neuronetz-gateway = "neuronetz_gateway.cli.manage:app" [project.optional-dependencies] dev = [ "ruff>=0.6", "mypy>=1.11", "bandit>=1.7", "pip-audit>=2.7", "pytest>=8.3", "pytest-asyncio>=0.24", "pytest-cov>=5.0", "testcontainers>=4.8", "respx>=0.21", "locust>=2.31", ] [build-system] requires = ["hatchling"] build-backend = "hatchling.build" [tool.hatch.build.targets.wheel] packages = ["src/neuronetz_gateway"] [tool.ruff] target-version = "py312" line-length = 100 src = ["src", "tests"] [tool.ruff.lint] select = ["E", "F", "I", "B", "UP", "S", "ASYNC"] [tool.ruff.lint.per-file-ignores] # Tests may use assert, bind to all interfaces in fixtures, and use obvious # fake-token strings as inputs (S105/S106 fire on any literal that looks like # a credential — fine in test inputs). "tests/**" = ["S101", "S104", "S105", "S106"] [tool.mypy] python_version = "3.12" strict = true mypy_path = "src" plugins = ["pydantic.mypy"] namespace_packages = true explicit_package_bases = true [[tool.mypy.overrides]] # argon2 ships types but some transitive deps may not; keep strictness elsewhere. # asyncpg ships no stubs/py.typed marker; it is used in revocation.py only. module = ["testcontainers.*", "locust.*", "asyncpg", "asyncpg.*"] ignore_missing_imports = true [tool.pytest.ini_options] asyncio_mode = "auto" testpaths = ["tests"] pythonpath = ["src"] addopts = "--cov=neuronetz_gateway --cov-report=term-missing" [tool.coverage.run] source = ["src/neuronetz_gateway"] branch = true omit = [ "src/neuronetz_gateway/__main__.py", "src/neuronetz_gateway/cli/*", ] [tool.coverage.report] # Phase 1: coverage is reported but non-blocking. Later phases set fail_under. show_missing = true [tool.bandit] exclude_dirs = ["tests"]