Skip to content

Commit 59dcff2

Browse files
committed
update docs
1 parent b297934 commit 59dcff2

File tree

2 files changed

+188
-63
lines changed

2 files changed

+188
-63
lines changed

docs_src/src/pages/documentation/api_reference/streaming.mdx

+77-30
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,20 @@
11
export const description =
2-
'On this page, we’ll dive into the different conversation endpoints you can use to manage conversations programmatically.'
2+
'Learn how to use streaming responses in Robyn for real-time data, large files, and server-sent events.'
33

4-
5-
6-
## Coming From
7-
8-
If you're coming from [File Handling](/documentation/api_reference/file_handling), you'll find streaming provides a more efficient way to handle large files.
9-
10-
## Streaming Responses
4+
## Overview
115

126
Like Batman's gadgets streaming from the Batcave to his utility belt, Robyn provides built-in support for streaming responses. This allows you to send data in chunks, perfect for large files, real-time updates, and server-sent events.
137

14-
Streaming responses are perfect for handling large datasets or real-time updates without consuming excessive memory.
8+
## Creating Streaming Responses
159

16-
## Response
10+
There are two ways to create streaming responses in Robyn:
1711

18-
When the Bat-Signal needs to stream continuously through the night sky, you'll want to use a generator or iterator as the `description` parameter:
12+
### 1. Using the streaming parameter
1913

2014
<Row>
2115
<CodeGroup title="Server">
2216
```python
23-
from robyn import Response
24-
25-
@app.get("/bat-signal")
17+
@app.get("/bat-signal", streaming=True)
2618
async def stream_signal():
2719
async def signal_generator():
2820
while True:
@@ -44,13 +36,46 @@ When the Bat-Signal needs to stream continuously through the night sky, you'll w
4436
</CodeGroup>
4537
</Row>
4638

39+
### 2. Returning an Iterator/Generator
40+
41+
Robyn automatically detects iterators and generators and treats them as streaming responses:
42+
43+
<Row>
44+
<CodeGroup title="Server">
45+
```python
46+
@app.get("/bat-signal")
47+
async def stream_signal():
48+
async def signal_generator():
49+
while True:
50+
yield b"Bat-Signal Active\n"
51+
await asyncio.sleep(1)
52+
53+
return signal_generator() # Automatically detected as streaming
54+
```
55+
</CodeGroup>
56+
</Row>
57+
58+
## Response Object
59+
60+
The Response class supports streaming through its constructor parameters:
61+
62+
```python
63+
Response(
64+
status_code=200,
65+
headers={"Content-Type": "text/plain"},
66+
description=generator(), # Can be str, bytes, or iterator/generator
67+
streaming=True # Optional, automatically set for iterators/generators
68+
)
69+
```
70+
4771
### Parameters
4872

4973
| Name | Type | Description | Default |
5074
|------|------|-------------|---------|
5175
| status_code | int | Response status code | 200 |
5276
| headers | Dict[str, str] | Response headers | None |
53-
| description | Union[str, bytes, Generator, AsyncGenerator] | Content to stream | None |
77+
| description | Union[str, bytes, Iterator, AsyncIterator] | Content to stream | None |
78+
| streaming | bool | Whether to treat as streaming response | False |
5479

5580
### Supported Types
5681

@@ -60,25 +85,29 @@ Like Batman's versatile arsenal, the streaming response system supports multiple
6085
<CodeGroup title="Binary">
6186
```python
6287
# Raw binary data (like Batcomputer logs)
63-
yield b"Batcomputer Log Entry\n"
88+
async def generator():
89+
yield b"Batcomputer Log Entry\n"
6490
```
6591
</CodeGroup>
6692
<CodeGroup title="Text">
6793
```python
6894
# Text messages (like Alfred's updates)
69-
yield "Master Wayne, your tea is ready\n".encode()
95+
async def generator():
96+
yield "Master Wayne, your tea is ready\n".encode()
7097
```
7198
</CodeGroup>
7299
<CodeGroup title="Numbers">
73100
```python
74101
# Numbers (like Batmobile telemetry)
75-
yield str(speed).encode()
102+
async def generator():
103+
yield str(speed).encode()
76104
```
77105
</CodeGroup>
78106
<CodeGroup title="JSON">
79107
```python
80108
# JSON data (like Gotham City surveillance)
81-
yield json.dumps({"location": "Crime Alley"}).encode()
109+
async def generator():
110+
yield json.dumps({"location": "Crime Alley"}).encode()
82111
```
83112
</CodeGroup>
84113
</Row>
@@ -90,7 +119,7 @@ For real-time updates from the Batcomputer:
90119
<Row>
91120
<CodeGroup title="Server">
92121
```python
93-
@app.get("/batcomputer/events")
122+
@app.get("/batcomputer/events", streaming=True)
94123
async def batcomputer_feed():
95124
async def event_generator():
96125
while True:
@@ -129,7 +158,7 @@ For streaming large files from the Batcomputer archives:
129158
<Row>
130159
<CodeGroup title="Server">
131160
```python
132-
@app.get("/batcomputer/files")
161+
@app.get("/batcomputer/files", streaming=True)
133162
async def download_files():
134163
async def file_generator():
135164
chunk_size = 8192 # Size of a Batarang
@@ -154,6 +183,25 @@ For streaming large files from the Batcomputer archives:
154183
</CodeGroup>
155184
</Row>
156185

186+
## Helper Functions
187+
188+
Robyn provides helper functions for common streaming scenarios:
189+
190+
```python
191+
from robyn import html
192+
193+
@app.get("/bat-report", streaming=True)
194+
async def stream_html():
195+
async def generator():
196+
yield "<html><body>"
197+
for i in range(5):
198+
yield f"<p>Bat-Signal sighting {i}</p>"
199+
await asyncio.sleep(0.1)
200+
yield "</body></html>"
201+
202+
return html(generator(), streaming=True)
203+
```
204+
157205
## Common Headers
158206

159207
### Plain Text
@@ -182,8 +230,6 @@ headers = {
182230

183231
Even Batman needs contingency plans:
184232

185-
Always handle errors gracefully in your streaming responses to prevent connection hangs.
186-
187233
```python
188234
async def generator():
189235
try:
@@ -201,12 +247,12 @@ Test your streaming responses like Batman testing his equipment:
201247
```python
202248
@pytest.mark.asyncio
203249
async def test_bat_signal():
204-
async with app.test_client() as client:
205-
response = await client.get("/bat-signal")
206-
signals = []
207-
async for signal in response.content:
208-
signals.append(signal)
209-
assert len(signals) > 0
250+
async with aiohttp.ClientSession() as client:
251+
async with client.get("http://localhost:8080/bat-signal") as response:
252+
chunks = []
253+
async for chunk in response.content:
254+
chunks.append(chunk.decode())
255+
assert len(chunks) > 0
210256
```
211257

212258
## Best Practices
@@ -231,5 +277,6 @@ Implement timeouts (even Batman needs sleep)
231277
Now that you've mastered streaming, you might want to explore:
232278

233279
- [WebSockets](/documentation/api_reference/websockets) - For real-time bidirectional communication
234-
- [Scaling](/documentation/api_reference/scaling) - Scale your streaming applications across multiple cores
280+
- [File Handling](/documentation/api_reference/file_handling) - For more file operations
281+
- [Middleware](/documentation/api_reference/middleware) - For request/response processing
235282

0 commit comments

Comments
 (0)