Skip to content

Commit 9f98e53

Browse files
committed
docs: add comprehensive plugin creation guide (#686)
Made-with: Cursor
1 parent 9e1fd74 commit 9f98e53

2 files changed

Lines changed: 155 additions & 12 deletions

File tree

docs_src/src/components/documentation/Navigation.jsx

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,10 @@ export const navigation = [
232232
href: '/documentation/en/api_reference/getting_started',
233233
title: 'Getting Started',
234234
},
235+
{
236+
href: '/documentation/en/api_reference/response-objects',
237+
title: 'Response Objects',
238+
},
235239
{
236240
href: '/documentation/en/api_reference/request_object',
237241
title: 'The Request Object',
@@ -393,6 +397,10 @@ export const navigation = [
393397
href: '/documentation/en/plugins',
394398
title: 'Plugins',
395399
},
400+
{
401+
href: '/documentation/en/plugins#creating-your-own-plugin',
402+
title: 'Creating Plugins',
403+
},
396404
],
397405
},
398406
{
@@ -448,6 +456,7 @@ const translations = {
448456
Templates: 'Templates',
449457
SubRouters: 'SubRouters',
450458
Installation: 'Installation',
459+
'Response Objects': 'Response Objects',
451460
'The Request Object': 'The Request Object',
452461
'The Robyn Env file': 'The Robyn Env file',
453462
'Middlewares, Events and Websockets':
@@ -480,6 +489,7 @@ const translations = {
480489
'Upcoming Features': 'Upcoming Features',
481490
Railway: 'Railway',
482491
'Exposing Ports': 'Exposing Ports',
492+
'Creating Plugins': 'Creating Plugins',
483493
},
484494
},
485495
zh: {
@@ -496,6 +506,7 @@ const translations = {
496506
Templates: '模板',
497507
SubRouters: '子路由',
498508
Installation: '安装',
509+
'Response Objects': '响应对象',
499510
'The Request Object': '请求对象',
500511
'The Robyn Env file': 'Robyn 环境文件',
501512
'Middlewares, Events and Websockets': '中间件、事件和 WebSocket',
@@ -526,7 +537,8 @@ const translations = {
526537
'Introduction': '引入',
527538
'Upcoming Features': '即将推出的功能',
528539
'Railway': 'Railway',
529-
'Exposing Ports': '开放端口'
540+
'Exposing Ports': '开放端口',
541+
'Creating Plugins': '创建插件'
530542
}
531543
}
532544
}

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

Lines changed: 142 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
1+
export const description =
2+
'Learn how to use existing Robyn plugins and create your own to extend the framework.'
3+
14
## Plugins
25

3-
Robyn is a versatile and extensible web framework that allows anyone to make plugins over the top of Robyn.
4-
Plugins in Robyn allow you to enhance and customize the framework's functionality to suit your specific needs. Here are some noteworthy plugins that can supercharge your Robyn-based projects:
6+
Robyn is a versatile and extensible web framework that allows anyone to build plugins on top of Robyn.
7+
Plugins in Robyn are standard Python packages that use Robyn's public APIs — there is no special plugin runtime or registry. You build them using the same tools you use to build Robyn applications: routes, middleware, SubRouters, dependency injection, and lifecycle events.
8+
9+
## Community Plugins
510

611
### Rate Limit Plugin
712

8-
- Description: This plugin enables you to implement rate limiting for your Robyn application's routes. It helps prevent abuse, and brute-force attacks and ensures fair usage of your resources.
9-
- GitHub repository: [robyn-rate-limits](https://github.com/IdoKendo/robyn_rate_limits)
10-
- Installation:
11-
`python -m pip install robyn-rate-limits`
12-
- Usage:
13+
- **Description**: Enables rate limiting for your Robyn application's routes to prevent abuse and brute-force attacks.
14+
- **GitHub**: [robyn-rate-limits](https://github.com/IdoKendo/robyn_rate_limits)
15+
- **Installation**: `pip install robyn-rate-limits`
1316

1417
```py
1518
from robyn import Robyn, Request
@@ -30,12 +33,140 @@ def h():
3033
app.start(port=8080)
3134
```
3235

33-
In this example, robyn-rate-limits is used to enforce a rate limit of 3 requests per 100-seconds window for specific routes. If a client exceeds this limit, they will receive a "Too many requests" message.
36+
---
3437

35-
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.
38+
## Creating Your Own Plugin
3639

37-
## What's next?
40+
A Robyn plugin is a regular Python package that depends on `robyn` and uses its public API. There is no special base class or registration mechanism — any pattern that works in a Robyn app works in a plugin.
41+
42+
### Plugin Patterns
43+
44+
There are several common patterns for building plugins:
45+
46+
#### 1. Middleware-Based Plugins
47+
48+
Middleware plugins hook into `before_request` or `after_request` to process every request. This is ideal for cross-cutting concerns like logging, authentication, or rate limiting.
49+
50+
```py
51+
from robyn import Request, Response, Headers
52+
53+
class RequestLogger:
54+
"""A plugin that logs all incoming requests."""
55+
56+
def __init__(self, log_headers: bool = False):
57+
self.log_headers = log_headers
58+
59+
def handle(self, request: Request):
60+
print(f"[{request.method}] {request.url.path}")
61+
if self.log_headers:
62+
print(f" Headers: {request.headers}")
63+
64+
# Usage in an app:
65+
# logger = RequestLogger(log_headers=True)
66+
# @app.before_request()
67+
# def log_request(request: Request):
68+
# logger.handle(request)
69+
```
70+
71+
#### 2. SubRouter-Based Plugins
72+
73+
SubRouter plugins bundle a set of routes that can be included in any Robyn app via `app.include_router()`. This is ideal for reusable API modules like health checks, admin panels, or metrics endpoints.
74+
75+
```py
76+
from robyn import SubRouter, Request
77+
78+
def create_health_router(prefix: str = "/health") -> SubRouter:
79+
"""A plugin that adds health check endpoints."""
80+
router = SubRouter(__name__, prefix=prefix)
81+
82+
@router.get("/")
83+
def health_check():
84+
return {"status": "healthy"}
85+
86+
@router.get("/ready")
87+
def readiness_check():
88+
return {"ready": True}
89+
90+
return router
91+
92+
# Usage in an app:
93+
# from my_plugin import create_health_router
94+
# app.include_router(create_health_router())
95+
```
96+
97+
#### 3. Lifecycle Plugins
3898

39-
After exploring the plugins, Batman wanted to explore the community.So, Robyn pointed him to
99+
Plugins can hook into application startup and shutdown events for initialization and cleanup tasks like database connections or background workers.
100+
101+
```py
102+
from robyn import Robyn
103+
104+
def register_db_plugin(app: Robyn, connection_string: str):
105+
"""A plugin that manages a database connection pool."""
106+
107+
@app.startup_handler
108+
async def init_db():
109+
app.state["db"] = await create_pool(connection_string)
110+
print("Database pool initialized")
111+
112+
@app.shutdown_handler
113+
async def close_db():
114+
await app.state["db"].close()
115+
print("Database pool closed")
116+
```
117+
118+
### Package Structure
119+
120+
A typical Robyn plugin package looks like this:
121+
122+
```
123+
robyn-my-plugin/
124+
├── pyproject.toml
125+
├── README.md
126+
├── src/
127+
│ └── robyn_my_plugin/
128+
│ ├── __init__.py
129+
│ └── core.py
130+
└── tests/
131+
└── test_plugin.py
132+
```
133+
134+
Your `pyproject.toml` should declare `robyn` as a dependency:
135+
136+
```toml
137+
[project]
138+
name = "robyn-my-plugin"
139+
version = "0.1.0"
140+
dependencies = ["robyn>=0.80.0"]
141+
```
142+
143+
### Naming Conventions
144+
145+
To make your plugin discoverable, we recommend:
146+
- Package name: `robyn-<plugin-name>` (e.g., `robyn-rate-limits`, `robyn-cors-helper`)
147+
- Import name: `robyn_<plugin_name>` (e.g., `robyn_rate_limits`)
148+
149+
### Testing Your Plugin
150+
151+
Test your plugin by creating a minimal Robyn app in your test suite:
152+
153+
```py
154+
import pytest
155+
from robyn import Robyn
156+
from robyn_my_plugin import create_health_router
157+
158+
@pytest.fixture
159+
def app():
160+
app = Robyn(__name__)
161+
app.include_router(create_health_router())
162+
return app
163+
164+
def test_health_endpoint(app):
165+
# Use Robyn's test client or integration test patterns
166+
pass
167+
```
168+
169+
## What's next?
40170

171+
- [Community Resources](/documentation/en/community-resources)
41172
- [Future Roadmap](/documentation/en/api_reference/future-roadmap)

0 commit comments

Comments
 (0)