-
Notifications
You must be signed in to change notification settings - Fork 122
Expand file tree
/
Copy pathpyproject.toml
More file actions
427 lines (409 loc) · 18.3 KB
/
pyproject.toml
File metadata and controls
427 lines (409 loc) · 18.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
[project]
name = "sie"
version = "0.0.0"
description = "Search Inference Engine - GPU inference server for search workloads"
requires-python = ">=3.12,<3.13"
dependencies = [
"sie-server",
"sie-sdk",
"sie-bench",
"sie-router",
"einops>=0.8.1",
# Using fork for filter_languages fix (filters metadata.eval_langs for retrieval tasks)
"mteb[image] @ git+https://github.com/superlinked/mteb.git@main",
"pycocotools>=2.0.11",
]
[project.optional-dependencies]
# Terminal UI for monitoring (sie-top command)
top = ["sie-admin[top]"]
# Flash Attention optimization for development (Linux only - workspace extra)
flash-attn = ["sie-server[flash-attn]"]
# GPU metrics support for server
gpu-metrics = ["sie-server[gpu-metrics]"]
# xformers for memory-efficient attention (required by Stella models)
xformers = ["sie-server[xformers]"]
[dependency-groups]
dev = [
# Testing
"pytest~=8.0",
"pytest-sugar",
"pytest-asyncio",
"pytest-cov",
"pytest-subprocess", # For testing mise task subprocess calls
# Mise task dependencies
"pydantic>=2.0", # Config validation in mise tasks
"httpx>=0.27", # HTTP client for health checks in mise tasks
# Type checking
"ty>=0.0.21",
# Linting
"ruff>=0.14,<1",
# Pre-commit
"pre-commit~=4.0",
"docker>=7.1.0",
"ipykernel>=7.1.0",
"python-hcl2>=7.3.1",
"pandas>=2.0",
"plotly>=5.0",
"statsmodels>=0.14",
"marimo>=0.20.4",
"modal>=0.73",
]
benchview = [
"datasets>=2.19,<4.0", # trust_remote_code support was removed in 4.0
"pillow>=10.0",
"pyyaml>=6.0",
"umap-learn>=0.5.5",
]
[tool.uv]
index-strategy = "unsafe-best-match"
# Use CUDA PyTorch on Linux only
# explicit = true ensures only torch/torchvision use this index, not other packages
# Using cu128 for PyTorch 2.9+ compatibility with xformers/flash-attn
[[tool.uv.index]]
name = "pytorch-cu128"
url = "https://download.pytorch.org/whl/cu128"
explicit = true
[tool.uv.sources]
torch = [
{ index = "pytorch-cu128", marker = "sys_platform == 'linux'" },
]
torchvision = [
{ index = "pytorch-cu128", marker = "sys_platform == 'linux'" },
]
sie-server = { workspace = true }
sie-sdk = { workspace = true }
sie-bench = { workspace = true }
sie-admin = { workspace = true }
sie-router = { workspace = true }
[tool.uv.workspace]
# Note: packages/sie_ts_sdk is TypeScript, not Python
# Note: integrations/sie_ts_* are TypeScript, listed explicitly to avoid matching them
members = [
"packages/sie_admin",
"packages/sie_bench",
"packages/sie_router",
"packages/sie_sdk",
"packages/sie_server",
"integrations/sie_chroma",
"integrations/sie_crewai",
"integrations/sie_dspy",
"integrations/sie_haystack",
"integrations/sie_langchain",
"integrations/sie_llamaindex",
"integrations/sie_qdrant",
"integrations/sie_weaviate",
"integrations/sie_lancedb",
]
[tool.pytest.ini_options]
# Note: integrations are NOT in testpaths because each has its own conftest.py
# which causes pytest plugin conflicts. Run with: mise run test integrations/
testpaths = ["packages/sie_server/tests", "packages/sie_sdk/tests", "packages/sie_bench/tests", "packages/sie_admin/tests", "packages/sie_router/tests", "tools/mise_tasks/tests"]
pythonpath = ["packages/sie_server/src", "packages/sie_sdk/src", "packages/sie_bench/src", "packages/sie_admin/src", "packages/sie_router/src", "tools/mise_tasks"]
addopts = "-m 'not integration and not docker and not model' --import-mode=importlib"
asyncio_mode = "auto"
markers = [
"integration: tests that require a running SIE server (deselected by default)",
"docker: tests that build/run Docker images (use -m 'integration and not docker' to skip)",
"gpu: tests that require a GPU worker pool",
"gpu_hw: tests that require real GPU hardware",
"scaling: tests for autoscaling behavior (KEDA)",
"gke: tests that require a real GKE cluster",
"eks: tests that require a real EKS cluster",
"model: Model regression tests (download real weights, slow)"
]
[tool.ruff]
line-length = 120
indent-width = 4
target-version = "py312"
exclude = [
"product/gtm/", # Website content with HTML-styled code examples
"product/research/", # Research scripts with relaxed linting
"tools/modal_sandbox.py", # modal sandbox script
]
[tool.ruff.format]
quote-style = "double"
indent-style = "space"
docstring-code-format = true
skip-magic-trailing-comma = false
[tool.ruff.lint]
select = ["ALL"]
ignore = [
"A001", # builtin-variable-shadowing (sometimes intentional)
"A002", # builtin-argument-shadowing (common in APIs)
"ANN401", # Dynamically typed expressions (typing.Any) are disallowed
"ARG001", # unused-function-argument (common in callbacks/interfaces)
"ARG004", # unused-static-method-argument (interface implementations)
"C901", # complex-structure (tracked separately, refactor later)
"B007", # Unused loop control variable (common in iteration patterns)
"B023", # function-uses-loop-variable (common pattern)
"B027", # empty-method-without-abstract-decorator (interface stubs)
"B905", # zip-without-explicit-strict (not always needed)
"COM812", # Missing trailing comma (conflicts with formatter)
"D100", # Missing docstring in public module
"D101", # Missing docstring in public class
"D102", # Missing docstring in public method
"D103", # Missing docstring in public function
"D104", # Missing docstring in public package
"D105", # undocumented-magic-method
"D107", # Missing docstring in __init__
"D205", # 1 blank line required between summary line and description
"D213", # Multi-line docstring summary should start at the second line
"D402", # signature-in-docstring (autogenerated docs)
"D417", # undocumented-param (not all params need docs)
"E402", # module-import-not-at-top-of-file (lazy imports)
"E501", # line-too-long (formatter handles this)
"EM101", # Raw string in exception (readability over DRY)
"EM102", # F-string in exception (readability over DRY)
"FBT001", # Boolean positional args - common in ML APIs
"FBT002", # Boolean default args - common in ML APIs
"FBT003", # Boolean positional value in call - common in ML APIs
"FIX002", # Line contains TODO
"N806", # non-lowercase-variable-in-function (ML conventions)
"N812", # lowercase-imported-as-non-lowercase (ML conventions)
"PERF401", # manual-list-comprehension (sometimes clearer as loop)
"PERF402", # manual-list-copy (sometimes clearer)
"PD011", # use-to-numpy (false positive for PyTorch .values on max())
"PGH003", # blanket-type-ignore (ty handles this)
"PLR0911", # too-many-return-statements (tracked separately)
"PLR0912", # too-many-branches (tracked separately)
"PLR0913", # too-many-arguments (common in ML APIs)
"PLR0915", # too-many-statements (tracked separately)
"PLW0603", # global-statement (needed for module-level singletons)
"PLW2901", # redefined-loop-name (common pattern in batch processing)
"PT012", # pytest-raises-with-multiple-statements (readability)
"PTH100", # os-path-abspath (not always cleaner with pathlib)
"PTH110", # os-path-exists (not always cleaner with pathlib)
"PTH118", # os-path-join (not always cleaner with pathlib)
"PTH120", # os-path-dirname (not always cleaner with pathlib)
"PTH123", # builtin-open (pathlib.Path.open not always clearer)
"PTH207", # glob (glob module is fine)
"RET504", # unnecessary-assign (readability before return)
"RUF002", # ambiguous-unicode-character-docstring (intentional)
"RUF003", # ambiguous-unicode-character-comment (intentional)
"S101", # Use of assert detected
"SLF001", # private-member-access (internal library access patterns)
"SIM102", # collapsible-if (sometimes clearer separated)
"SIM105", # suppressible-exception (contextlib.suppress not always clearer)
"SIM108", # if-else-block-instead-of-if-exp (ternary not always clearer)
"SIM115", # open-file-with-context-handler (not always needed)
"TC001", # typing-only-first-party-import (style preference)
"TC002", # typing-only-third-party-import (style preference)
"TC003", # typing-only-standard-library-import (style preference)
"TD002", # Missing author in TODO
"TD003", # Missing issue link for this TODO
"TRY003", # Raise vanilla args (long messages are fine)
"TRY004", # type-check-without-type-error (isinstance patterns)
"TRY300", # try-consider-else (style preference)
"TRY301", # raise-within-try (sometimes intentional)
"TRY400", # error-instead-of-exception (logging preference)
"T201", # allow print (sometimes needed)
]
[tool.ruff.lint.per-file-ignores]
"**/tests/**/*" = [
"ANN", # Type annotations (tests don't need full typing)
"ARG", # Unused function arguments (fixtures)
"B007", # Unused loop control variable (common in test loops)
"B905", # zip without strict (tests don't need strict)
"ERA001", # Expected value comments look like code
"F821", # Forward references in type hints
"INP001", # Implicit namespace package (pytest requires this)
"NPY002", # numpy legacy random (tests use rng patterns)
"PLC0415", # Import not at top-level (common in tests for isolation)
"PLR2004", # Magic value comparisons
"RET504", # Unnecessary assignment before return
"S101", # Assert statements
"SIM108", # if-else-block-instead-of-if-exp (readability in tests)
"SIM117", # Nested with statements (readability in tests)
"SLF001", # Private member access
]
# Cluster integration tests use print for progress output
"deploy/tests/**/*" = [
"ANN", # Type annotations (tests don't need full typing)
"ARG", # Unused function arguments (fixtures)
"INP001", # Implicit namespace package (pytest requires this)
"PLR2004", # Magic value comparisons
"S101", # Assert statements
"T201", # Progress output is intentional in cluster tests
]
"integrations/**/src/**/*" = [
"PLC0415", # Lazy imports for optional dependencies
"PLR0913", # Too many arguments (integration wrappers expose full SDK options)
"TC002", # Move to TYPE_CHECKING block (conflicts with lazy loading pattern)
]
# Adapters use lazy imports for optional dependencies
"**/adapters/**/*" = [
"ARG002", # Unused method arguments (adapter interface conformance)
"ARG003", # Unused classmethod arguments (factory method interface conformance)
"ERA001", # Tensor shape docs and reference implementations look like code
"F401", # Unused imports (dependency availability checks)
"PLC0415", # Lazy imports for optional dependencies (torch, flash_attn, etc.)
"PLR0913", # Adapter constructors need many parameters for flexibility
"PLR2004", # Magic numbers in adapter-specific logic
]
# Benchmark eval uses print for progress output
"**/eval/**/*" = [
"ARG002", # Unused method arguments (interface conformance)
"ERA001", # Tensor shape docs look like code
"PLR0913", # Wrappers expose full SDK options
"SLF001", # Private member access (MTEB internals)
"T201", # Progress output is intentional in benchmarking
]
# CLI commands use print and lazy imports for optional dependencies
"**/commands/**/*" = [
"T201", # CLI output is intentional
"PLC0415", # Lazy imports for optional CLI dependencies
]
# Benchmark runners print progress
"**/runners/**/*" = [
"T201", # Benchmark runners print progress
"PLC0415", # Lazy imports for optional dependencies
]
# Core server has intentional patterns
"packages/sie_server/src/sie_server/core/**/*" = [
"ARG002", # Unused method arguments (interface conformance)
"PLC0415", # Lazy imports for optional GPU features
"PLR2004", # Magic values in core logic
"SLF001", # Private member access (internal APIs)
]
# Server API uses lazy imports for optional features
"packages/sie_server/src/sie_server/api/**/*" = [
"PLC0415", # Lazy imports for optional features
]
# Server CLI uses lazy imports
"packages/sie_server/src/sie_server/cli.py" = [
"PLC0415", # Lazy imports for CLI initialization
]
# Server config uses lazy imports
"packages/sie_server/src/sie_server/config/**/*" = [
"PLC0415", # Lazy imports for optional configs
]
# Server observability uses lazy imports for optional tracing
"packages/sie_server/src/sie_server/observability/**/*" = [
"PLC0415", # Lazy imports for optional tracing/GPU libs
]
# Router package uses lazy imports
"packages/sie_router/src/sie_router/**/*" = [
"PLC0415", # Lazy imports for optional features
"PLR2004", # HTTP status codes are well-known magic numbers
"T201", # CLI output
]
# Admin package uses lazy imports for optional dependencies (GCS, curses, etc.)
"packages/sie_admin/src/sie_admin/**/*" = [
"PLC0415", # Lazy imports for optional admin dependencies
"T201", # CLI output is intentional
]
# SDK has intentional patterns
"packages/sie_sdk/src/sie_sdk/**/*" = [
"ARG002", # Unused method arguments (interface conformance)
"PLC0415", # Lazy imports for optional dependencies
"PLR2004", # HTTP status codes are well-known magic numbers
"SLF001", # Private member access (internal APIs)
]
# Bench package uses lazy imports and prints
"packages/sie_bench/src/sie_bench/**/*" = [
"ARG002", # Unused method arguments (interface conformance)
"F401", # Unused imports (dependency availability checks)
"PLC0415", # Lazy imports for optional dependencies
"PLR2004", # Magic values in benchmark configs (intentional)
"SLF001", # Private member access (benchmark internals)
"T201", # Benchmark output is intentional
]
# Admin package CLI - magic values are OK in CLI output formatting
"packages/sie_admin/src/sie_admin/commands/**/*" = [
"PLR2004", # Magic values in CLI display logic
]
# Marimo benchmark dashboard notebook
"tools/benchview.py" = [
"ANN", # Type annotations not needed in notebook cells
"B018", # Marimo uses bare expressions for cell output display
"D", # Docstrings not needed in notebook cells
"ERA001", # Marimo cell comments may look like commented-out code
"INP001", # Standalone script, not a package
"N803", # Marimo cells receive uppercase constants as arguments
"PLC0415", # Lazy imports in notebook cells
"PLR2004", # Magic values in threshold constants and display logic
"T201", # Print output is intentional in notebooks
]
# Profiling scripts use inline imports for optional GPU deps and print output
"tools/profile_sparse.py" = [
"INP001", # Standalone script, not a package
"PLC0415", # Lazy imports for optional GPU dependencies (flash_attn)
"S311", # Pseudo-random generator is fine for synthetic text generation
"SLF001", # Private member access (adapter internals for profiling)
"T201", # Script output is intentional
]
"tools/profile_colbert.py" = [
"INP001", # Standalone script, not a package
"PLC0415", # Lazy imports for optional GPU dependencies (flash_attn)
"S311", # Pseudo-random generator is fine for synthetic text generation
"SLF001", # Private member access (adapter internals for profiling)
"T201", # Script output is intentional
]
"tools/profile_dense_p50.py" = [
"INP001", # Standalone script, not a package
"PLR2004", # Magic values in threshold constants and display logic
"S311", # Pseudo-random generator is fine for synthetic text generation
"T201", # Script output is intentional
]
# Mise task scripts - CLI scripts that use print, subprocess, etc.
"tools/mise_tasks/**/*" = [
"C901", # Complexity acceptable for CLI command handlers
"INP001", # Implicit namespace package (scripts, not a package)
"N999", # Module name matrix-eval.py uses dash (mise convention)
"PLC0415", # Lazy imports for optional dependencies
"PLR1714", # Comparison style choice in CLI scripts
"PLR2004", # Magic values in CLI display logic
"SIM112", # Lowercase env vars (TF_VAR_*, usage_* are conventions)
"T201", # CLI output is intentional
]
# CLI and orchestration code - complexity acceptable for command handlers
"packages/sie_bench/src/sie_bench/cli.py" = [
"C901", # CLI commands are inherently complex (many options, validation)
]
"packages/sie_bench/src/sie_bench/matrix/executor.py" = [
"C901", # Orchestration code is inherently complex (thread management, queues)
]
[tool.ruff.lint.pydocstyle]
convention = "google"
[tool.ruff.lint.pylint]
max-args = 6
# ty (Astral type checker) configuration
# https://docs.astral.sh/ty/
[tool.ty.environment]
python-version = "3.12"
[tool.ty.src]
exclude = [
# Test files - use mocks/fixtures that don't type-check well with ty
"packages/*/tests/**",
# kubernetes is optional (only in cluster deployments)
"packages/sie_router/src/sie_router/discovery.py",
"packages/sie_router/src/sie_router/pools.py",
# xformers/flash_attn optional (requires CUDA build)
"packages/sie_server/src/sie_server/adapters/bert_flash/**",
"packages/sie_server/src/sie_server/adapters/nomic_flash/**",
"packages/sie_server/src/sie_server/adapters/bert_flash_cross_encoder/**",
"packages/sie_server/src/sie_server/adapters/qwen2_flash_cross_encoder/**",
"packages/sie_server/src/sie_server/adapters/bge_m3_flash/**",
"packages/sie_server/src/sie_server/adapters/xlm_roberta_flash/**",
"packages/sie_server/src/sie_server/adapters/colbert_rotary_flash/**",
"packages/sie_server/src/sie_server/adapters/colbert_modernbert_flash/**",
"packages/sie_server/src/sie_server/adapters/splade_flash/**",
"packages/sie_server/src/sie_server/adapters/rope_flash/**",
"packages/sie_server/src/sie_server/adapters/qwen2_flash/**",
"packages/sie_server/src/sie_server/adapters/modernbert_flash_cross_encoder/**",
# mlflow/fastembed/wandb optional
"packages/sie_bench/src/sie_bench/tracking/mlflow.py",
"packages/sie_bench/src/sie_bench/tracking/wandb.py",
"packages/sie_bench/src/sie_bench/runners/fastembed.py",
# marimo notebooks
"tools/benchview.py",
# modal sandbox script
"tools/modal_sandbox.py",
]
[tool.ty.rules]
# Pydantic limitation: ty doesn't understand Pydantic's default system.
missing-argument = "warn"
# ty is stricter than needed for possibly-missing-attribute in many cases
possibly-missing-attribute = "warn"
# Suppress warnings about unused ty: ignore comments.
unused-ignore-comment = "ignore"