[build-system] requires = ["setuptools>=68", "wheel"] build-backend = "setuptools.build_meta" [project] name = "parcel-tracker-bot" version = "0.4.1" description = "Self-hosted parcel tracking: a Telegram bot and a web dashboard for people and small online shops" authors = [{ name = "Samuele Martinalli" }] readme = "README.md" license = { text = "MIT" } requires-python = ">=3.11" keywords = ["telegram", "bot", "parcel", "tracking", "courier", "shipment", "ecommerce", "dashboard", "self-hosted"] classifiers = [ "Development Status :: 4 - Beta", "Environment :: No Input/Output (Daemon)", "Environment :: Web Environment", "Framework :: aiohttp", "Intended Audience :: End Users/Desktop", "Intended Audience :: Other Audience", "License :: OSI Approved :: MIT License", "Natural Language :: English", "Natural Language :: Italian", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Topic :: Communications :: Chat", "Topic :: Office/Business", ] dependencies = [ "python-telegram-bot[job-queue]>=21.3,<22", "httpx>=0.27.0,<1", "aiosqlite>=0.20.0,<1", "python-dotenv>=1.0.1", "beautifulsoup4>=4.12.3", "lxml>=5.2.2", "Pillow>=10.3.0", "staticmap>=0.5.7", "tenacity>=9.0.0,<10", "structlog>=24.1", "prometheus-client>=0.20", "aiohttp>=3.14.3,<4", "jinja2>=3.1.6,<4", ] [project.optional-dependencies] dev = [ "pytest>=8.3.0", "pytest-asyncio>=0.24.0", "pytest-cov>=5.0.0", "respx>=0.21.1", "ruff>=0.7.0", "mypy>=1.13.0", "types-beautifulsoup4", "pre-commit>=4.0.0", "freezegun>=1.5", "babel>=2.16.0", ] [project.urls] Repository = "https://github.com/bernalli/parcel-tracker-bot" Issues = "https://github.com/bernalli/parcel-tracker-bot/issues" Changelog = "https://github.com/bernalli/parcel-tracker-bot/blob/main/CHANGELOG.md" Documentation = "https://github.com/bernalli/parcel-tracker-bot/tree/main/docs" Funding = "https://github.com/sponsors/bernalli" [project.scripts] parcel-tracker = "parcel_tracker.main:main" [project.entry-points."parcel_tracker.trackers"] # Built-in trackers will register themselves here. # External plugins can register via this same entry-point. [tool.setuptools.packages.find] where = ["src"] [tool.setuptools.package-data] "parcel_tracker.i18n" = ["locale/*/LC_MESSAGES/*.mo", "locale/*.pot"] "parcel_tracker.maps" = ["data/cities1000.tsv", "data/markers/*.png"] "parcel_tracker.web" = ["templates/*.html", "static/*"] [tool.ruff] line-length = 100 target-version = "py311" src = ["src", "tests"] [tool.ruff.lint] select = [ "E", "W", # pycodestyle "F", # pyflakes "I", # isort "B", # flake8-bugbear "C4", # flake8-comprehensions "UP", # pyupgrade "BLE", # flake8-blind-except (Bug #2 enforcement) "ASYNC", # flake8-async "S", # flake8-bandit "C901", # mccabe complexity "PLR0912", "PLR0915", "PLR0913", # too-many-* (function size) ] ignore = [ "E501", # line-too-long (ruff format handles) "S101", # assert (allowed in tests) ] [tool.ruff.lint.per-file-ignores] "tests/**" = ["S101", "BLE001", "S105", "S106"] "src/parcel_tracker/db/migrations.py" = ["S608"] "scripts/**" = ["S311", "S106", "S603", "S607", "C901", "PLR0912", "PLR0913", "PLR0915", "ASYNC240", "T201", "E501"] [tool.ruff.lint.mccabe] max-complexity = 10 [tool.ruff.lint.pylint] max-args = 6 max-statements = 50 [tool.ruff.format] quote-style = "double" indent-style = "space" [tool.mypy] python_version = "3.11" strict = true warn_return_any = true warn_unused_configs = true disallow_untyped_defs = true disallow_incomplete_defs = true check_untyped_defs = true no_implicit_optional = true warn_redundant_casts = true warn_unused_ignores = true files = ["src/parcel_tracker"] [[tool.mypy.overrides]] module = ["staticmap"] ignore_missing_imports = true [tool.pytest.ini_options] minversion = "8.0" addopts = [ "--strict-markers", "--strict-config", "-ra", "--cov=src/parcel_tracker", "--cov-report=term-missing", "--cov-report=xml", "--cov-fail-under=75", ] testpaths = ["tests"] asyncio_mode = "auto" markers = [ "unit: unit tests (fast, no I/O)", "integration: integration tests", "e2e: end-to-end tests (real network, opt-in)", ]