Skip to content

Commit 3bb7732

Browse files
committed
feat: add robyn-config as optional dependencies
1 parent d19b67f commit 3bb7732

12 files changed

Lines changed: 356 additions & 52 deletions

File tree

312 KB
Loading
200 KB
Loading
420 KB
Loading
309 KB
Loading
286 KB
Loading
778 KB
Loading
598 KB
Loading

docs_src/src/pages/documentation/en/api_reference/index.mdx

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,46 +5,43 @@ Once upon a time in the city of Gotham, there was a powerful superhero named Rob
55

66
One day, Batman approached Robyn for help with building a web application. Batman had heard about Robyn's powerful features and wanted to harness them to create a remarkable application. Batman was looking for an ally and in Robyn, he found the best one!
77

8-
98
## Installing Robyn
109

11-
1210
Robyn is a Python library that you can install using `pip` or `conda`
1311

1412
<CodeGroup title="installation">
1513

16-
```bash {{ title: 'pip' }}
17-
pip install robyn
18-
```
14+
```bash {{ title: 'pip' }}
15+
pip install robyn
16+
```
17+
18+
```bash {{ title: 'conda' }}
19+
conda install robyn -c conda-forge
20+
```
1921

20-
```bash {{ title: 'conda' }}
21-
conda install robyn -c conda-forge
22-
```
2322
</CodeGroup>
2423

25-
While there are other more extensions of Robyn like
24+
Robyn also ships optional extras for templating, Pydantic validation, project scaffolding with `robyn-config`, and a combined `all` bundle:
2625

2726
<CodeGroup title="installation">
2827

29-
```bash {{ title: 'pip' }}
30-
pip install "robyn[templating]"
31-
```
32-
33-
```bash {{ title: 'conda' }}
34-
conda install "robyn[templating]" -c conda-forge
35-
```
36-
</CodeGroup>
28+
```bash {{ title: 'pip' }}
29+
pip install "robyn[templating]"
30+
pip install "robyn[pydantic]"
31+
pip install "robyn[robyn-config]"
32+
pip install "robyn[all]"
33+
```
3734

35+
```bash {{ title: 'conda' }}
36+
conda install "robyn[templating]" -c conda-forge
37+
```
3838

39+
</CodeGroup>
3940

4041
It is recommended to install the base package first and then install the extensions as needed.
4142

4243
## What's next?
4344

4445
Now, we can start using Robyn to build our application.
4546

46-
4747
- [Getting Started](/documentation/en/api_reference/getting_started)
48-
49-
50-

docs_src/src/pages/documentation/en/api_reference/testing.mdx

Lines changed: 32 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
export const description =
2-
'On this page, we'll explore Robyn\'s built-in TestClient for fast, in-process unit testing without starting a server.'
2+
'On this page, we\'ll explore Robyn\'s built-in TestClient for fast, in-process unit testing without starting a server.'
33

44
## Testing
55

@@ -35,6 +35,7 @@ Import `TestClient` from `robyn.testing`, pass your app to it, and start making
3535
assert response.text == "Hello, World!"
3636
```
3737
</CodeGroup>
38+
3839
</Col>
3940
</Row>
4041

@@ -45,13 +46,13 @@ Every request method returns a `TestResponse` with the following properties:
4546
<Row>
4647
<Col>
4748

48-
| Property | Type | Description |
49-
| --- | --- | --- |
50-
| `status_code` | `int` | HTTP status code |
51-
| `text` | `str` | Response body as a decoded string |
52-
| `content` | `bytes` | Raw response body |
53-
| `headers` | `Headers` | Response headers |
54-
| `ok` | `bool` | `True` if status is 2xx |
49+
| Property | Type | Description |
50+
| ------------- | --------- | --------------------------------- |
51+
| `status_code` | `int` | HTTP status code |
52+
| `text` | `str` | Response body as a decoded string |
53+
| `content` | `bytes` | Raw response body |
54+
| `headers` | `Headers` | Response headers |
55+
| `ok` | `bool` | `True` if status is 2xx |
5556

5657
`TestResponse` also has a `.json()` method that parses the body as JSON.
5758

@@ -73,6 +74,7 @@ Every request method returns a `TestResponse` with the following properties:
7374
assert data[0]["name"] == "Batman"
7475
```
7576
</CodeGroup>
77+
7678
</Col>
7779
</Row>
7880

@@ -100,6 +102,7 @@ Use `json_data` to send JSON payloads — the client automatically sets `Content
100102
assert response.json()["name"] == "Batarang"
101103
```
102104
</CodeGroup>
105+
103106
</Col>
104107
</Row>
105108

@@ -122,10 +125,10 @@ You can also send raw string or bytes bodies, custom headers, query parameters,
122125
assert response.ok
123126
```
124127
</CodeGroup>
128+
125129
</Col>
126130
</Row>
127131

128-
129132
### Path Parameters
130133

131134
Routes with path parameters work exactly as they do in production. The `TestClient` matches the route pattern and extracts parameters automatically.
@@ -148,10 +151,10 @@ Path parameters are resolved from the URL and passed to your handler through the
148151
assert response.json()["user_id"] == 42
149152
```
150153
</CodeGroup>
154+
151155
</Col>
152156
</Row>
153157

154-
155158
### Testing Middleware
156159

157160
The `TestClient` replicates the full request pipeline — before middlewares, the handler, global response headers, and after middlewares — in the same order as the Rust runtime.
@@ -185,10 +188,10 @@ Middlewares that modify the request or response are executed just like in produc
185188
assert response.headers.get("X-Server") == "Robyn"
186189
```
187190
</CodeGroup>
191+
188192
</Col>
189193
</Row>
190194

191-
192195
### Using as a Context Manager
193196

194197
`TestClient` implements the context manager protocol. When used with `with`, the internal event loop is automatically cleaned up:
@@ -208,10 +211,10 @@ Middlewares that modify the request or response are executed just like in produc
208211
# event loop is closed here
209212
```
210213
</CodeGroup>
214+
211215
</Col>
212216
</Row>
213217

214-
215218
### Running Tests with pytest
216219

217220
Since `TestClient` doesn't start a server, tests run as fast as regular unit tests. Use `pytest` directly — no special plugins or fixtures required.
@@ -262,6 +265,7 @@ A typical test file:
262265
assert response.status_code == 404
263266
```
264267
</CodeGroup>
268+
265269
</Col>
266270
</Row>
267271

@@ -271,25 +275,24 @@ Run with:
271275
pytest test_app.py -v
272276
```
273277

274-
275278
### Available Methods
276279

277-
| Method | Signature |
278-
| --- | --- |
279-
| `client.get(path, **kw)` | GET request |
280-
| `client.post(path, json_data=None, **kw)` | POST request |
281-
| `client.put(path, json_data=None, **kw)` | PUT request |
282-
| `client.patch(path, json_data=None, **kw)` | PATCH request |
283-
| `client.delete(path, json_data=None, **kw)` | DELETE request |
284-
| `client.head(path, **kw)` | HEAD request |
285-
| `client.options(path, **kw)` | OPTIONS request |
280+
| Method | Signature |
281+
| ------------------------------------------- | --------------- |
282+
| `client.get(path, **kw)` | GET request |
283+
| `client.post(path, json_data=None, **kw)` | POST request |
284+
| `client.put(path, json_data=None, **kw)` | PUT request |
285+
| `client.patch(path, json_data=None, **kw)` | PATCH request |
286+
| `client.delete(path, json_data=None, **kw)` | DELETE request |
287+
| `client.head(path, **kw)` | HEAD request |
288+
| `client.options(path, **kw)` | OPTIONS request |
286289

287290
All methods accept these keyword arguments:
288291

289-
| Argument | Type | Description |
290-
| --- | --- | --- |
291-
| `body` | `str \| bytes` | Raw request body |
292-
| `headers` | `dict` | Request headers |
293-
| `query_params` | `dict` | Query string parameters |
294-
| `form_data` | `dict` | Form data fields |
295-
| `files` | `dict` | File uploads (name → bytes) |
292+
| Argument | Type | Description |
293+
| -------------- | -------------- | --------------------------- |
294+
| `body` | `str \| bytes` | Raw request body |
295+
| `headers` | `dict` | Request headers |
296+
| `query_params` | `dict` | Query string parameters |
297+
| `form_data` | `dict` | Form data fields |
298+
| `files` | `dict` | File uploads (name → bytes) |

docs_src/src/pages/documentation/en/plugins.mdx

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
export const description =
2+
'Robyn plugins, including rate limiting and robyn-config for project scaffolding, admin panels, and observability.'
3+
4+
export const sections = [
5+
{ title: 'Rate Limit Plugin', id: 'rate-limit-plugin' },
6+
{ title: 'Robyn Config', id: 'robyn-config' },
7+
]
8+
19
## Plugins
210

311
Robyn is a versatile and extensible web framework that allows anyone to make plugins over the top of Robyn.
@@ -34,6 +42,164 @@ In this example, robyn-rate-limits is used to enforce a rate limit of 3 requests
3442

3543
The plugin integrates seamlessly with the Robyn web framework, enhancing the security and stability of your application by preventing excessive requests from a single client.
3644

45+
### Robyn Config
46+
47+
- Description: A CLI companion for bootstrapping and maintaining production-ready Robyn applications. It can create new projects, add business entities, scaffold an admin panel, and wire an observability stack into an existing app.
48+
- GitHub repository: [robyn-config](https://github.com/Lehsqa/robyn-config)
49+
- Installation:
50+
`python -m pip install robyn-config`
51+
52+
Or as a Robyn optional dependency:
53+
`python -m pip install robyn[robyn-config]`
54+
55+
- Python support: Python 3.11 or newer.
56+
57+
#### Create a Project
58+
59+
```bash
60+
# DDD + SQLAlchemy with uv dependency locking (default)
61+
robyn-config create my-service --design ddd --orm sqlalchemy ./my-service
62+
63+
# MVC + Tortoise ORM with poetry dependency locking
64+
robyn-config create newsletter --design mvc --orm tortoise --package-manager poetry ./newsletter
65+
66+
# Interactive project setup
67+
robyn-config create -i
68+
```
69+
70+
`robyn-config create` gives you explicit choices for the two main architecture branches:
71+
72+
- **DDD** for domain, application, infrastructure, and presentation layers.
73+
- **MVC** for views, repositories, models, and URL routing.
74+
75+
It also lets you choose the database layer and package manager:
76+
77+
- **SQLAlchemy** or **Tortoise ORM** for persistence.
78+
- **uv** by default, or **poetry** with `--package-manager poetry`.
79+
80+
#### Add Business Logic
81+
82+
Inside a generated project, add a new entity and let `robyn-config` place the files in the correct design-specific layers:
83+
84+
```bash
85+
cd my-service
86+
robyn-config add product
87+
```
88+
89+
This generates the model, repository, route/controller code, and application wiring for the selected architecture. Custom generation paths can be configured in `[tool.robyn-config.add]` inside the generated project's `pyproject.toml`.
90+
91+
#### Add an Admin Panel
92+
93+
```bash
94+
cd my-service
95+
robyn-config adminpanel
96+
97+
# Override the default admin/admin bootstrap credentials
98+
robyn-config adminpanel --username superadmin --password super-secret-password ./my-service
99+
```
100+
101+
The admin panel scaffolding adds an ORM-aware admin module, registers it with the application, discovers available project models, and exposes CRUD views for those models.
102+
103+
<div className="not-prose my-8 grid gap-4 md:grid-cols-2">
104+
<figure className="overflow-hidden rounded-lg border border-white/10 bg-zinc-950">
105+
<img
106+
src="/images/robyn-config/admin/login.png"
107+
alt="Robyn Config admin login screen"
108+
className="w-full"
109+
/>
110+
<figcaption className="px-4 py-3 text-sm text-zinc-400">
111+
Admin login
112+
</figcaption>
113+
</figure>
114+
<figure className="overflow-hidden rounded-lg border border-white/10 bg-zinc-950">
115+
<img
116+
src="/images/robyn-config/admin/home.png"
117+
alt="Robyn Config admin home dashboard"
118+
className="w-full"
119+
/>
120+
<figcaption className="px-4 py-3 text-sm text-zinc-400">
121+
Admin dashboard
122+
</figcaption>
123+
</figure>
124+
<figure className="overflow-hidden rounded-lg border border-white/10 bg-zinc-950">
125+
<img
126+
src="/images/robyn-config/admin/model_list.png"
127+
alt="Robyn Config admin model table"
128+
className="w-full"
129+
/>
130+
<figcaption className="px-4 py-3 text-sm text-zinc-400">
131+
Model listing
132+
</figcaption>
133+
</figure>
134+
<figure className="overflow-hidden rounded-lg border border-white/10 bg-zinc-950">
135+
<img
136+
src="/images/robyn-config/admin/model_edit.png"
137+
alt="Robyn Config admin model editor"
138+
className="w-full"
139+
/>
140+
<figcaption className="px-4 py-3 text-sm text-zinc-400">
141+
Model editor
142+
</figcaption>
143+
</figure>
144+
</div>
145+
146+
#### Add Monitoring
147+
148+
```bash
149+
cd my-service
150+
robyn-config monitoring
151+
152+
# Start the application stack and observability stack
153+
docker compose up -d
154+
docker compose -f docker-compose.monitoring.yml up -d
155+
```
156+
157+
The monitoring command adds a `/metrics` endpoint, installs `prometheus-client`, and provisions Docker Compose assets for Grafana Alloy, Loki, Prometheus, and Grafana. Grafana is available at `http://localhost:3000` with dashboards for logs and process metrics.
158+
159+
<div className="not-prose my-8 grid gap-4 md:grid-cols-2">
160+
<figure className="overflow-hidden rounded-lg border border-white/10 bg-zinc-950">
161+
<img
162+
src="/images/robyn-config/monitoring/logs.png"
163+
alt="Robyn Config Grafana logs dashboard"
164+
className="w-full"
165+
/>
166+
<figcaption className="px-4 py-3 text-sm text-zinc-400">
167+
Logs dashboard
168+
</figcaption>
169+
</figure>
170+
<figure className="overflow-hidden rounded-lg border border-white/10 bg-zinc-950">
171+
<img
172+
src="/images/robyn-config/monitoring/metrics.png"
173+
alt="Robyn Config Grafana metrics dashboard"
174+
className="w-full"
175+
/>
176+
<figcaption className="px-4 py-3 text-sm text-zinc-400">
177+
Metrics dashboard
178+
</figcaption>
179+
</figure>
180+
</div>
181+
182+
#### Validate Generated Projects
183+
184+
After generating or modifying a project, run the checks that match the generated package manager:
185+
186+
```bash
187+
# uv projects
188+
uv run pytest
189+
uv run ruff check .
190+
191+
# poetry projects
192+
poetry run pytest
193+
poetry run ruff check .
194+
```
195+
196+
For monitoring, confirm the application exposes Prometheus metrics and that Grafana has data:
197+
198+
```bash
199+
curl http://localhost:8000/metrics
200+
curl -I http://localhost:3000
201+
```
202+
37203
## What's next?
38204

39205
After exploring the plugins, Batman wanted to explore the community.So, Robyn pointed him to

0 commit comments

Comments
 (0)