Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
314 changes: 157 additions & 157 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,157 +1,157 @@
[project]
name = "forecastlabai"
version = "0.1.0"
description = "Portfolio-grade end-to-end retail demand forecasting system"
readme = "README.md"
requires-python = ">=3.12"
license = { text = "MIT" }
authors = [{ name = "ForecastLabAI Team" }]
dependencies = [
"fastapi>=0.115.0",
"uvicorn[standard]>=0.32.0",
"pydantic>=2.10.0",
"pydantic-settings>=2.6.0",
"sqlalchemy[asyncio]>=2.0.36",
"asyncpg>=0.30.0",
"structlog>=24.4.0",
"alembic>=1.14.0",
"python-dotenv>=1.0.1",
]
[project.optional-dependencies]
dev = [
"pytest>=8.3.0",
"pytest-asyncio>=0.24.0",
"pytest-cov>=6.0.0",
"httpx>=0.28.0",
"ruff>=0.8.0",
"mypy>=1.13.0",
"pyright>=1.1.390",
]
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[tool.hatch.build.targets.wheel]
packages = ["app"]
# =============================================================================
# Ruff Configuration (per docs/validation/ruff-standard.md)
# =============================================================================
[tool.ruff]
target-version = "py312"
line-length = 100
exclude = [
".git",
".venv",
"venv",
"__pycache__",
".mypy_cache",
".pytest_cache",
".ruff_cache",
"alembic/versions",
]
[tool.ruff.lint]
select = [
"E", # pycodestyle errors
"W", # pycodestyle warnings
"F", # pyflakes
"I", # isort (import sorting)
"B", # flake8-bugbear (catch mutable defaults, etc.)
"C4", # flake8-comprehensions
"UP", # pyupgrade (modernize syntax)
"ANN", # flake8-annotations (enforce type hints)
"S", # flake8-bandit (security)
"DTZ", # flake8-datetimez (timezone-aware datetimes)
"RUF", # Ruff-specific rules
"ARG", # flake8-unused-arguments
"PTH", # flake8-use-pathlib (prefer Path over os.path)
]
ignore = [
"S311", # Standard random is fine for non-crypto use
"E501", # Line too long (formatter handles this)
]
[tool.ruff.lint.per-file-ignores]
"tests/**/*.py" = ["S101", "ANN", "ARG001", "D", "E731"]
"test_*.py" = ["S101", "ANN", "ARG001", "D", "E731"]
"**/tests/**/*.py" = ["S101", "ANN", "ARG001", "D", "E731"]
"__init__.py" = ["F401"]
"scripts/**/*.py" = ["T201", "ANN", "S101"]
"examples/**/*.py" = ["T201", "ANN"]
"app/core/health.py" = ["B008"]
"alembic/env.py" = ["ANN"]
[tool.ruff.format]
quote-style = "double"
indent-style = "space"
line-ending = "auto"
[tool.ruff.lint.isort]
known-first-party = ["app"]
# =============================================================================
# MyPy Configuration (per docs/validation/mypy-standard.md)
# =============================================================================
[tool.mypy]
python_version = "3.12"
strict = true
show_error_codes = true
warn_unused_ignores = true
# Practical adjustments
disallow_untyped_defs = true
disallow_incomplete_defs = true
check_untyped_defs = true
disallow_untyped_decorators = false # FastAPI decorators aren't typed
[[tool.mypy.overrides]]
module = "*.tests.*"
disallow_untyped_defs = false
[[tool.mypy.overrides]]
module = "tests.*"
disallow_untyped_defs = false
[[tool.mypy.overrides]]
module = "alembic.*"
ignore_errors = true
# =============================================================================
# Pyright Configuration (per docs/validation/pyright-standard.md)
# =============================================================================
[tool.pyright]
include = ["app"]
exclude = [
"**/__pycache__",
".venv",
".mypy_cache",
".pytest_cache",
".ruff_cache",
"alembic",
"**/tests/**",
"tests",
]
pythonVersion = "3.12"
pythonPlatform = "Linux"
typeCheckingMode = "strict"
# Test files can have unused functions (fixtures, route handlers)
reportUnusedFunction = "none"
# =============================================================================
# Pytest Configuration (per docs/validation/pytest-standard.md)
# =============================================================================
[tool.pytest.ini_options]
asyncio_mode = "auto"
testpaths = ["app", "tests"]
markers = [
"integration: marks tests requiring real database (deselect with '-m \"not integration\"')",
]
filterwarnings = [
"ignore::DeprecationWarning",
]
[project]
name = "forecastlabai"
version = "0.1.0"
description = "Portfolio-grade end-to-end retail demand forecasting system"
readme = "README.md"
requires-python = ">=3.12"
license = { text = "MIT" }
authors = [{ name = "ForecastLabAI Team" }]
dependencies = [
"fastapi>=0.115.0",
"uvicorn[standard]>=0.32.0",
"pydantic>=2.10.0",
"pydantic-settings>=2.6.0",
"sqlalchemy[asyncio]>=2.0.36",
"asyncpg>=0.30.0",
"structlog>=24.4.0",
"alembic>=1.14.0",
"python-dotenv>=1.0.1",
]

[project.optional-dependencies]
dev = [
"pytest>=8.3.0",
"pytest-asyncio>=0.24.0",
"pytest-cov>=6.0.0",
"httpx>=0.28.0",
"ruff>=0.8.0",
"mypy>=1.13.0",
"pyright>=1.1.390",
]

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[tool.hatch.build.targets.wheel]
packages = ["app"]

# =============================================================================
# Ruff Configuration (per docs/validation/ruff-standard.md)
# =============================================================================
[tool.ruff]
target-version = "py312"
line-length = 100

exclude = [
".git",
".venv",
"venv",
"__pycache__",
".mypy_cache",
".pytest_cache",
".ruff_cache",
"alembic/versions",
]

[tool.ruff.lint]
select = [
"E", # pycodestyle errors
"W", # pycodestyle warnings
"F", # pyflakes
"I", # isort (import sorting)
"B", # flake8-bugbear (catch mutable defaults, etc.)
"C4", # flake8-comprehensions
"UP", # pyupgrade (modernize syntax)
"ANN", # flake8-annotations (enforce type hints)
"S", # flake8-bandit (security)
"DTZ", # flake8-datetimez (timezone-aware datetimes)
"RUF", # Ruff-specific rules
"ARG", # flake8-unused-arguments
"PTH", # flake8-use-pathlib (prefer Path over os.path)
]

ignore = [
"S311", # Standard random is fine for non-crypto use
"E501", # Line too long (formatter handles this)
]

[tool.ruff.lint.per-file-ignores]
"tests/**/*.py" = ["S101", "ANN", "ARG001", "D", "E731"]
"test_*.py" = ["S101", "ANN", "ARG001", "D", "E731"]
"**/tests/**/*.py" = ["S101", "ANN", "ARG001", "D", "E731"]
"__init__.py" = ["F401"]
"scripts/**/*.py" = ["T201", "ANN", "S101"]
"examples/**/*.py" = ["T201", "ANN"]
"app/core/health.py" = ["B008"]
"alembic/env.py" = ["ANN"]

[tool.ruff.format]
quote-style = "double"
indent-style = "space"
line-ending = "auto"

[tool.ruff.lint.isort]
known-first-party = ["app"]

# =============================================================================
# MyPy Configuration (per docs/validation/mypy-standard.md)
# =============================================================================
[tool.mypy]
python_version = "3.12"
strict = true
show_error_codes = true
warn_unused_ignores = true

# Practical adjustments
disallow_untyped_defs = true
disallow_incomplete_defs = true
check_untyped_defs = true
disallow_untyped_decorators = false # FastAPI decorators aren't typed

[[tool.mypy.overrides]]
module = "*.tests.*"
disallow_untyped_defs = false

[[tool.mypy.overrides]]
module = "tests.*"
disallow_untyped_defs = false

[[tool.mypy.overrides]]
module = "alembic.*"
ignore_errors = true

# =============================================================================
# Pyright Configuration (per docs/validation/pyright-standard.md)
# =============================================================================
[tool.pyright]
include = ["app"]
exclude = [
"**/__pycache__",
".venv",
".mypy_cache",
".pytest_cache",
".ruff_cache",
"alembic",
"**/tests/**",
"tests",
]
pythonVersion = "3.12"
pythonPlatform = "Linux"
typeCheckingMode = "strict"

# Test files can have unused functions (fixtures, route handlers)
reportUnusedFunction = "none"

# =============================================================================
# Pytest Configuration (per docs/validation/pytest-standard.md)
# =============================================================================
[tool.pytest.ini_options]
asyncio_mode = "auto"
testpaths = ["app", "tests"]
markers = [
"integration: marks tests requiring real database (deselect with '-m \"not integration\"')",
]
filterwarnings = [
"ignore::DeprecationWarning",
]