[build-system] requires = ["uv_build>=0.8.12,<0.9.0"] build-backend = "uv_build" [dependency-groups] common = [ "blinker==1.9.0", "click==7.1.2", "datadog==0.51.0", "ddtrace==2.21.11", "deepmerge==0.3.0", "dnspython==2.0.0", "erlpack", "faker==4.18.0", "flask==1.1.4", "gevent==24.2.1", "google-api-core==2.19.2", "google-api-python-client==2.105.0", "google-auth==2.40.3", "google-auth-httplib2==0.2.0", "google-cloud-appengine-logging==1.6.2", "google-cloud-audit-log==0.3.2", "google-cloud-bigquery==3.27.0", "google-cloud-bigtable==2.10.0", "google-cloud-core==2.4.3", "google-cloud-kms==3.5.1", "google-cloud-logging==3.4.0", "google-cloud-pubsub==2.15.2", "google-cloud-secret-manager==2.24.0", "google-cloud-storage==2.10.0", "google-resumable-media==2.7.2", "googleapis-common-protos==1.70.0", "graphviz==0.20", "greenlet", "grpc-google-iam-v1==0.14.2", "grpcio==1.49.1; platform_machine == 'x86_64'", "grpcio==1.53.*; platform_machine != 'x86_64'", "grpcio-health-checking==1.44.0", "grpcio-reflection==1.44.0", "grpcio-status==1.49.1; platform_machine == 'x86_64'", "grpcio-status==1.53.*; platform_machine != 'x86_64'", "grpcio-tools==1.49.1; platform_machine == 'x86_64'", "grpcio-tools==1.53.*; platform_machine != 'x86_64'", "gunicorn", "hash-ring", "intervals==0.9.2", "jslog4kube==1.0.6", "jsonpath-rw", "kafka-python==1.4.7", "minio>=7.2.16", "mmh3==3.0.0", "msgpack==1.0.8", "nostril", "phone-iso3166==0.3.8", "pluggy==1.5.0", "protobuf==4.25.8", "psycogreen==1.0.2", "psycopg2-binary==2.9.10", "pycryptodome==3.21.0", "pydantic==1.10.19", "pydruid==0.6.9", "pytest==8.3.5", "pytest-mock==3.14.1", "python-dateutil==2.8.0", "python-json-logger==0.1.10", "python-levenshtein==0.12.2", "pytz==2022.1", "pyyaml==6.0.1", "requests==2.32.4", "result==0.5.0", "sentry-sdk==1.5.12", "simplejson==3.20.2", "six==1.16.0", "sqlalchemy==1.4.31", "sqlalchemy-utils==0.41.1", "tenacity==8.1.0", "tink==1.9.0", "tld==0.12.7", "traitlets==5.14.3", "typing-extensions==4.6.3", "typing-inspect==0.9.0", "unidecode==1.3.8", "werkzeug==1.0.1", # --- Type stubs (used by mypy, not imported directly) --- "types-cachetools==6.1.0.20250717", "types-click==7.1.8", "types-flask==1.1.6", "types-ipaddress==1.0.8", "types-jinja2==2.11.9", "types-markupsafe==1.1.10", "types-maxminddb==1.5.0", "types-protobuf==4.24.0.1", "types-psycopg2>=2.9.21.20250809", "types-python-dateutil==2.9.0.20250708", "types-pytz==2025.2.0.20250516", "types-pyyaml==6.0.12.20250516", "types-requests==2.27.7", "types-simplejson==3.20.0.20250326", "types-six==1.17.0.20250515", "types-urllib3==1.26.25.14", "types-werkzeug==1.0.9", ] dev = [ "ipdb==0.13.13", "ipython==9.4.0", "memray==1.17.2", "mypy>=1.13.0", "mypy-extensions==1.0.0", "mypy-protobuf==3.6.0", "pre-commit>=4.3.0", "pytest-flask==1.3.0", "pytest-order==1.3.0", "requests-mock==1.12.1", "ruff>=0.12.9", "setuptools==80.9.0", "sqlalchemy[mypy]>=1.4.31", "sqlalchemy2-stubs==0.0.2a38", "types-flask-cors>=3.0.10", ] [tool.uv] override-dependencies = ["ddtrace>=2.17.2,<3.0.0"] default-groups = ["common", "dev"] [tool.uv.sources] erlpack = { git = "https://github.com/discord/erlpack.git", rev = "b25ebd51ae4c097bd7f756fd4e1c841b61bfe50b" } greenlet = { git = "https://github.com/discord/greenlet.git", rev = "a75d78f1547c74a81134644a179467525a255466" } gunicorn = { git = "https://github.com/discord/gunicorn.git", rev = "979efdcb918daa536d8923668241c6e6bf1edb58" } hash-ring = { url = "https://storage.googleapis.com/discord-devops/hash_ring-src-b4b56bc93053881b68b829ee9d1a4871b4aee592.zip" } jsonpath-rw = { url = "https://github.com/kennknowles/python-jsonpath-rw/archive/6f5647bb3ad2395c20f0191fef07a1df51c9fed8.tar.gz" } nostril = { url = "https://github.com/casics/nostril/archive/v1.2.0.tar.gz" } osprey_rpc = { workspace = true } osprey_worker = { workspace = true } example_plugins = { workspace = true } [tool.uv.workspace] members = [ "osprey_rpc", "osprey_worker", "example_plugins", ] [tool.ruff] target-version = "py311" line-length = 120 fix = true force-exclude = true # Needed for pre-commit to work on staged files extend-exclude = [ # Exclude protobuf generated files "**/*_pb2*.py", "**/*_pb2*.pyi", ] [tool.ruff.format] quote-style = "single" indent-style = "space" skip-magic-trailing-comma = false line-ending = "auto" [tool.ruff.lint] select = [ "E", # pycodestyle errors "F", # pyflakes (includes F401 unused imports) "I", # isort "B006", # flake8-bugbear, B006 catches mutable defaults ] ignore = [ "E501", # Formatter already does a best effort of handling line-length, but some lines just can't be shortened anymore ] [tool.ruff.lint.isort] known-first-party = ["osprey_worker", "osprey_rpc", "example_plugins"] [tool.fawltydeps] code = ["osprey_worker/src", "osprey_rpc/src", "example_plugins/src"] deps = ["pyproject.toml"] ignore_unused = [ # Type stubs: used by mypy, never imported directly "types-cachetools", "types-click", "types-flask", "types-flask-cors", "types-ipaddress", "types-jinja2", "types-markupsafe", "types-maxminddb", "types-protobuf", "types-psycopg2", "types-python-dateutil", "types-pytz", "types-pyyaml", "types-requests", "types-simplejson", "types-six", "types-urllib3", "types-werkzeug", "sqlalchemy2-stubs", # Dev CLI tools: run as commands, not imported "grpcio-tools", "ipdb", "ipython", "memray", "mypy", "mypy-extensions", "mypy-protobuf", "pre-commit", "pytest-flask", "pytest-order", "requests-mock", "ruff", "setuptools", # Runtime CLI: started via command line, not imported in source "gunicorn", # Gunicorn logger class: loaded via --logger-class flag, not imported in source "jslog4kube", # Optional runtime dep of sentry-sdk for FlaskIntegration "blinker", # gRPC server extensions: registered at startup, not imported directly "grpcio-health-checking", "grpcio-reflection", "grpcio-status", # Needs investigation: may be unused, verify before removing "erlpack", "google-api-python-client", "google-auth-httplib2", "nostril", ] [tool.mypy] plugins = ["pydantic.mypy", "sqlalchemy.ext.mypy.plugin"] python_version = "3.11" namespace_packages = true explicit_package_bases = true disable_error_code = ["annotation-unchecked"] mypy_path = [ "osprey_rpc/src", "osprey_worker/src", "example_plugins/src", ] # Strict mode includes the following flags. When these are all True, they can be replaced with strict mode. # Mostly disabled to match old config warn_unused_configs = true disallow_any_generics = true disallow_subclassing_any = true disallow_untyped_calls = false disallow_untyped_defs = false disallow_incomplete_defs = false check_untyped_defs = false disallow_untyped_decorators = false warn_redundant_casts = true warn_return_any = false no_implicit_reexport = false strict_equality = false # Additional checks we want to turn on eventually (disabled for now) disallow_any_unimported = false disallow_any_expr = false disallow_any_decorated = false disallow_any_explicit = false warn_unreachable = false exclude = [ "^.*/venv/.*$", ".*/setup\\.py$", ".*_pb2\\.py$", ".*_pb2\\.pyi$", ".*_pb2_grpc\\.py$", ".*/tests/.*", ".*/test_.*\\.py$", ] # required until pydantic explicitly exports Extra [[tool.mypy.overrides]] module = "pydantic.main" implicit_reexport = true [[tool.mypy.overrides]] module = ["jsonpath_rw", "minio.*"] ignore_missing_imports = true # third party packages we don't care about [[tool.mypy.overrides]] module = [ "stubs.*", "pigeon.*", "google.*", "perf_tools.*", "gevent.*", "grpc.*", "pydruid.*", "phone_iso3166.*", "typing_inspect.*", "tink.*", "sqlalchemy_utils.*", "graphviz.*", "psycogreen.*", "hash_ring.*", "deepmerge.*", "greenlet.*", "Levenshtein.*", "kafka.*", "pythonjsonlogger.*", "msgpack.*", "jose.*", ] ignore_errors = true disable_error_code = ["annotation-unchecked", "import-untyped"] ignore_missing_imports = true # At least for now, ignore tests. # TODO: Remove these exclusions once they're fixed [[tool.mypy.overrides]] module = "osprey.worker.*.tests.*" ignore_errors = true [[tool.mypy.overrides]] module = ["osprey.rpc.*"] ignore_errors = true