queryargus 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. queryargus-0.1.0/LICENSE +21 -0
  2. queryargus-0.1.0/PKG-INFO +368 -0
  3. queryargus-0.1.0/README.md +304 -0
  4. queryargus-0.1.0/pyproject.toml +95 -0
  5. queryargus-0.1.0/src/queryargus/__init__.py +36 -0
  6. queryargus-0.1.0/src/queryargus/_internal/__init__.py +1 -0
  7. queryargus-0.1.0/src/queryargus/_internal/clock.py +18 -0
  8. queryargus-0.1.0/src/queryargus/_internal/collector.py +40 -0
  9. queryargus-0.1.0/src/queryargus/_internal/context.py +43 -0
  10. queryargus-0.1.0/src/queryargus/_internal/detection.py +100 -0
  11. queryargus-0.1.0/src/queryargus/_internal/events.py +53 -0
  12. queryargus-0.1.0/src/queryargus/_internal/fingerprint.py +20 -0
  13. queryargus-0.1.0/src/queryargus/_internal/ids.py +11 -0
  14. queryargus-0.1.0/src/queryargus/_internal/inference.py +132 -0
  15. queryargus-0.1.0/src/queryargus/_internal/registry.py +45 -0
  16. queryargus-0.1.0/src/queryargus/_internal/serialization.py +86 -0
  17. queryargus-0.1.0/src/queryargus/adapters/__init__.py +13 -0
  18. queryargus-0.1.0/src/queryargus/adapters/asyncpg.py +74 -0
  19. queryargus-0.1.0/src/queryargus/adapters/base.py +16 -0
  20. queryargus-0.1.0/src/queryargus/adapters/psycopg.py +97 -0
  21. queryargus-0.1.0/src/queryargus/adapters/sqlalchemy.py +78 -0
  22. queryargus-0.1.0/src/queryargus/analysis/__init__.py +16 -0
  23. queryargus-0.1.0/src/queryargus/analysis/coverage.py +30 -0
  24. queryargus-0.1.0/src/queryargus/analysis/heuristics.py +329 -0
  25. queryargus-0.1.0/src/queryargus/analysis/metrics.py +17 -0
  26. queryargus-0.1.0/src/queryargus/analysis/report.py +27 -0
  27. queryargus-0.1.0/src/queryargus/cli/__init__.py +1 -0
  28. queryargus-0.1.0/src/queryargus/cli/_charts.py +233 -0
  29. queryargus-0.1.0/src/queryargus/cli/_styles.py +200 -0
  30. queryargus-0.1.0/src/queryargus/cli/badge.py +86 -0
  31. queryargus-0.1.0/src/queryargus/cli/report.py +834 -0
  32. queryargus-0.1.0/src/queryargus/cli/summary.py +73 -0
  33. queryargus-0.1.0/src/queryargus/config.py +16 -0
  34. queryargus-0.1.0/src/queryargus/decorators.py +98 -0
  35. queryargus-0.1.0/src/queryargus/exceptions.py +9 -0
  36. queryargus-0.1.0/src/queryargus/instrumentation.py +90 -0
  37. queryargus-0.1.0/src/queryargus/integrations/__init__.py +6 -0
  38. queryargus-0.1.0/src/queryargus/integrations/fastapi.py +52 -0
  39. queryargus-0.1.0/src/queryargus/integrations/starlette.py +52 -0
  40. queryargus-0.1.0/src/queryargus/models.py +123 -0
  41. queryargus-0.1.0/src/queryargus/py.typed +1 -0
  42. queryargus-0.1.0/src/queryargus/scope.py +49 -0
  43. queryargus-0.1.0/src/queryargus/setup.py +156 -0
  44. queryargus-0.1.0/src/queryargus/sinks/__init__.py +7 -0
  45. queryargus-0.1.0/src/queryargus/sinks/base.py +15 -0
  46. queryargus-0.1.0/src/queryargus/sinks/jsonl.py +24 -0
  47. queryargus-0.1.0/src/queryargus/sinks/memory.py +16 -0
  48. queryargus-0.1.0/src/queryargus/testing/__init__.py +20 -0
  49. queryargus-0.1.0/src/queryargus/testing/assertions.py +73 -0
  50. queryargus-0.1.0/src/queryargus/testing/capture.py +66 -0
  51. queryargus-0.1.0/src/queryargus/testing/plugin.py +33 -0
  52. queryargus-0.1.0/src/queryargus/trace.py +108 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 matheuss0xf
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,368 @@
1
+ Metadata-Version: 2.3
2
+ Name: queryargus
3
+ Version: 0.1.0
4
+ Summary: Scope-aware SQL query tracing for Python applications, tests, and offline reports.
5
+ Keywords: sql,query tracing,observability,performance,fastapi,sqlalchemy,pytest,n+1
6
+ Author: matheuss0xf
7
+ License: MIT License
8
+
9
+ Copyright (c) 2026 matheuss0xf
10
+
11
+ Permission is hereby granted, free of charge, to any person obtaining a copy
12
+ of this software and associated documentation files (the "Software"), to deal
13
+ in the Software without restriction, including without limitation the rights
14
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15
+ copies of the Software, and to permit persons to whom the Software is
16
+ furnished to do so, subject to the following conditions:
17
+
18
+ The above copyright notice and this permission notice shall be included in all
19
+ copies or substantial portions of the Software.
20
+
21
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27
+ SOFTWARE.
28
+ Classifier: Development Status :: 3 - Alpha
29
+ Classifier: Intended Audience :: Developers
30
+ Classifier: License :: OSI Approved :: MIT License
31
+ Classifier: Operating System :: OS Independent
32
+ Classifier: Programming Language :: Python
33
+ Classifier: Programming Language :: Python :: 3
34
+ Classifier: Programming Language :: Python :: 3.10
35
+ Classifier: Programming Language :: Python :: 3.11
36
+ Classifier: Programming Language :: Python :: 3.12
37
+ Classifier: Programming Language :: Python :: 3.13
38
+ Classifier: Programming Language :: Python :: 3.14
39
+ Classifier: Programming Language :: Python :: Implementation :: CPython
40
+ Classifier: Framework :: AsyncIO
41
+ Classifier: Framework :: Pytest
42
+ Classifier: Topic :: Database
43
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
44
+ Classifier: Topic :: Software Development :: Testing
45
+ Classifier: Typing :: Typed
46
+ Requires-Dist: asyncpg>=0.29,<1 ; extra == 'asyncpg'
47
+ Requires-Dist: fastapi>=0.115,<1 ; extra == 'fastapi'
48
+ Requires-Dist: starlette>=0.37,<1 ; extra == 'fastapi'
49
+ Requires-Dist: psycopg>=3,<4 ; extra == 'psycopg'
50
+ Requires-Dist: sqlalchemy>=2,<3 ; extra == 'sqlalchemy'
51
+ Requires-Dist: pytest>=8,<9 ; extra == 'testing'
52
+ Requires-Python: >=3.10, <3.15
53
+ Project-URL: Homepage, https://github.com/matheuss0xf/queryargus
54
+ Project-URL: Repository, https://github.com/matheuss0xf/queryargus
55
+ Project-URL: Documentation, https://github.com/matheuss0xf/queryargus/tree/main/docs
56
+ Project-URL: Changelog, https://github.com/matheuss0xf/queryargus/blob/main/CHANGELOG.md
57
+ Project-URL: Issues, https://github.com/matheuss0xf/queryargus/issues
58
+ Provides-Extra: asyncpg
59
+ Provides-Extra: fastapi
60
+ Provides-Extra: psycopg
61
+ Provides-Extra: sqlalchemy
62
+ Provides-Extra: testing
63
+ Description-Content-Type: text/markdown
64
+
65
+ # QueryArgus
66
+
67
+ See every query. Miss nothing.
68
+
69
+ QueryArgus is a Python library for tracing SQL queries across requests, jobs, tests, CLI commands, and regular functions. It captures query execution with business context, stores finished traces in simple offline-friendly formats, and helps you understand repeated queries, hotspots, and possible N+1 sequences without forcing an APM-shaped workflow on your application.
70
+
71
+ [Portuguese (Brazil) documentation](https://github.com/matheuss0xf/queryargus/blob/main/README.pt-BR.md)
72
+
73
+ ## Why QueryArgus
74
+
75
+ Database behavior often becomes opaque as an application grows:
76
+
77
+ - N+1 issues slip into production unnoticed.
78
+ - Performance regressions show up late.
79
+ - Generic APMs reveal symptoms, but not the actual query flow inside the unit of work you care about.
80
+ - Plain logs rarely connect a query to the request, job, or repository method that caused it.
81
+
82
+ QueryArgus exists to make query behavior visible, understandable, and actionable.
83
+
84
+ ## What it does
85
+
86
+ - Captures SQL queries through pluggable adapters.
87
+ - Associates queries with a root trace and nested business scopes.
88
+ - Infers a useful scope from caller code when you do not set one explicitly.
89
+ - Works in HTTP apps, background jobs, worker handlers, tests, and CLI code.
90
+ - Persists finished traces to JSONL or memory sinks.
91
+ - Generates offline reports in text, JSON, HTML, SVG badge, and Markdown summary formats.
92
+ - Provides pytest fixtures and assertions for query-aware tests.
93
+
94
+ ## Installation
95
+
96
+ Install the core package:
97
+
98
+ ```bash
99
+ pip install queryargus
100
+ ```
101
+
102
+ Install common integrations:
103
+
104
+ ```bash
105
+ pip install "queryargus[sqlalchemy,fastapi,testing]"
106
+ ```
107
+
108
+ Available extras:
109
+
110
+ - `sqlalchemy`: SQLAlchemy `Engine` and `AsyncEngine` instrumentation.
111
+ - `psycopg`: psycopg 3 sync and async connection instrumentation.
112
+ - `asyncpg`: asyncpg connection instrumentation.
113
+ - `fastapi`: FastAPI and Starlette middleware integration.
114
+ - `testing`: pytest plugin and testing helpers.
115
+
116
+ ## Quick start
117
+
118
+ `setup()` is the recommended entrypoint when you want one line to configure sinks, database instrumentation, and framework integration:
119
+
120
+ ```python
121
+ from fastapi import FastAPI
122
+ from sqlalchemy import create_engine
123
+ import queryargus
124
+
125
+ app = FastAPI()
126
+ engine = create_engine("sqlite:///app.db")
127
+
128
+ queryargus.setup(
129
+ adapter=engine,
130
+ framework=app,
131
+ sink="jsonl",
132
+ )
133
+ ```
134
+
135
+ With that in place:
136
+
137
+ - the SQLAlchemy adapter captures queries automatically
138
+ - the FastAPI middleware opens one trace per request
139
+ - traces are appended to `traces/queryargus.jsonl`
140
+
141
+ ## Core usage patterns
142
+
143
+ ### FastAPI or Starlette request tracing
144
+
145
+ ```python
146
+ from fastapi import FastAPI
147
+ from sqlalchemy import create_engine
148
+ import queryargus
149
+
150
+ app = FastAPI()
151
+ engine = create_engine("sqlite:///inventory.db")
152
+
153
+ queryargus.setup(adapter=engine, framework=app, sink="jsonl")
154
+ ```
155
+
156
+ Each HTTP request becomes a root trace named like `GET /products`.
157
+
158
+ ### Jobs, workers, and CLI functions
159
+
160
+ Use `@traced` when the function itself is the unit of work:
161
+
162
+ ```python
163
+ import queryargus
164
+
165
+ queryargus.setup(adapter=engine, sink="jsonl")
166
+
167
+ @queryargus.traced("billing.process_invoice")
168
+ def process_invoice(invoice_id: str) -> None:
169
+ repository.load_invoice(invoice_id)
170
+ service.apply_rules(invoice_id)
171
+ repository.mark_processed(invoice_id)
172
+ ```
173
+
174
+ If a trace is already active, `@traced` does not open a nested root trace.
175
+
176
+ ### Manual tracing
177
+
178
+ Use `start_trace()` when a context manager fits better than a decorator:
179
+
180
+ ```python
181
+ from queryargus import start_trace, trace_scope
182
+
183
+ with start_trace("inventory.rebuild_projection"):
184
+ with trace_scope("inventory_repository.load_snapshot"):
185
+ repository.load_snapshot()
186
+ ```
187
+
188
+ Important behavior:
189
+
190
+ - `start_trace()` raises `NestedTraceError` if a root trace is already active.
191
+ - `trace_scope()` is a no-op when there is no active trace.
192
+
193
+ ### Automatic business scopes on repositories and services
194
+
195
+ Instrument a class:
196
+
197
+ ```python
198
+ from queryargus import trace_methods
199
+
200
+ @trace_methods()
201
+ class StockRepository:
202
+ def get_by_id(self, stock_id: str):
203
+ ...
204
+
205
+ def list_all(self):
206
+ ...
207
+ ```
208
+
209
+ Instrument an existing instance:
210
+
211
+ ```python
212
+ from queryargus import instrument_object_methods
213
+
214
+ repository = instrument_object_methods(repository, namespace="products")
215
+ ```
216
+
217
+ That gives you scope labels such as `StockRepository.get_by_id` or `products.list_all` in reports.
218
+
219
+ ## Supported adapters and integrations
220
+
221
+ ### SQLAlchemy
222
+
223
+ Auto-detected by `setup(adapter=engine)` or explicitly installed:
224
+
225
+ ```python
226
+ from queryargus.adapters import instrument_sqlalchemy
227
+
228
+ instrument_sqlalchemy(engine)
229
+ ```
230
+
231
+ ### psycopg 3
232
+
233
+ ```python
234
+ from queryargus.adapters import instrument_psycopg
235
+
236
+ conn = instrument_psycopg(conn)
237
+ ```
238
+
239
+ ### asyncpg
240
+
241
+ ```python
242
+ from queryargus.adapters import instrument_asyncpg
243
+
244
+ conn = instrument_asyncpg(conn)
245
+ ```
246
+
247
+ ### FastAPI and Starlette
248
+
249
+ Auto-detected by `setup(framework=app)` or explicitly installed:
250
+
251
+ ```python
252
+ from queryargus.integrations.fastapi import instrument_fastapi
253
+ from queryargus.integrations.starlette import instrument_starlette
254
+
255
+ instrument_fastapi(app)
256
+ instrument_starlette(app)
257
+ ```
258
+
259
+ ## Sinks
260
+
261
+ QueryArgus ships with two built-in sinks:
262
+
263
+ - `JsonlSink`: appends one serialized trace per line to a JSONL file
264
+ - `MemorySink`: keeps traces in memory for tests and local experiments
265
+
266
+ Examples:
267
+
268
+ ```python
269
+ import queryargus
270
+
271
+ queryargus.setup(sink="jsonl")
272
+ queryargus.setup(sink="memory")
273
+ queryargus.setup(sink=[queryargus.MemorySink(), queryargus.JsonlSink("var/traces.jsonl")])
274
+ ```
275
+
276
+ When you omit `sink`, QueryArgus defaults to `JsonlSink("traces/queryargus.jsonl")`.
277
+
278
+ ## Testing support
279
+
280
+ Install the testing extra:
281
+
282
+ ```bash
283
+ pip install "queryargus[testing]"
284
+ ```
285
+
286
+ Pytest fixtures exposed through the `pytest11` entry point:
287
+
288
+ - `queryargus_memory_sink`
289
+ - `queryargus_trace`
290
+ - `queryargus_captured`
291
+
292
+ Useful helpers:
293
+
294
+ ```python
295
+ from queryargus.testing import (
296
+ assert_all_queries_scoped,
297
+ assert_max_duration_ms,
298
+ assert_no_n_plus_one,
299
+ assert_no_repeated_queries,
300
+ assert_query_count_at_most,
301
+ capture_queries,
302
+ )
303
+ ```
304
+
305
+ Example:
306
+
307
+ ```python
308
+ def test_repository_is_efficient(queryargus_trace):
309
+ repository.list_products()
310
+
311
+ assert_query_count_at_most(queryargus_trace, 3)
312
+ assert_no_n_plus_one(queryargus_trace)
313
+ ```
314
+
315
+ ## Offline reports
316
+
317
+ Generate a report from a JSONL trace file:
318
+
319
+ ```bash
320
+ queryargus-report traces/queryargus.jsonl
321
+ ```
322
+
323
+ Supported formats:
324
+
325
+ - `text`
326
+ - `json`
327
+ - `html`
328
+ - `badge`
329
+ - `summary`
330
+
331
+ Examples:
332
+
333
+ ```bash
334
+ queryargus-report traces/queryargus.jsonl --format html --output artifacts/queryargus-report
335
+ queryargus-report traces/queryargus.jsonl --format badge --output artifacts/queryargus-coverage.svg
336
+ queryargus-report traces/queryargus.jsonl --format summary --output artifacts/queryargus-summary.md
337
+ ```
338
+
339
+ The HTML report includes coverage summaries, entrypoint breakdowns, hotspot analysis, and N+1 detection.
340
+
341
+ ## Documentation
342
+
343
+ Detailed English documentation:
344
+
345
+ - [Documentation index](https://github.com/matheuss0xf/queryargus/blob/main/docs/en/index.md)
346
+ - [User guide](https://github.com/matheuss0xf/queryargus/blob/main/docs/en/user-guide.md)
347
+ - [API reference](https://github.com/matheuss0xf/queryargus/blob/main/docs/en/api-reference.md)
348
+ - [Publishing guide](https://github.com/matheuss0xf/queryargus/blob/main/docs/en/publishing.md)
349
+ - [Troubleshooting](https://github.com/matheuss0xf/queryargus/blob/main/docs/en/troubleshooting.md)
350
+
351
+ Detailed Brazilian Portuguese documentation:
352
+
353
+ - [Índice da documentação](https://github.com/matheuss0xf/queryargus/blob/main/docs/pt-BR/index.md)
354
+ - [Guia de uso](https://github.com/matheuss0xf/queryargus/blob/main/docs/pt-BR/guia-de-uso.md)
355
+ - [Referência da API](https://github.com/matheuss0xf/queryargus/blob/main/docs/pt-BR/referencia-da-api.md)
356
+ - [Guia de publicação](https://github.com/matheuss0xf/queryargus/blob/main/docs/pt-BR/publicacao.md)
357
+ - [Solução de problemas](https://github.com/matheuss0xf/queryargus/blob/main/docs/pt-BR/solucao-de-problemas.md)
358
+
359
+ ## Compatibility
360
+
361
+ - Python `>=3.10,<3.15`
362
+ - Typed package (`py.typed` included)
363
+ - Offline-first JSONL workflow by default
364
+ - Designed for application code, tests, and CI pipelines
365
+
366
+ ## Development status
367
+
368
+ The package is ready for early professional usage and packaging, with a deliberately small public API. The current release focuses on reliable trace capture, scope-aware analysis, and offline reporting.
@@ -0,0 +1,304 @@
1
+ # QueryArgus
2
+
3
+ See every query. Miss nothing.
4
+
5
+ QueryArgus is a Python library for tracing SQL queries across requests, jobs, tests, CLI commands, and regular functions. It captures query execution with business context, stores finished traces in simple offline-friendly formats, and helps you understand repeated queries, hotspots, and possible N+1 sequences without forcing an APM-shaped workflow on your application.
6
+
7
+ [Portuguese (Brazil) documentation](https://github.com/matheuss0xf/queryargus/blob/main/README.pt-BR.md)
8
+
9
+ ## Why QueryArgus
10
+
11
+ Database behavior often becomes opaque as an application grows:
12
+
13
+ - N+1 issues slip into production unnoticed.
14
+ - Performance regressions show up late.
15
+ - Generic APMs reveal symptoms, but not the actual query flow inside the unit of work you care about.
16
+ - Plain logs rarely connect a query to the request, job, or repository method that caused it.
17
+
18
+ QueryArgus exists to make query behavior visible, understandable, and actionable.
19
+
20
+ ## What it does
21
+
22
+ - Captures SQL queries through pluggable adapters.
23
+ - Associates queries with a root trace and nested business scopes.
24
+ - Infers a useful scope from caller code when you do not set one explicitly.
25
+ - Works in HTTP apps, background jobs, worker handlers, tests, and CLI code.
26
+ - Persists finished traces to JSONL or memory sinks.
27
+ - Generates offline reports in text, JSON, HTML, SVG badge, and Markdown summary formats.
28
+ - Provides pytest fixtures and assertions for query-aware tests.
29
+
30
+ ## Installation
31
+
32
+ Install the core package:
33
+
34
+ ```bash
35
+ pip install queryargus
36
+ ```
37
+
38
+ Install common integrations:
39
+
40
+ ```bash
41
+ pip install "queryargus[sqlalchemy,fastapi,testing]"
42
+ ```
43
+
44
+ Available extras:
45
+
46
+ - `sqlalchemy`: SQLAlchemy `Engine` and `AsyncEngine` instrumentation.
47
+ - `psycopg`: psycopg 3 sync and async connection instrumentation.
48
+ - `asyncpg`: asyncpg connection instrumentation.
49
+ - `fastapi`: FastAPI and Starlette middleware integration.
50
+ - `testing`: pytest plugin and testing helpers.
51
+
52
+ ## Quick start
53
+
54
+ `setup()` is the recommended entrypoint when you want one line to configure sinks, database instrumentation, and framework integration:
55
+
56
+ ```python
57
+ from fastapi import FastAPI
58
+ from sqlalchemy import create_engine
59
+ import queryargus
60
+
61
+ app = FastAPI()
62
+ engine = create_engine("sqlite:///app.db")
63
+
64
+ queryargus.setup(
65
+ adapter=engine,
66
+ framework=app,
67
+ sink="jsonl",
68
+ )
69
+ ```
70
+
71
+ With that in place:
72
+
73
+ - the SQLAlchemy adapter captures queries automatically
74
+ - the FastAPI middleware opens one trace per request
75
+ - traces are appended to `traces/queryargus.jsonl`
76
+
77
+ ## Core usage patterns
78
+
79
+ ### FastAPI or Starlette request tracing
80
+
81
+ ```python
82
+ from fastapi import FastAPI
83
+ from sqlalchemy import create_engine
84
+ import queryargus
85
+
86
+ app = FastAPI()
87
+ engine = create_engine("sqlite:///inventory.db")
88
+
89
+ queryargus.setup(adapter=engine, framework=app, sink="jsonl")
90
+ ```
91
+
92
+ Each HTTP request becomes a root trace named like `GET /products`.
93
+
94
+ ### Jobs, workers, and CLI functions
95
+
96
+ Use `@traced` when the function itself is the unit of work:
97
+
98
+ ```python
99
+ import queryargus
100
+
101
+ queryargus.setup(adapter=engine, sink="jsonl")
102
+
103
+ @queryargus.traced("billing.process_invoice")
104
+ def process_invoice(invoice_id: str) -> None:
105
+ repository.load_invoice(invoice_id)
106
+ service.apply_rules(invoice_id)
107
+ repository.mark_processed(invoice_id)
108
+ ```
109
+
110
+ If a trace is already active, `@traced` does not open a nested root trace.
111
+
112
+ ### Manual tracing
113
+
114
+ Use `start_trace()` when a context manager fits better than a decorator:
115
+
116
+ ```python
117
+ from queryargus import start_trace, trace_scope
118
+
119
+ with start_trace("inventory.rebuild_projection"):
120
+ with trace_scope("inventory_repository.load_snapshot"):
121
+ repository.load_snapshot()
122
+ ```
123
+
124
+ Important behavior:
125
+
126
+ - `start_trace()` raises `NestedTraceError` if a root trace is already active.
127
+ - `trace_scope()` is a no-op when there is no active trace.
128
+
129
+ ### Automatic business scopes on repositories and services
130
+
131
+ Instrument a class:
132
+
133
+ ```python
134
+ from queryargus import trace_methods
135
+
136
+ @trace_methods()
137
+ class StockRepository:
138
+ def get_by_id(self, stock_id: str):
139
+ ...
140
+
141
+ def list_all(self):
142
+ ...
143
+ ```
144
+
145
+ Instrument an existing instance:
146
+
147
+ ```python
148
+ from queryargus import instrument_object_methods
149
+
150
+ repository = instrument_object_methods(repository, namespace="products")
151
+ ```
152
+
153
+ That gives you scope labels such as `StockRepository.get_by_id` or `products.list_all` in reports.
154
+
155
+ ## Supported adapters and integrations
156
+
157
+ ### SQLAlchemy
158
+
159
+ Auto-detected by `setup(adapter=engine)` or explicitly installed:
160
+
161
+ ```python
162
+ from queryargus.adapters import instrument_sqlalchemy
163
+
164
+ instrument_sqlalchemy(engine)
165
+ ```
166
+
167
+ ### psycopg 3
168
+
169
+ ```python
170
+ from queryargus.adapters import instrument_psycopg
171
+
172
+ conn = instrument_psycopg(conn)
173
+ ```
174
+
175
+ ### asyncpg
176
+
177
+ ```python
178
+ from queryargus.adapters import instrument_asyncpg
179
+
180
+ conn = instrument_asyncpg(conn)
181
+ ```
182
+
183
+ ### FastAPI and Starlette
184
+
185
+ Auto-detected by `setup(framework=app)` or explicitly installed:
186
+
187
+ ```python
188
+ from queryargus.integrations.fastapi import instrument_fastapi
189
+ from queryargus.integrations.starlette import instrument_starlette
190
+
191
+ instrument_fastapi(app)
192
+ instrument_starlette(app)
193
+ ```
194
+
195
+ ## Sinks
196
+
197
+ QueryArgus ships with two built-in sinks:
198
+
199
+ - `JsonlSink`: appends one serialized trace per line to a JSONL file
200
+ - `MemorySink`: keeps traces in memory for tests and local experiments
201
+
202
+ Examples:
203
+
204
+ ```python
205
+ import queryargus
206
+
207
+ queryargus.setup(sink="jsonl")
208
+ queryargus.setup(sink="memory")
209
+ queryargus.setup(sink=[queryargus.MemorySink(), queryargus.JsonlSink("var/traces.jsonl")])
210
+ ```
211
+
212
+ When you omit `sink`, QueryArgus defaults to `JsonlSink("traces/queryargus.jsonl")`.
213
+
214
+ ## Testing support
215
+
216
+ Install the testing extra:
217
+
218
+ ```bash
219
+ pip install "queryargus[testing]"
220
+ ```
221
+
222
+ Pytest fixtures exposed through the `pytest11` entry point:
223
+
224
+ - `queryargus_memory_sink`
225
+ - `queryargus_trace`
226
+ - `queryargus_captured`
227
+
228
+ Useful helpers:
229
+
230
+ ```python
231
+ from queryargus.testing import (
232
+ assert_all_queries_scoped,
233
+ assert_max_duration_ms,
234
+ assert_no_n_plus_one,
235
+ assert_no_repeated_queries,
236
+ assert_query_count_at_most,
237
+ capture_queries,
238
+ )
239
+ ```
240
+
241
+ Example:
242
+
243
+ ```python
244
+ def test_repository_is_efficient(queryargus_trace):
245
+ repository.list_products()
246
+
247
+ assert_query_count_at_most(queryargus_trace, 3)
248
+ assert_no_n_plus_one(queryargus_trace)
249
+ ```
250
+
251
+ ## Offline reports
252
+
253
+ Generate a report from a JSONL trace file:
254
+
255
+ ```bash
256
+ queryargus-report traces/queryargus.jsonl
257
+ ```
258
+
259
+ Supported formats:
260
+
261
+ - `text`
262
+ - `json`
263
+ - `html`
264
+ - `badge`
265
+ - `summary`
266
+
267
+ Examples:
268
+
269
+ ```bash
270
+ queryargus-report traces/queryargus.jsonl --format html --output artifacts/queryargus-report
271
+ queryargus-report traces/queryargus.jsonl --format badge --output artifacts/queryargus-coverage.svg
272
+ queryargus-report traces/queryargus.jsonl --format summary --output artifacts/queryargus-summary.md
273
+ ```
274
+
275
+ The HTML report includes coverage summaries, entrypoint breakdowns, hotspot analysis, and N+1 detection.
276
+
277
+ ## Documentation
278
+
279
+ Detailed English documentation:
280
+
281
+ - [Documentation index](https://github.com/matheuss0xf/queryargus/blob/main/docs/en/index.md)
282
+ - [User guide](https://github.com/matheuss0xf/queryargus/blob/main/docs/en/user-guide.md)
283
+ - [API reference](https://github.com/matheuss0xf/queryargus/blob/main/docs/en/api-reference.md)
284
+ - [Publishing guide](https://github.com/matheuss0xf/queryargus/blob/main/docs/en/publishing.md)
285
+ - [Troubleshooting](https://github.com/matheuss0xf/queryargus/blob/main/docs/en/troubleshooting.md)
286
+
287
+ Detailed Brazilian Portuguese documentation:
288
+
289
+ - [Índice da documentação](https://github.com/matheuss0xf/queryargus/blob/main/docs/pt-BR/index.md)
290
+ - [Guia de uso](https://github.com/matheuss0xf/queryargus/blob/main/docs/pt-BR/guia-de-uso.md)
291
+ - [Referência da API](https://github.com/matheuss0xf/queryargus/blob/main/docs/pt-BR/referencia-da-api.md)
292
+ - [Guia de publicação](https://github.com/matheuss0xf/queryargus/blob/main/docs/pt-BR/publicacao.md)
293
+ - [Solução de problemas](https://github.com/matheuss0xf/queryargus/blob/main/docs/pt-BR/solucao-de-problemas.md)
294
+
295
+ ## Compatibility
296
+
297
+ - Python `>=3.10,<3.15`
298
+ - Typed package (`py.typed` included)
299
+ - Offline-first JSONL workflow by default
300
+ - Designed for application code, tests, and CI pipelines
301
+
302
+ ## Development status
303
+
304
+ The package is ready for early professional usage and packaging, with a deliberately small public API. The current release focuses on reliable trace capture, scope-aware analysis, and offline reporting.