Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion docs_src/src/components/documentation/Navigation.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,10 @@ export const navigation = [
href: '/documentation/en/api_reference/getting_started',
title: 'Getting Started',
},
{
href: '/documentation/en/api_reference/response-objects',
title: 'Response Objects',
},
Comment on lines +235 to +238
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check if the Response Objects page exists for both languages

echo "=== English Response Objects page ==="
fd 'response-objects\.mdx$' docs_src/src/pages/documentation/en --type f || echo "Not found in en/"

echo ""
echo "=== Chinese Response Objects page ==="
fd 'response-objects\.mdx$' docs_src/src/pages/documentation/zh --type f || echo "Not found in zh/"

echo ""
echo "=== All response-objects files ==="
fd 'response-objects' docs_src/src/pages/documentation --type f

Repository: sparckles/Robyn

Length of output: 171


🏁 Script executed:

# Check the documentation directory structure to understand how pages are organized
echo "=== Documentation directory structure ==="
find docs_src/src/pages/documentation -type d | head -20

echo ""
echo "=== Check for api_reference directory ==="
fd 'api_reference' docs_src/src/pages/documentation --type d

echo ""
echo "=== All files in api_reference if it exists ==="
find docs_src/src/pages/documentation -name 'api_reference' -type d -exec find {} -type f \;

echo ""
echo "=== Check for any response-related files ==="
rg -l 'response' docs_src/src/pages/documentation --type mdx | head -20

Repository: sparckles/Robyn

Length of output: 4630


🏁 Script executed:

# Search for any response-objects references in the entire codebase
echo "=== Search for response-objects references ==="
rg 'response-objects' docs_src --type-list | grep -i mdx

echo ""
echo "=== Search for response-objects in all file types ==="
rg -l 'response-objects' docs_src

echo ""
echo "=== Check if response-objects.mdx exists anywhere ==="
find docs_src -name '*response*objects*' -o -name '*response-object*'

echo ""
echo "=== Check the git status to see added/modified files ==="
git status --short | grep -i response || echo "No response files in git status"

Repository: sparckles/Robyn

Length of output: 765


🏁 Script executed:

# Check the Navigation.jsx file to see the context of the response-objects link
echo "=== Navigation.jsx around lines 235-238 ==="
sed -n '230,245p' docs_src/src/components/documentation/Navigation.jsx

echo ""
echo "=== Check if there are any other response-objects references ==="
grep -n 'response-objects' docs_src/src/components/documentation/Navigation.jsx

Repository: sparckles/Robyn

Length of output: 703


Create the Response Objects documentation page before adding the navigation link.

The navigation entry at line 236 links to /documentation/en/api_reference/response-objects, but this page does not exist in the codebase. The getLocalizedHref() function will convert this to /documentation/zh/api_reference/response-objects for Chinese users, but neither version exists. Users will encounter 404 errors when clicking this link. Either create the documentation file or remove the navigation entry.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs_src/src/components/documentation/Navigation.jsx` around lines 235 - 238,
The navigation array in Navigation.jsx contains an entry with href
'/documentation/en/api_reference/response-objects' which points to a
non-existent page; either remove that object from the navigation list (the
object with title 'Response Objects' and href
'/documentation/en/api_reference/response-objects') or create the missing
documentation page(s) (add a response-objects page under the docs content for
English and its localized counterpart so getLocalizedHref() resolves correctly);
ensure the new page path matches the href exactly and include it in the docs
build so clicking the link does not 404.

{
href: '/documentation/en/api_reference/request_object',
title: 'The Request Object',
Expand Down Expand Up @@ -393,6 +397,10 @@ export const navigation = [
href: '/documentation/en/plugins',
title: 'Plugins',
},
{
href: '/documentation/en/plugins#creating-your-own-plugin',
title: 'Creating Plugins',
},
],
},
{
Expand Down Expand Up @@ -448,6 +456,7 @@ const translations = {
Templates: 'Templates',
SubRouters: 'SubRouters',
Installation: 'Installation',
'Response Objects': 'Response Objects',
'The Request Object': 'The Request Object',
'The Robyn Env file': 'The Robyn Env file',
'Middlewares, Events and Websockets':
Expand Down Expand Up @@ -480,6 +489,7 @@ const translations = {
'Upcoming Features': 'Upcoming Features',
Railway: 'Railway',
'Exposing Ports': 'Exposing Ports',
'Creating Plugins': 'Creating Plugins',
},
},
zh: {
Expand All @@ -496,6 +506,7 @@ const translations = {
Templates: '模板',
SubRouters: '子路由',
Installation: '安装',
'Response Objects': '响应对象',
'The Request Object': '请求对象',
'The Robyn Env file': 'Robyn 环境文件',
'Middlewares, Events and Websockets': '中间件、事件和 WebSocket',
Expand Down Expand Up @@ -526,7 +537,8 @@ const translations = {
'Introduction': '引入',
'Upcoming Features': '即将推出的功能',
'Railway': 'Railway',
'Exposing Ports': '开放端口'
'Exposing Ports': '开放端口',
'Creating Plugins': '创建插件'
}
}
}
Expand Down
153 changes: 142 additions & 11 deletions docs_src/src/pages/documentation/en/plugins.mdx
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
export const description =
'Learn how to use existing Robyn plugins and create your own to extend the framework.'

## Plugins

Robyn is a versatile and extensible web framework that allows anyone to make plugins over the top of Robyn.
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:
Robyn is a versatile and extensible web framework that allows anyone to build plugins on top of Robyn.
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.

## Community Plugins

### Rate Limit Plugin

- 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.
- GitHub repository: [robyn-rate-limits](https://github.com/IdoKendo/robyn_rate_limits)
- Installation:
`python -m pip install robyn-rate-limits`
- Usage:
- **Description**: Enables rate limiting for your Robyn application's routes to prevent abuse and brute-force attacks.
- **GitHub**: [robyn-rate-limits](https://github.com/IdoKendo/robyn_rate_limits)
- **Installation**: `pip install robyn-rate-limits`

```py
from robyn import Robyn, Request
Expand All @@ -30,12 +33,140 @@ def h():
app.start(port=8080)
```

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.
---

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.
## Creating Your Own Plugin

## What's next?
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.

### Plugin Patterns

There are several common patterns for building plugins:

#### 1. Middleware-Based Plugins

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.

```py
from robyn import Request, Response, Headers

class RequestLogger:
"""A plugin that logs all incoming requests."""

def __init__(self, log_headers: bool = False):
self.log_headers = log_headers

def handle(self, request: Request):
print(f"[{request.method}] {request.url.path}")
if self.log_headers:
print(f" Headers: {request.headers}")

# Usage in an app:
# logger = RequestLogger(log_headers=True)
# @app.before_request()
# def log_request(request: Request):
# logger.handle(request)
```

#### 2. SubRouter-Based Plugins

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.

```py
from robyn import SubRouter, Request

def create_health_router(prefix: str = "/health") -> SubRouter:
"""A plugin that adds health check endpoints."""
router = SubRouter(__name__, prefix=prefix)

@router.get("/")
def health_check():
return {"status": "healthy"}

@router.get("/ready")
def readiness_check():
return {"ready": True}

return router

# Usage in an app:
# from my_plugin import create_health_router
# app.include_router(create_health_router())
```

#### 3. Lifecycle Plugins

After exploring the plugins, Batman wanted to explore the community.So, Robyn pointed him to
Plugins can hook into application startup and shutdown events for initialization and cleanup tasks like database connections or background workers.

```py
from robyn import Robyn

def register_db_plugin(app: Robyn, connection_string: str):
"""A plugin that manages a database connection pool."""

@app.startup_handler
async def init_db():
app.state["db"] = await create_pool(connection_string)
print("Database pool initialized")

@app.shutdown_handler
async def close_db():
await app.state["db"].close()
print("Database pool closed")
```

### Package Structure

A typical Robyn plugin package looks like this:

```
robyn-my-plugin/
├── pyproject.toml
├── README.md
├── src/
│ └── robyn_my_plugin/
│ ├── __init__.py
│ └── core.py
└── tests/
└── test_plugin.py
```

Your `pyproject.toml` should declare `robyn` as a dependency:

```toml
[project]
name = "robyn-my-plugin"
version = "0.1.0"
dependencies = ["robyn>=0.80.0"]
```

### Naming Conventions

To make your plugin discoverable, we recommend:
- Package name: `robyn-<plugin-name>` (e.g., `robyn-rate-limits`, `robyn-cors-helper`)
- Import name: `robyn_<plugin_name>` (e.g., `robyn_rate_limits`)

### Testing Your Plugin

Test your plugin by creating a minimal Robyn app in your test suite:

```py
import pytest
from robyn import Robyn
from robyn_my_plugin import create_health_router

@pytest.fixture
def app():
app = Robyn(__name__)
app.include_router(create_health_router())
return app

def test_health_endpoint(app):
# Use Robyn's test client or integration test patterns
pass
```

## What's next?

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