Mirror of https://github.com/roostorg/osprey
github.com/roostorg/osprey
1[build-system]
2requires = ["uv_build>=0.8.12,<0.9.0"]
3build-backend = "uv_build"
4
5[dependency-groups]
6common = [
7 "blinker==1.9.0",
8 "click==7.1.2",
9 "datadog==0.51.0",
10 "ddtrace==2.21.11",
11 "deepmerge==0.3.0",
12 "dnspython==2.0.0",
13 "erlpack",
14 "faker==4.18.0",
15 "flask==1.1.4",
16 "gevent==24.2.1",
17 "google-api-core==2.19.2",
18 "google-api-python-client==2.105.0",
19 "google-auth==2.40.3",
20 "google-auth-httplib2==0.2.0",
21 "google-cloud-appengine-logging==1.6.2",
22 "google-cloud-audit-log==0.3.2",
23 "google-cloud-bigquery==3.27.0",
24 "google-cloud-bigtable==2.10.0",
25 "google-cloud-core==2.4.3",
26 "google-cloud-kms==3.5.1",
27 "google-cloud-logging==3.4.0",
28 "google-cloud-pubsub==2.15.2",
29 "google-cloud-secret-manager==2.24.0",
30 "google-cloud-storage==2.10.0",
31 "google-resumable-media==2.7.2",
32 "googleapis-common-protos==1.70.0",
33 "graphviz==0.20",
34 "greenlet",
35 "grpc-google-iam-v1==0.14.2",
36 "grpcio==1.49.1; platform_machine == 'x86_64'",
37 "grpcio==1.53.*; platform_machine != 'x86_64'",
38 "grpcio-health-checking==1.44.0",
39 "grpcio-reflection==1.44.0",
40 "grpcio-status==1.49.1; platform_machine == 'x86_64'",
41 "grpcio-status==1.53.*; platform_machine != 'x86_64'",
42 "grpcio-tools==1.49.1; platform_machine == 'x86_64'",
43 "grpcio-tools==1.53.*; platform_machine != 'x86_64'",
44 "gunicorn",
45 "hash-ring",
46 "intervals==0.9.2",
47 "jslog4kube==1.0.6",
48 "jsonpath-rw",
49 "kafka-python==1.4.7",
50 "minio>=7.2.16",
51 "mmh3==3.0.0",
52 "msgpack==1.0.8",
53 "nostril",
54 "phone-iso3166==0.3.8",
55 "pluggy==1.5.0",
56 "protobuf==4.25.8",
57 "psycogreen==1.0.2",
58 "psycopg2-binary==2.9.10",
59 "pycryptodome==3.21.0",
60 "pydantic==1.10.19",
61 "pydruid==0.6.9",
62 "pytest==8.3.5",
63 "pytest-mock==3.14.1",
64 "python-dateutil==2.8.0",
65 "python-json-logger==0.1.10",
66 "python-levenshtein==0.12.2",
67 "pytz==2022.1",
68 "pyyaml==6.0.1",
69 "requests==2.32.4",
70 "result==0.5.0",
71 "sentry-sdk==1.5.12",
72 "simplejson==3.20.2",
73 "six==1.16.0",
74 "sqlalchemy==1.4.31",
75 "sqlalchemy-utils==0.41.1",
76 "tenacity==8.1.0",
77 "tink==1.9.0",
78 "tld==0.12.7",
79 "traitlets==5.14.3",
80 "typing-extensions==4.6.3",
81 "typing-inspect==0.9.0",
82 "unidecode==1.3.8",
83 "werkzeug==1.0.1",
84 # --- Type stubs (used by mypy, not imported directly) ---
85 "types-cachetools==6.1.0.20250717",
86 "types-click==7.1.8",
87 "types-flask==1.1.6",
88 "types-ipaddress==1.0.8",
89 "types-jinja2==2.11.9",
90 "types-markupsafe==1.1.10",
91 "types-maxminddb==1.5.0",
92 "types-protobuf==4.24.0.1",
93 "types-psycopg2>=2.9.21.20250809",
94 "types-python-dateutil==2.9.0.20250708",
95 "types-pytz==2025.2.0.20250516",
96 "types-pyyaml==6.0.12.20250516",
97 "types-requests==2.27.7",
98 "types-simplejson==3.20.0.20250326",
99 "types-six==1.17.0.20250515",
100 "types-urllib3==1.26.25.14",
101 "types-werkzeug==1.0.9",
102]
103dev = [
104 "ipdb==0.13.13",
105 "ipython==9.4.0",
106 "memray==1.17.2",
107 "mypy>=1.13.0",
108 "mypy-extensions==1.0.0",
109 "mypy-protobuf==3.6.0",
110 "pre-commit>=4.3.0",
111 "pytest-flask==1.3.0",
112 "pytest-order==1.3.0",
113 "requests-mock==1.12.1",
114 "ruff>=0.12.9",
115 "setuptools==80.9.0",
116 "sqlalchemy[mypy]>=1.4.31",
117 "sqlalchemy2-stubs==0.0.2a38",
118 "types-flask-cors>=3.0.10",
119]
120
121
122[tool.uv]
123override-dependencies = ["ddtrace>=2.17.2,<3.0.0"]
124default-groups = ["common", "dev"]
125
126[tool.uv.sources]
127erlpack = { git = "https://github.com/discord/erlpack.git", rev = "b25ebd51ae4c097bd7f756fd4e1c841b61bfe50b" }
128greenlet = { git = "https://github.com/discord/greenlet.git", rev = "a75d78f1547c74a81134644a179467525a255466" }
129gunicorn = { git = "https://github.com/discord/gunicorn.git", rev = "979efdcb918daa536d8923668241c6e6bf1edb58" }
130hash-ring = { url = "https://storage.googleapis.com/discord-devops/hash_ring-src-b4b56bc93053881b68b829ee9d1a4871b4aee592.zip" }
131jsonpath-rw = { url = "https://github.com/kennknowles/python-jsonpath-rw/archive/6f5647bb3ad2395c20f0191fef07a1df51c9fed8.tar.gz" }
132nostril = { url = "https://github.com/casics/nostril/archive/v1.2.0.tar.gz" }
133osprey_rpc = { workspace = true }
134osprey_worker = { workspace = true }
135example_plugins = { workspace = true }
136
137[tool.uv.workspace]
138members = [
139 "osprey_rpc",
140 "osprey_worker",
141 "example_plugins",
142]
143
144
145[tool.ruff]
146target-version = "py311"
147line-length = 120
148fix = true
149force-exclude = true # Needed for pre-commit to work on staged files
150extend-exclude = [
151 # Exclude protobuf generated files
152 "**/*_pb2*.py",
153 "**/*_pb2*.pyi",
154]
155
156[tool.ruff.format]
157quote-style = "single"
158indent-style = "space"
159skip-magic-trailing-comma = false
160line-ending = "auto"
161
162[tool.ruff.lint]
163select = [
164 "E", # pycodestyle errors
165 "F", # pyflakes (includes F401 unused imports)
166 "I", # isort
167 "B006", # flake8-bugbear, B006 catches mutable defaults
168]
169ignore = [
170 "E501", # Formatter already does a best effort of handling line-length, but some lines just can't be shortened anymore
171]
172
173[tool.ruff.lint.isort]
174known-first-party = ["osprey_worker", "osprey_rpc", "example_plugins"]
175
176[tool.fawltydeps]
177code = ["osprey_worker/src", "osprey_rpc/src", "example_plugins/src"]
178deps = ["pyproject.toml"]
179ignore_unused = [
180 # Type stubs: used by mypy, never imported directly
181 "types-cachetools",
182 "types-click",
183 "types-flask",
184 "types-flask-cors",
185 "types-ipaddress",
186 "types-jinja2",
187 "types-markupsafe",
188 "types-maxminddb",
189 "types-protobuf",
190 "types-psycopg2",
191 "types-python-dateutil",
192 "types-pytz",
193 "types-pyyaml",
194 "types-requests",
195 "types-simplejson",
196 "types-six",
197 "types-urllib3",
198 "types-werkzeug",
199 "sqlalchemy2-stubs",
200 # Dev CLI tools: run as commands, not imported
201 "grpcio-tools",
202 "ipdb",
203 "ipython",
204 "memray",
205 "mypy",
206 "mypy-extensions",
207 "mypy-protobuf",
208 "pre-commit",
209 "pytest-flask",
210 "pytest-order",
211 "requests-mock",
212 "ruff",
213 "setuptools",
214 # Runtime CLI: started via command line, not imported in source
215 "gunicorn",
216 # Gunicorn logger class: loaded via --logger-class flag, not imported in source
217 "jslog4kube",
218 # Optional runtime dep of sentry-sdk for FlaskIntegration
219 "blinker",
220 # gRPC server extensions: registered at startup, not imported directly
221 "grpcio-health-checking",
222 "grpcio-reflection",
223 "grpcio-status",
224 # Needs investigation: may be unused, verify before removing
225 "erlpack",
226 "google-api-python-client",
227 "google-auth-httplib2",
228 "nostril",
229]
230
231[tool.mypy]
232plugins = ["pydantic.mypy", "sqlalchemy.ext.mypy.plugin"]
233python_version = "3.11"
234namespace_packages = true
235explicit_package_bases = true
236disable_error_code = ["annotation-unchecked"]
237
238mypy_path = [
239 "osprey_rpc/src",
240 "osprey_worker/src",
241 "example_plugins/src",
242]
243
244# Strict mode includes the following flags. When these are all True, they can be replaced with strict mode.
245# Mostly disabled to match old config
246warn_unused_configs = true
247disallow_any_generics = true
248disallow_subclassing_any = true
249disallow_untyped_calls = false
250disallow_untyped_defs = false
251disallow_incomplete_defs = false
252check_untyped_defs = false
253disallow_untyped_decorators = false
254warn_redundant_casts = true
255warn_return_any = false
256no_implicit_reexport = false
257strict_equality = false
258
259# Additional checks we want to turn on eventually (disabled for now)
260disallow_any_unimported = false
261disallow_any_expr = false
262disallow_any_decorated = false
263disallow_any_explicit = false
264warn_unreachable = false
265
266exclude = [
267 "^.*/venv/.*$",
268 ".*/setup\\.py$",
269 ".*_pb2\\.py$",
270 ".*_pb2\\.pyi$",
271 ".*_pb2_grpc\\.py$",
272 ".*/tests/.*",
273 ".*/test_.*\\.py$",
274]
275
276# required until pydantic explicitly exports Extra
277[[tool.mypy.overrides]]
278module = "pydantic.main"
279implicit_reexport = true
280
281[[tool.mypy.overrides]]
282module = ["jsonpath_rw", "minio.*"]
283ignore_missing_imports = true
284
285# third party packages we don't care about
286[[tool.mypy.overrides]]
287module = [
288 "stubs.*",
289 "pigeon.*",
290 "google.*",
291 "perf_tools.*",
292 "gevent.*",
293 "grpc.*",
294 "pydruid.*",
295 "phone_iso3166.*",
296 "typing_inspect.*",
297 "tink.*",
298 "sqlalchemy_utils.*",
299 "graphviz.*",
300 "psycogreen.*",
301 "hash_ring.*",
302 "deepmerge.*",
303 "greenlet.*",
304 "Levenshtein.*",
305 "kafka.*",
306 "pythonjsonlogger.*",
307 "msgpack.*",
308 "jose.*",
309]
310ignore_errors = true
311disable_error_code = ["annotation-unchecked", "import-untyped"]
312ignore_missing_imports = true
313# At least for now, ignore tests.
314# TODO: Remove these exclusions once they're fixed
315[[tool.mypy.overrides]]
316module = "osprey.worker.*.tests.*"
317ignore_errors = true
318
319[[tool.mypy.overrides]]
320module = ["osprey.rpc.*"]
321ignore_errors = true