reqly 0.1.0__tar.gz → 0.1.2__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.
- reqly-0.1.2/PKG-INFO +137 -0
- reqly-0.1.2/README.md +101 -0
- {reqly-0.1.0 → reqly-0.1.2}/pyproject.toml +4 -3
- {reqly-0.1.0 → reqly-0.1.2}/reqly/core/shipper.py +10 -3
- reqly-0.1.2/reqly.egg-info/PKG-INFO +137 -0
- reqly-0.1.0/PKG-INFO +0 -99
- reqly-0.1.0/README.md +0 -64
- reqly-0.1.0/reqly.egg-info/PKG-INFO +0 -99
- {reqly-0.1.0 → reqly-0.1.2}/reqly/__init__.py +0 -0
- {reqly-0.1.0 → reqly-0.1.2}/reqly/core/__init__.py +0 -0
- {reqly-0.1.0 → reqly-0.1.2}/reqly/core/buffer.py +0 -0
- {reqly-0.1.0 → reqly-0.1.2}/reqly/core/capture.py +0 -0
- {reqly-0.1.0 → reqly-0.1.2}/reqly/core/client.py +0 -0
- {reqly-0.1.0 → reqly-0.1.2}/reqly/core/config.py +0 -0
- {reqly-0.1.0 → reqly-0.1.2}/reqly/core/sampling.py +0 -0
- {reqly-0.1.0 → reqly-0.1.2}/reqly/integrations/__init__.py +0 -0
- {reqly-0.1.0 → reqly-0.1.2}/reqly/integrations/fastapi.py +0 -0
- {reqly-0.1.0 → reqly-0.1.2}/reqly/integrations/flask.py +0 -0
- {reqly-0.1.0 → reqly-0.1.2}/reqly.egg-info/SOURCES.txt +0 -0
- {reqly-0.1.0 → reqly-0.1.2}/reqly.egg-info/dependency_links.txt +0 -0
- {reqly-0.1.0 → reqly-0.1.2}/reqly.egg-info/requires.txt +0 -0
- {reqly-0.1.0 → reqly-0.1.2}/reqly.egg-info/top_level.txt +0 -0
- {reqly-0.1.0 → reqly-0.1.2}/setup.cfg +0 -0
- {reqly-0.1.0 → reqly-0.1.2}/tests/test_buffer.py +0 -0
- {reqly-0.1.0 → reqly-0.1.2}/tests/test_capture.py +0 -0
- {reqly-0.1.0 → reqly-0.1.2}/tests/test_fastapi_integration.py +0 -0
- {reqly-0.1.0 → reqly-0.1.2}/tests/test_flask_integration.py +0 -0
- {reqly-0.1.0 → reqly-0.1.2}/tests/test_sampling.py +0 -0
reqly-0.1.2/PKG-INFO
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: reqly
|
|
3
|
+
Version: 0.1.2
|
|
4
|
+
Summary: Auto-instrumentation SDK for FastAPI and Flask: zero-code latency, error rates, and status codes shipped to a Reqly collector.
|
|
5
|
+
Author: reqly
|
|
6
|
+
License-Expression: GPL-3.0-or-later
|
|
7
|
+
Project-URL: Homepage, https://reqly-sdk.vercel.app/
|
|
8
|
+
Project-URL: Repository, https://github.com/tanisheesh/reqly
|
|
9
|
+
Project-URL: Issues, https://github.com/tanisheesh/reqly/issues
|
|
10
|
+
Project-URL: Documentation, https://github.com/tanisheesh/reqly/blob/main/CONTRIBUTING.md
|
|
11
|
+
Project-URL: Live Demo, https://eventflow-g2h5.onrender.com
|
|
12
|
+
Keywords: observability,apm,monitoring,fastapi,flask,telemetry,metrics,latency,tracing
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
21
|
+
Classifier: Topic :: System :: Monitoring
|
|
22
|
+
Classifier: Framework :: FastAPI
|
|
23
|
+
Classifier: Framework :: Flask
|
|
24
|
+
Requires-Python: >=3.9
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
Requires-Dist: httpx<1.0,>=0.27
|
|
27
|
+
Provides-Extra: fastapi
|
|
28
|
+
Requires-Dist: fastapi>=0.100; extra == "fastapi"
|
|
29
|
+
Provides-Extra: flask
|
|
30
|
+
Requires-Dist: flask>=2.3; extra == "flask"
|
|
31
|
+
Provides-Extra: dev
|
|
32
|
+
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
33
|
+
Requires-Dist: fastapi>=0.100; extra == "dev"
|
|
34
|
+
Requires-Dist: flask>=2.3; extra == "dev"
|
|
35
|
+
Requires-Dist: httpx>=0.27; extra == "dev"
|
|
36
|
+
|
|
37
|
+
# reqly
|
|
38
|
+
|
|
39
|
+
**Open-source API observability SDK for FastAPI and Flask.**
|
|
40
|
+
Auto-instrument your app with 2 lines of code — get latency percentiles, error rates, status distribution, top routes, and weekly AI-generated anomaly reports.
|
|
41
|
+
|
|
42
|
+
[](https://pypi.org/project/reqly/)
|
|
43
|
+
[](https://pypi.org/project/reqly/)
|
|
44
|
+
[](https://github.com/tanisheesh/reqly/blob/main/LICENSE)
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Install
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
pip install reqly
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Usage
|
|
55
|
+
|
|
56
|
+
**FastAPI**
|
|
57
|
+
|
|
58
|
+
```python
|
|
59
|
+
import reqly
|
|
60
|
+
from fastapi import FastAPI
|
|
61
|
+
|
|
62
|
+
app = FastAPI()
|
|
63
|
+
reqly.instrument(app, service_name="checkout-api")
|
|
64
|
+
# Every route is now tracked — latency · error rate · status codes
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
**Flask**
|
|
68
|
+
|
|
69
|
+
```python
|
|
70
|
+
import reqly
|
|
71
|
+
from flask import Flask
|
|
72
|
+
|
|
73
|
+
app = Flask(__name__)
|
|
74
|
+
reqly.instrument(app, service_name="checkout-api")
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
`instrument()` auto-detects FastAPI vs Flask — no other code changes needed.
|
|
78
|
+
|
|
79
|
+
## What you get
|
|
80
|
+
|
|
81
|
+
- **p50 / p95 / p99 latency** per route
|
|
82
|
+
- **Error rates** and status code distribution (2xx / 3xx / 4xx / 5xx)
|
|
83
|
+
- **Top routes** ranked by volume and error rate
|
|
84
|
+
- **Live requests/min** tile, time windows 1h / 6h / 24h / 7d
|
|
85
|
+
- **Weekly AI anomaly report** — z-score detection with Groq (Llama 3.3-70b) writing the narrative
|
|
86
|
+
|
|
87
|
+
> "Your `/auth` endpoint degrades every Monday morning (08:00–10:00), with error rate at 18% vs. a 2% baseline and p95 latency at 1850ms vs. 320ms baseline."
|
|
88
|
+
|
|
89
|
+
## Live Demo
|
|
90
|
+
|
|
91
|
+
Reqly is running live against [EventFlow](https://eventflow-g2h5.onrender.com), a Flask event management app.
|
|
92
|
+
|
|
93
|
+
- **Demo app** → [eventflow-g2h5.onrender.com](https://eventflow-g2h5.onrender.com)
|
|
94
|
+
- **Metrics dashboard** → [reqly-eventflow-dashboard.onrender.com](https://reqly-eventflow-dashboard.onrender.com)
|
|
95
|
+
|
|
96
|
+
> Login as **Administrator** (`admin@eventhub.com` / `Admin@123`) → click **Metrics** in the nav.
|
|
97
|
+
|
|
98
|
+
## Configuration
|
|
99
|
+
|
|
100
|
+
Every option can be passed as a kwarg to `instrument()` or set via environment variable.
|
|
101
|
+
Resolution order: **kwarg → env var → default**.
|
|
102
|
+
|
|
103
|
+
| kwarg | env var | default |
|
|
104
|
+
|---|---|---|
|
|
105
|
+
| `service_name` | `REQLY_SERVICE_NAME` | `sys.argv[0]` basename |
|
|
106
|
+
| `collector_url` | `REQLY_COLLECTOR_URL` | `http://localhost:8000` |
|
|
107
|
+
| `api_key` | `REQLY_API_KEY` | `None` |
|
|
108
|
+
| `sample_rate` | `REQLY_SAMPLE_RATE` | `1.0` |
|
|
109
|
+
| `flush_interval_seconds` | `REQLY_FLUSH_INTERVAL_SECONDS` | `5.0` |
|
|
110
|
+
| `max_batch_size` | `REQLY_MAX_BATCH_SIZE` | `200` |
|
|
111
|
+
| `max_queue_size` | `REQLY_MAX_QUEUE_SIZE` | `2000` |
|
|
112
|
+
| `ignore_routes` | `REQLY_IGNORE_ROUTES` (comma-separated) | `/health,/metrics` |
|
|
113
|
+
| `capture_request_body` | `REQLY_CAPTURE_REQUEST_BODY` | `False` |
|
|
114
|
+
|
|
115
|
+
## Design guarantees
|
|
116
|
+
|
|
117
|
+
**Fail-open** — any internal SDK error is caught and logged once; instrumentation disables itself rather than raise into your app. A slow or unreachable collector never blocks request threads — all shipping happens on a background thread with strict HTTP timeouts.
|
|
118
|
+
|
|
119
|
+
**Bounded cardinality** — routes are captured as the framework's matched template (`/users/{id}`), never the raw path (`/users/123`). Unmatched paths collapse into a single `__unmatched__` bucket.
|
|
120
|
+
|
|
121
|
+
**Bounded memory** — events are held in a fixed-size in-memory queue; under backpressure, oldest events are dropped and counted rather than growing unbounded.
|
|
122
|
+
|
|
123
|
+
## Self-hosting
|
|
124
|
+
|
|
125
|
+
Reqly is fully self-hostable. Run the full stack (collector + TimescaleDB + dashboard) with Docker Compose:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
git clone https://github.com/tanisheesh/reqly.git
|
|
129
|
+
cd reqly
|
|
130
|
+
docker compose up -d
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
See the [repository](https://github.com/tanisheesh/reqly) and [CONTRIBUTING.md](https://github.com/tanisheesh/reqly/blob/main/CONTRIBUTING.md) for full setup instructions.
|
|
134
|
+
|
|
135
|
+
## License
|
|
136
|
+
|
|
137
|
+
GPL-3.0-or-later — see [LICENSE](https://github.com/tanisheesh/reqly/blob/main/LICENSE).
|
reqly-0.1.2/README.md
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# reqly
|
|
2
|
+
|
|
3
|
+
**Open-source API observability SDK for FastAPI and Flask.**
|
|
4
|
+
Auto-instrument your app with 2 lines of code — get latency percentiles, error rates, status distribution, top routes, and weekly AI-generated anomaly reports.
|
|
5
|
+
|
|
6
|
+
[](https://pypi.org/project/reqly/)
|
|
7
|
+
[](https://pypi.org/project/reqly/)
|
|
8
|
+
[](https://github.com/tanisheesh/reqly/blob/main/LICENSE)
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Install
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
pip install reqly
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Usage
|
|
19
|
+
|
|
20
|
+
**FastAPI**
|
|
21
|
+
|
|
22
|
+
```python
|
|
23
|
+
import reqly
|
|
24
|
+
from fastapi import FastAPI
|
|
25
|
+
|
|
26
|
+
app = FastAPI()
|
|
27
|
+
reqly.instrument(app, service_name="checkout-api")
|
|
28
|
+
# Every route is now tracked — latency · error rate · status codes
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
**Flask**
|
|
32
|
+
|
|
33
|
+
```python
|
|
34
|
+
import reqly
|
|
35
|
+
from flask import Flask
|
|
36
|
+
|
|
37
|
+
app = Flask(__name__)
|
|
38
|
+
reqly.instrument(app, service_name="checkout-api")
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
`instrument()` auto-detects FastAPI vs Flask — no other code changes needed.
|
|
42
|
+
|
|
43
|
+
## What you get
|
|
44
|
+
|
|
45
|
+
- **p50 / p95 / p99 latency** per route
|
|
46
|
+
- **Error rates** and status code distribution (2xx / 3xx / 4xx / 5xx)
|
|
47
|
+
- **Top routes** ranked by volume and error rate
|
|
48
|
+
- **Live requests/min** tile, time windows 1h / 6h / 24h / 7d
|
|
49
|
+
- **Weekly AI anomaly report** — z-score detection with Groq (Llama 3.3-70b) writing the narrative
|
|
50
|
+
|
|
51
|
+
> "Your `/auth` endpoint degrades every Monday morning (08:00–10:00), with error rate at 18% vs. a 2% baseline and p95 latency at 1850ms vs. 320ms baseline."
|
|
52
|
+
|
|
53
|
+
## Live Demo
|
|
54
|
+
|
|
55
|
+
Reqly is running live against [EventFlow](https://eventflow-g2h5.onrender.com), a Flask event management app.
|
|
56
|
+
|
|
57
|
+
- **Demo app** → [eventflow-g2h5.onrender.com](https://eventflow-g2h5.onrender.com)
|
|
58
|
+
- **Metrics dashboard** → [reqly-eventflow-dashboard.onrender.com](https://reqly-eventflow-dashboard.onrender.com)
|
|
59
|
+
|
|
60
|
+
> Login as **Administrator** (`admin@eventhub.com` / `Admin@123`) → click **Metrics** in the nav.
|
|
61
|
+
|
|
62
|
+
## Configuration
|
|
63
|
+
|
|
64
|
+
Every option can be passed as a kwarg to `instrument()` or set via environment variable.
|
|
65
|
+
Resolution order: **kwarg → env var → default**.
|
|
66
|
+
|
|
67
|
+
| kwarg | env var | default |
|
|
68
|
+
|---|---|---|
|
|
69
|
+
| `service_name` | `REQLY_SERVICE_NAME` | `sys.argv[0]` basename |
|
|
70
|
+
| `collector_url` | `REQLY_COLLECTOR_URL` | `http://localhost:8000` |
|
|
71
|
+
| `api_key` | `REQLY_API_KEY` | `None` |
|
|
72
|
+
| `sample_rate` | `REQLY_SAMPLE_RATE` | `1.0` |
|
|
73
|
+
| `flush_interval_seconds` | `REQLY_FLUSH_INTERVAL_SECONDS` | `5.0` |
|
|
74
|
+
| `max_batch_size` | `REQLY_MAX_BATCH_SIZE` | `200` |
|
|
75
|
+
| `max_queue_size` | `REQLY_MAX_QUEUE_SIZE` | `2000` |
|
|
76
|
+
| `ignore_routes` | `REQLY_IGNORE_ROUTES` (comma-separated) | `/health,/metrics` |
|
|
77
|
+
| `capture_request_body` | `REQLY_CAPTURE_REQUEST_BODY` | `False` |
|
|
78
|
+
|
|
79
|
+
## Design guarantees
|
|
80
|
+
|
|
81
|
+
**Fail-open** — any internal SDK error is caught and logged once; instrumentation disables itself rather than raise into your app. A slow or unreachable collector never blocks request threads — all shipping happens on a background thread with strict HTTP timeouts.
|
|
82
|
+
|
|
83
|
+
**Bounded cardinality** — routes are captured as the framework's matched template (`/users/{id}`), never the raw path (`/users/123`). Unmatched paths collapse into a single `__unmatched__` bucket.
|
|
84
|
+
|
|
85
|
+
**Bounded memory** — events are held in a fixed-size in-memory queue; under backpressure, oldest events are dropped and counted rather than growing unbounded.
|
|
86
|
+
|
|
87
|
+
## Self-hosting
|
|
88
|
+
|
|
89
|
+
Reqly is fully self-hostable. Run the full stack (collector + TimescaleDB + dashboard) with Docker Compose:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
git clone https://github.com/tanisheesh/reqly.git
|
|
93
|
+
cd reqly
|
|
94
|
+
docker compose up -d
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
See the [repository](https://github.com/tanisheesh/reqly) and [CONTRIBUTING.md](https://github.com/tanisheesh/reqly/blob/main/CONTRIBUTING.md) for full setup instructions.
|
|
98
|
+
|
|
99
|
+
## License
|
|
100
|
+
|
|
101
|
+
GPL-3.0-or-later — see [LICENSE](https://github.com/tanisheesh/reqly/blob/main/LICENSE).
|
|
@@ -4,11 +4,11 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "reqly"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.2"
|
|
8
8
|
description = "Auto-instrumentation SDK for FastAPI and Flask: zero-code latency, error rates, and status codes shipped to a Reqly collector."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.9"
|
|
11
|
-
license = "
|
|
11
|
+
license = "GPL-3.0-or-later"
|
|
12
12
|
authors = [{ name = "reqly" }]
|
|
13
13
|
keywords = [
|
|
14
14
|
"observability", "apm", "monitoring", "fastapi", "flask",
|
|
@@ -32,10 +32,11 @@ dependencies = [
|
|
|
32
32
|
]
|
|
33
33
|
|
|
34
34
|
[project.urls]
|
|
35
|
-
Homepage = "https://
|
|
35
|
+
Homepage = "https://reqly-sdk.vercel.app/"
|
|
36
36
|
Repository = "https://github.com/tanisheesh/reqly"
|
|
37
37
|
Issues = "https://github.com/tanisheesh/reqly/issues"
|
|
38
38
|
Documentation = "https://github.com/tanisheesh/reqly/blob/main/CONTRIBUTING.md"
|
|
39
|
+
"Live Demo" = "https://eventflow-g2h5.onrender.com"
|
|
39
40
|
|
|
40
41
|
[project.optional-dependencies]
|
|
41
42
|
fastapi = ["fastapi>=0.100"]
|
|
@@ -59,12 +59,19 @@ class Shipper:
|
|
|
59
59
|
for attempt in range(_MAX_RETRIES):
|
|
60
60
|
try:
|
|
61
61
|
response = self._client.post("/v1/ingest", json=payload)
|
|
62
|
-
if response.status_code <
|
|
62
|
+
if response.status_code < 400:
|
|
63
63
|
self.shipped_events += len(events)
|
|
64
64
|
return True
|
|
65
|
+
if response.status_code != 429:
|
|
66
|
+
# permanent client error (auth failure, bad payload, etc.) — no point retrying
|
|
67
|
+
logger.warning(
|
|
68
|
+
"reqly: collector rejected batch with %s, dropping",
|
|
69
|
+
response.status_code,
|
|
70
|
+
)
|
|
71
|
+
self.dropped_batches += 1
|
|
72
|
+
return False
|
|
65
73
|
logger.debug(
|
|
66
|
-
"reqly:
|
|
67
|
-
response.status_code,
|
|
74
|
+
"reqly: rate-limited (429), attempt %d/%d",
|
|
68
75
|
attempt + 1,
|
|
69
76
|
_MAX_RETRIES,
|
|
70
77
|
)
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: reqly
|
|
3
|
+
Version: 0.1.2
|
|
4
|
+
Summary: Auto-instrumentation SDK for FastAPI and Flask: zero-code latency, error rates, and status codes shipped to a Reqly collector.
|
|
5
|
+
Author: reqly
|
|
6
|
+
License-Expression: GPL-3.0-or-later
|
|
7
|
+
Project-URL: Homepage, https://reqly-sdk.vercel.app/
|
|
8
|
+
Project-URL: Repository, https://github.com/tanisheesh/reqly
|
|
9
|
+
Project-URL: Issues, https://github.com/tanisheesh/reqly/issues
|
|
10
|
+
Project-URL: Documentation, https://github.com/tanisheesh/reqly/blob/main/CONTRIBUTING.md
|
|
11
|
+
Project-URL: Live Demo, https://eventflow-g2h5.onrender.com
|
|
12
|
+
Keywords: observability,apm,monitoring,fastapi,flask,telemetry,metrics,latency,tracing
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
21
|
+
Classifier: Topic :: System :: Monitoring
|
|
22
|
+
Classifier: Framework :: FastAPI
|
|
23
|
+
Classifier: Framework :: Flask
|
|
24
|
+
Requires-Python: >=3.9
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
Requires-Dist: httpx<1.0,>=0.27
|
|
27
|
+
Provides-Extra: fastapi
|
|
28
|
+
Requires-Dist: fastapi>=0.100; extra == "fastapi"
|
|
29
|
+
Provides-Extra: flask
|
|
30
|
+
Requires-Dist: flask>=2.3; extra == "flask"
|
|
31
|
+
Provides-Extra: dev
|
|
32
|
+
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
33
|
+
Requires-Dist: fastapi>=0.100; extra == "dev"
|
|
34
|
+
Requires-Dist: flask>=2.3; extra == "dev"
|
|
35
|
+
Requires-Dist: httpx>=0.27; extra == "dev"
|
|
36
|
+
|
|
37
|
+
# reqly
|
|
38
|
+
|
|
39
|
+
**Open-source API observability SDK for FastAPI and Flask.**
|
|
40
|
+
Auto-instrument your app with 2 lines of code — get latency percentiles, error rates, status distribution, top routes, and weekly AI-generated anomaly reports.
|
|
41
|
+
|
|
42
|
+
[](https://pypi.org/project/reqly/)
|
|
43
|
+
[](https://pypi.org/project/reqly/)
|
|
44
|
+
[](https://github.com/tanisheesh/reqly/blob/main/LICENSE)
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Install
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
pip install reqly
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Usage
|
|
55
|
+
|
|
56
|
+
**FastAPI**
|
|
57
|
+
|
|
58
|
+
```python
|
|
59
|
+
import reqly
|
|
60
|
+
from fastapi import FastAPI
|
|
61
|
+
|
|
62
|
+
app = FastAPI()
|
|
63
|
+
reqly.instrument(app, service_name="checkout-api")
|
|
64
|
+
# Every route is now tracked — latency · error rate · status codes
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
**Flask**
|
|
68
|
+
|
|
69
|
+
```python
|
|
70
|
+
import reqly
|
|
71
|
+
from flask import Flask
|
|
72
|
+
|
|
73
|
+
app = Flask(__name__)
|
|
74
|
+
reqly.instrument(app, service_name="checkout-api")
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
`instrument()` auto-detects FastAPI vs Flask — no other code changes needed.
|
|
78
|
+
|
|
79
|
+
## What you get
|
|
80
|
+
|
|
81
|
+
- **p50 / p95 / p99 latency** per route
|
|
82
|
+
- **Error rates** and status code distribution (2xx / 3xx / 4xx / 5xx)
|
|
83
|
+
- **Top routes** ranked by volume and error rate
|
|
84
|
+
- **Live requests/min** tile, time windows 1h / 6h / 24h / 7d
|
|
85
|
+
- **Weekly AI anomaly report** — z-score detection with Groq (Llama 3.3-70b) writing the narrative
|
|
86
|
+
|
|
87
|
+
> "Your `/auth` endpoint degrades every Monday morning (08:00–10:00), with error rate at 18% vs. a 2% baseline and p95 latency at 1850ms vs. 320ms baseline."
|
|
88
|
+
|
|
89
|
+
## Live Demo
|
|
90
|
+
|
|
91
|
+
Reqly is running live against [EventFlow](https://eventflow-g2h5.onrender.com), a Flask event management app.
|
|
92
|
+
|
|
93
|
+
- **Demo app** → [eventflow-g2h5.onrender.com](https://eventflow-g2h5.onrender.com)
|
|
94
|
+
- **Metrics dashboard** → [reqly-eventflow-dashboard.onrender.com](https://reqly-eventflow-dashboard.onrender.com)
|
|
95
|
+
|
|
96
|
+
> Login as **Administrator** (`admin@eventhub.com` / `Admin@123`) → click **Metrics** in the nav.
|
|
97
|
+
|
|
98
|
+
## Configuration
|
|
99
|
+
|
|
100
|
+
Every option can be passed as a kwarg to `instrument()` or set via environment variable.
|
|
101
|
+
Resolution order: **kwarg → env var → default**.
|
|
102
|
+
|
|
103
|
+
| kwarg | env var | default |
|
|
104
|
+
|---|---|---|
|
|
105
|
+
| `service_name` | `REQLY_SERVICE_NAME` | `sys.argv[0]` basename |
|
|
106
|
+
| `collector_url` | `REQLY_COLLECTOR_URL` | `http://localhost:8000` |
|
|
107
|
+
| `api_key` | `REQLY_API_KEY` | `None` |
|
|
108
|
+
| `sample_rate` | `REQLY_SAMPLE_RATE` | `1.0` |
|
|
109
|
+
| `flush_interval_seconds` | `REQLY_FLUSH_INTERVAL_SECONDS` | `5.0` |
|
|
110
|
+
| `max_batch_size` | `REQLY_MAX_BATCH_SIZE` | `200` |
|
|
111
|
+
| `max_queue_size` | `REQLY_MAX_QUEUE_SIZE` | `2000` |
|
|
112
|
+
| `ignore_routes` | `REQLY_IGNORE_ROUTES` (comma-separated) | `/health,/metrics` |
|
|
113
|
+
| `capture_request_body` | `REQLY_CAPTURE_REQUEST_BODY` | `False` |
|
|
114
|
+
|
|
115
|
+
## Design guarantees
|
|
116
|
+
|
|
117
|
+
**Fail-open** — any internal SDK error is caught and logged once; instrumentation disables itself rather than raise into your app. A slow or unreachable collector never blocks request threads — all shipping happens on a background thread with strict HTTP timeouts.
|
|
118
|
+
|
|
119
|
+
**Bounded cardinality** — routes are captured as the framework's matched template (`/users/{id}`), never the raw path (`/users/123`). Unmatched paths collapse into a single `__unmatched__` bucket.
|
|
120
|
+
|
|
121
|
+
**Bounded memory** — events are held in a fixed-size in-memory queue; under backpressure, oldest events are dropped and counted rather than growing unbounded.
|
|
122
|
+
|
|
123
|
+
## Self-hosting
|
|
124
|
+
|
|
125
|
+
Reqly is fully self-hostable. Run the full stack (collector + TimescaleDB + dashboard) with Docker Compose:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
git clone https://github.com/tanisheesh/reqly.git
|
|
129
|
+
cd reqly
|
|
130
|
+
docker compose up -d
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
See the [repository](https://github.com/tanisheesh/reqly) and [CONTRIBUTING.md](https://github.com/tanisheesh/reqly/blob/main/CONTRIBUTING.md) for full setup instructions.
|
|
134
|
+
|
|
135
|
+
## License
|
|
136
|
+
|
|
137
|
+
GPL-3.0-or-later — see [LICENSE](https://github.com/tanisheesh/reqly/blob/main/LICENSE).
|
reqly-0.1.0/PKG-INFO
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: reqly
|
|
3
|
-
Version: 0.1.0
|
|
4
|
-
Summary: Auto-instrumentation SDK for FastAPI and Flask: zero-code latency, error rates, and status codes shipped to a Reqly collector.
|
|
5
|
-
Author: reqly
|
|
6
|
-
License-Expression: MIT
|
|
7
|
-
Project-URL: Homepage, https://github.com/tanisheesh/reqly
|
|
8
|
-
Project-URL: Repository, https://github.com/tanisheesh/reqly
|
|
9
|
-
Project-URL: Issues, https://github.com/tanisheesh/reqly/issues
|
|
10
|
-
Project-URL: Documentation, https://github.com/tanisheesh/reqly/blob/main/CONTRIBUTING.md
|
|
11
|
-
Keywords: observability,apm,monitoring,fastapi,flask,telemetry,metrics,latency,tracing
|
|
12
|
-
Classifier: Development Status :: 4 - Beta
|
|
13
|
-
Classifier: Intended Audience :: Developers
|
|
14
|
-
Classifier: Programming Language :: Python :: 3
|
|
15
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
16
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
-
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
20
|
-
Classifier: Topic :: System :: Monitoring
|
|
21
|
-
Classifier: Framework :: FastAPI
|
|
22
|
-
Classifier: Framework :: Flask
|
|
23
|
-
Requires-Python: >=3.9
|
|
24
|
-
Description-Content-Type: text/markdown
|
|
25
|
-
Requires-Dist: httpx<1.0,>=0.27
|
|
26
|
-
Provides-Extra: fastapi
|
|
27
|
-
Requires-Dist: fastapi>=0.100; extra == "fastapi"
|
|
28
|
-
Provides-Extra: flask
|
|
29
|
-
Requires-Dist: flask>=2.3; extra == "flask"
|
|
30
|
-
Provides-Extra: dev
|
|
31
|
-
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
32
|
-
Requires-Dist: fastapi>=0.100; extra == "dev"
|
|
33
|
-
Requires-Dist: flask>=2.3; extra == "dev"
|
|
34
|
-
Requires-Dist: httpx>=0.27; extra == "dev"
|
|
35
|
-
|
|
36
|
-
# Reqly
|
|
37
|
-
|
|
38
|
-
Auto-instrumentation SDK for FastAPI and Flask. One line captures latency, status codes, and error rates for every request and ships them to an [Reqly collector](../collector).
|
|
39
|
-
|
|
40
|
-
## Install
|
|
41
|
-
|
|
42
|
-
```bash
|
|
43
|
-
pip install reqly
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
(For local development against this monorepo: `pip install -e ./sdk[dev]`.)
|
|
47
|
-
|
|
48
|
-
## Usage
|
|
49
|
-
|
|
50
|
-
```python
|
|
51
|
-
from fastapi import FastAPI
|
|
52
|
-
import reqly
|
|
53
|
-
|
|
54
|
-
app = FastAPI()
|
|
55
|
-
reqly.instrument(app, service_name="checkout-api")
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
```python
|
|
59
|
-
from flask import Flask
|
|
60
|
-
import reqly
|
|
61
|
-
|
|
62
|
-
app = Flask(__name__)
|
|
63
|
-
reqly.instrument(app, service_name="checkout-api")
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
`instrument()` auto-detects FastAPI vs Flask — no other code changes needed.
|
|
67
|
-
|
|
68
|
-
## Configuration
|
|
69
|
-
|
|
70
|
-
Every option can be passed as a kwarg to `instrument()` or set via environment variable. Resolution order: kwarg > env var > default.
|
|
71
|
-
|
|
72
|
-
| kwarg | env var | default |
|
|
73
|
-
|---|---|---|
|
|
74
|
-
| `service_name` | `REQLY_SERVICE_NAME` | `sys.argv[0]` basename |
|
|
75
|
-
| `collector_url` | `REQLY_COLLECTOR_URL` | `http://localhost:8000` |
|
|
76
|
-
| `api_key` | `REQLY_API_KEY` | `None` |
|
|
77
|
-
| `sample_rate` | `REQLY_SAMPLE_RATE` | `1.0` |
|
|
78
|
-
| `flush_interval_seconds` | `REQLY_FLUSH_INTERVAL_SECONDS` | `5.0` |
|
|
79
|
-
| `max_batch_size` | `REQLY_MAX_BATCH_SIZE` | `200` |
|
|
80
|
-
| `max_queue_size` | `REQLY_MAX_QUEUE_SIZE` | `2000` |
|
|
81
|
-
| `ignore_routes` | `REQLY_IGNORE_ROUTES` (comma-separated) | `/health,/metrics` |
|
|
82
|
-
| `capture_request_body` | `REQLY_CAPTURE_REQUEST_BODY` | `False` |
|
|
83
|
-
|
|
84
|
-
## Design guarantees
|
|
85
|
-
|
|
86
|
-
- **Fails open.** Any internal SDK error is caught and logged once; instrumentation then disables itself rather than risk repeatedly raising into your app. A slow or unreachable collector never slows down your app — all shipping happens off a background thread with strict per-phase HTTP timeouts.
|
|
87
|
-
- **Bounded cardinality.** Captured routes are the framework's matched route *template* (`/users/{id}`), never the raw path (`/users/123`). Unmatched paths (404s, scanners) collapse into a single `__unmatched__` bucket instead of blowing up cardinality.
|
|
88
|
-
- **Bounded memory.** Events are held in a fixed-size in-memory queue; under sustained backpressure, the oldest events are dropped (and counted) rather than growing unbounded or blocking request threads.
|
|
89
|
-
|
|
90
|
-
## Architecture
|
|
91
|
-
|
|
92
|
-
See [`../ARCHITECTURE.md`](../ARCHITECTURE.md#2-sdk-design) for the full design rationale (why pure ASGI middleware over `BaseHTTPMiddleware`, why a background thread over `asyncio.create_task`, why `httpx` over `requests`, etc).
|
|
93
|
-
|
|
94
|
-
## Running tests
|
|
95
|
-
|
|
96
|
-
```bash
|
|
97
|
-
pip install -e .[dev]
|
|
98
|
-
pytest
|
|
99
|
-
```
|
reqly-0.1.0/README.md
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
# Reqly
|
|
2
|
-
|
|
3
|
-
Auto-instrumentation SDK for FastAPI and Flask. One line captures latency, status codes, and error rates for every request and ships them to an [Reqly collector](../collector).
|
|
4
|
-
|
|
5
|
-
## Install
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
pip install reqly
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
(For local development against this monorepo: `pip install -e ./sdk[dev]`.)
|
|
12
|
-
|
|
13
|
-
## Usage
|
|
14
|
-
|
|
15
|
-
```python
|
|
16
|
-
from fastapi import FastAPI
|
|
17
|
-
import reqly
|
|
18
|
-
|
|
19
|
-
app = FastAPI()
|
|
20
|
-
reqly.instrument(app, service_name="checkout-api")
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
```python
|
|
24
|
-
from flask import Flask
|
|
25
|
-
import reqly
|
|
26
|
-
|
|
27
|
-
app = Flask(__name__)
|
|
28
|
-
reqly.instrument(app, service_name="checkout-api")
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
`instrument()` auto-detects FastAPI vs Flask — no other code changes needed.
|
|
32
|
-
|
|
33
|
-
## Configuration
|
|
34
|
-
|
|
35
|
-
Every option can be passed as a kwarg to `instrument()` or set via environment variable. Resolution order: kwarg > env var > default.
|
|
36
|
-
|
|
37
|
-
| kwarg | env var | default |
|
|
38
|
-
|---|---|---|
|
|
39
|
-
| `service_name` | `REQLY_SERVICE_NAME` | `sys.argv[0]` basename |
|
|
40
|
-
| `collector_url` | `REQLY_COLLECTOR_URL` | `http://localhost:8000` |
|
|
41
|
-
| `api_key` | `REQLY_API_KEY` | `None` |
|
|
42
|
-
| `sample_rate` | `REQLY_SAMPLE_RATE` | `1.0` |
|
|
43
|
-
| `flush_interval_seconds` | `REQLY_FLUSH_INTERVAL_SECONDS` | `5.0` |
|
|
44
|
-
| `max_batch_size` | `REQLY_MAX_BATCH_SIZE` | `200` |
|
|
45
|
-
| `max_queue_size` | `REQLY_MAX_QUEUE_SIZE` | `2000` |
|
|
46
|
-
| `ignore_routes` | `REQLY_IGNORE_ROUTES` (comma-separated) | `/health,/metrics` |
|
|
47
|
-
| `capture_request_body` | `REQLY_CAPTURE_REQUEST_BODY` | `False` |
|
|
48
|
-
|
|
49
|
-
## Design guarantees
|
|
50
|
-
|
|
51
|
-
- **Fails open.** Any internal SDK error is caught and logged once; instrumentation then disables itself rather than risk repeatedly raising into your app. A slow or unreachable collector never slows down your app — all shipping happens off a background thread with strict per-phase HTTP timeouts.
|
|
52
|
-
- **Bounded cardinality.** Captured routes are the framework's matched route *template* (`/users/{id}`), never the raw path (`/users/123`). Unmatched paths (404s, scanners) collapse into a single `__unmatched__` bucket instead of blowing up cardinality.
|
|
53
|
-
- **Bounded memory.** Events are held in a fixed-size in-memory queue; under sustained backpressure, the oldest events are dropped (and counted) rather than growing unbounded or blocking request threads.
|
|
54
|
-
|
|
55
|
-
## Architecture
|
|
56
|
-
|
|
57
|
-
See [`../ARCHITECTURE.md`](../ARCHITECTURE.md#2-sdk-design) for the full design rationale (why pure ASGI middleware over `BaseHTTPMiddleware`, why a background thread over `asyncio.create_task`, why `httpx` over `requests`, etc).
|
|
58
|
-
|
|
59
|
-
## Running tests
|
|
60
|
-
|
|
61
|
-
```bash
|
|
62
|
-
pip install -e .[dev]
|
|
63
|
-
pytest
|
|
64
|
-
```
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: reqly
|
|
3
|
-
Version: 0.1.0
|
|
4
|
-
Summary: Auto-instrumentation SDK for FastAPI and Flask: zero-code latency, error rates, and status codes shipped to a Reqly collector.
|
|
5
|
-
Author: reqly
|
|
6
|
-
License-Expression: MIT
|
|
7
|
-
Project-URL: Homepage, https://github.com/tanisheesh/reqly
|
|
8
|
-
Project-URL: Repository, https://github.com/tanisheesh/reqly
|
|
9
|
-
Project-URL: Issues, https://github.com/tanisheesh/reqly/issues
|
|
10
|
-
Project-URL: Documentation, https://github.com/tanisheesh/reqly/blob/main/CONTRIBUTING.md
|
|
11
|
-
Keywords: observability,apm,monitoring,fastapi,flask,telemetry,metrics,latency,tracing
|
|
12
|
-
Classifier: Development Status :: 4 - Beta
|
|
13
|
-
Classifier: Intended Audience :: Developers
|
|
14
|
-
Classifier: Programming Language :: Python :: 3
|
|
15
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
16
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
-
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
20
|
-
Classifier: Topic :: System :: Monitoring
|
|
21
|
-
Classifier: Framework :: FastAPI
|
|
22
|
-
Classifier: Framework :: Flask
|
|
23
|
-
Requires-Python: >=3.9
|
|
24
|
-
Description-Content-Type: text/markdown
|
|
25
|
-
Requires-Dist: httpx<1.0,>=0.27
|
|
26
|
-
Provides-Extra: fastapi
|
|
27
|
-
Requires-Dist: fastapi>=0.100; extra == "fastapi"
|
|
28
|
-
Provides-Extra: flask
|
|
29
|
-
Requires-Dist: flask>=2.3; extra == "flask"
|
|
30
|
-
Provides-Extra: dev
|
|
31
|
-
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
32
|
-
Requires-Dist: fastapi>=0.100; extra == "dev"
|
|
33
|
-
Requires-Dist: flask>=2.3; extra == "dev"
|
|
34
|
-
Requires-Dist: httpx>=0.27; extra == "dev"
|
|
35
|
-
|
|
36
|
-
# Reqly
|
|
37
|
-
|
|
38
|
-
Auto-instrumentation SDK for FastAPI and Flask. One line captures latency, status codes, and error rates for every request and ships them to an [Reqly collector](../collector).
|
|
39
|
-
|
|
40
|
-
## Install
|
|
41
|
-
|
|
42
|
-
```bash
|
|
43
|
-
pip install reqly
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
(For local development against this monorepo: `pip install -e ./sdk[dev]`.)
|
|
47
|
-
|
|
48
|
-
## Usage
|
|
49
|
-
|
|
50
|
-
```python
|
|
51
|
-
from fastapi import FastAPI
|
|
52
|
-
import reqly
|
|
53
|
-
|
|
54
|
-
app = FastAPI()
|
|
55
|
-
reqly.instrument(app, service_name="checkout-api")
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
```python
|
|
59
|
-
from flask import Flask
|
|
60
|
-
import reqly
|
|
61
|
-
|
|
62
|
-
app = Flask(__name__)
|
|
63
|
-
reqly.instrument(app, service_name="checkout-api")
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
`instrument()` auto-detects FastAPI vs Flask — no other code changes needed.
|
|
67
|
-
|
|
68
|
-
## Configuration
|
|
69
|
-
|
|
70
|
-
Every option can be passed as a kwarg to `instrument()` or set via environment variable. Resolution order: kwarg > env var > default.
|
|
71
|
-
|
|
72
|
-
| kwarg | env var | default |
|
|
73
|
-
|---|---|---|
|
|
74
|
-
| `service_name` | `REQLY_SERVICE_NAME` | `sys.argv[0]` basename |
|
|
75
|
-
| `collector_url` | `REQLY_COLLECTOR_URL` | `http://localhost:8000` |
|
|
76
|
-
| `api_key` | `REQLY_API_KEY` | `None` |
|
|
77
|
-
| `sample_rate` | `REQLY_SAMPLE_RATE` | `1.0` |
|
|
78
|
-
| `flush_interval_seconds` | `REQLY_FLUSH_INTERVAL_SECONDS` | `5.0` |
|
|
79
|
-
| `max_batch_size` | `REQLY_MAX_BATCH_SIZE` | `200` |
|
|
80
|
-
| `max_queue_size` | `REQLY_MAX_QUEUE_SIZE` | `2000` |
|
|
81
|
-
| `ignore_routes` | `REQLY_IGNORE_ROUTES` (comma-separated) | `/health,/metrics` |
|
|
82
|
-
| `capture_request_body` | `REQLY_CAPTURE_REQUEST_BODY` | `False` |
|
|
83
|
-
|
|
84
|
-
## Design guarantees
|
|
85
|
-
|
|
86
|
-
- **Fails open.** Any internal SDK error is caught and logged once; instrumentation then disables itself rather than risk repeatedly raising into your app. A slow or unreachable collector never slows down your app — all shipping happens off a background thread with strict per-phase HTTP timeouts.
|
|
87
|
-
- **Bounded cardinality.** Captured routes are the framework's matched route *template* (`/users/{id}`), never the raw path (`/users/123`). Unmatched paths (404s, scanners) collapse into a single `__unmatched__` bucket instead of blowing up cardinality.
|
|
88
|
-
- **Bounded memory.** Events are held in a fixed-size in-memory queue; under sustained backpressure, the oldest events are dropped (and counted) rather than growing unbounded or blocking request threads.
|
|
89
|
-
|
|
90
|
-
## Architecture
|
|
91
|
-
|
|
92
|
-
See [`../ARCHITECTURE.md`](../ARCHITECTURE.md#2-sdk-design) for the full design rationale (why pure ASGI middleware over `BaseHTTPMiddleware`, why a background thread over `asyncio.create_task`, why `httpx` over `requests`, etc).
|
|
93
|
-
|
|
94
|
-
## Running tests
|
|
95
|
-
|
|
96
|
-
```bash
|
|
97
|
-
pip install -e .[dev]
|
|
98
|
-
pytest
|
|
99
|
-
```
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|