All the latest Robyn releases, right here.

v0.71.2 - fix auth route conflict

What's Changed

  • fix: auth route conflict by @VishnuSanal in https://github.com/sparckles/Robyn/pull/987

Full Changelog: https://github.com/sparckles/Robyn/compare/v0.71.1...v0.71.2

v0.71.1 - make SSE PEP compliant and improve implementation

What's Changed

  • fix: make SSE PEP compliant and improve implementation by @sansyrox in https://github.com/sparckles/Robyn/pull/1202
"""
Server-Sent Events (SSE) Example for Robyn

This example demonstrates how to implement Server-Sent Events using Robyn. SSE allows real-time server-to-client
communication over a single HTTP connection.
"""

import asyncio
import time

from robyn import Robyn, SSEMessage, SSEResponse

app = Robyn(__file__)


@app.get("/events")
def stream_events(request):
    """Basic SSE endpoint that sends a message every second"""

    def event_generator():
        """Generator function that yields SSE-formatted messages"""
        for i in range(10):
            yield SSEMessage(f"Message {i} - {time.strftime('%H:%M:%S')}", id=str(i))
            time.sleep(1)

        # Send a final message
        yield SSEMessage("Stream ended", event="end")

    return SSEResponse(event_generator())


@app.get("/events/json")
def stream_json_events(request):
    """SSE endpoint that sends JSON data"""
    import json

    def json_event_generator():
        """Generator that yields JSON data as SSE"""
        for i in range(5):
            data = {"id": i, "message": f"JSON message {i}", "timestamp": time.time(), "type": "notification"}
            yield SSEMessage(json.dumps(data), event="notification", id=str(i))
            time.sleep(2)

    return SSEResponse(json_event_generator())


@app.get("/events/named")
def stream_named_events(request):
    """SSE endpoint with named events"""

    def named_event_generator():
        """Generator that yields named SSE events"""
        events = [
            ("user_joined", "Alice joined the chat"),
            ("message", "Hello everyone!"),
            ("user_left", "Bob left the chat"),
            ("message", "How is everyone doing?"),
            ("user_joined", "Charlie joined the chat"),
        ]

        for i, (event_type, message) in enumerate(events):
            yield SSEMessage(message, event=event_type, id=str(i))
            time.sleep(1.5)

    return SSEResponse(named_event_generator())


@app.get("/events/async")
async def stream_async_events(request):
    """Async SSE endpoint demonstrating async generators"""

    async def async_event_generator():
        """Async generator for SSE events"""
        for i in range(8):
            # Simulate async work
            await asyncio.sleep(0.5)
            yield SSEMessage(f"Async message {i} - {time.strftime('%H:%M:%S')}", event="async", id=str(i))

    return SSEResponse(async_event_generator())


@app.get("/events/heartbeat")
def stream_heartbeat(request):
    """SSE endpoint that sends heartbeat messages"""

    def heartbeat_generator():
        """Generator that sends heartbeat pings"""
        counter = 0
        while counter < 20:  # Send 20 heartbeats
            yield SSE_Message(f"heartbeat {counter}", event="heartbeat", id=str(counter))
            counter += 1
            time.sleep(0.5)

        yield SSEMessage("heartbeat ended", event="end")

    return SSEResponse(heartbeat_generator())

Full Changelog: https://github.com/sparckles/Robyn/compare/v0.71.0...v0.71.1

v0.71.0 - add support for server sent events

What's Changed

  • feat: add server sent events by @sansyrox in https://github.com/sparckles/Robyn/pull/1200
"""
Server-Sent Events (SSE) Example for Robyn

This example demonstrates how to implement Server-Sent Events using Robyn,
similar to FastAPI's implementation. SSE allows real-time server-to-client
communication over a single HTTP connection.
"""

import asyncio
import time

from robyn import Robyn, SSE_Message, SSE_Response

app = Robyn(__file__)


@app.get("/events")
def stream_events(request):
    """Basic SSE endpoint that sends a message every second"""

    def event_generator():
        """Generator function that yields SSE-formatted messages"""
        for i in range(10):
            yield SSE_Message(f"Message {i} - {time.strftime('%H:%M:%S')}", id=str(i))
            time.sleep(1)

        # Send a final message
        yield SSE_Message("Stream ended", event="end")

    return SSE_Response(event_generator())


@app.get("/events/json")
def stream_json_events(request):
    """SSE endpoint that sends JSON data"""
    import json

    def json_event_generator():
        """Generator that yields JSON data as SSE"""
        for i in range(5):
            data = {"id": i, "message": f"JSON message {i}", "timestamp": time.time(), "type": "notification"}
            yield SSE_Message(json.dumps(data), event="notification", id=str(i))
            time.sleep(2)

    return SSE_Response(json_event_generator())


@app.get("/events/named")
def stream_named_events(request):
    """SSE endpoint with named events"""

    def named_event_generator():
        """Generator that yields named SSE events"""
        events = [
            ("user_joined", "Alice joined the chat"),
            ("message", "Hello everyone!"),
            ("user_left", "Bob left the chat"),
            ("message", "How is everyone doing?"),
            ("user_joined", "Charlie joined the chat"),
        ]

        for i, (event_type, message) in enumerate(events):
            yield SSE_Message(message, event=event_type, id=str(i))
            time.sleep(1.5)

    return SSE_Response(named_event_generator())


@app.get("/events/async")
async def stream_async_events(request):
    """Async SSE endpoint demonstrating async generators"""

    async def async_event_generator():
        """Async generator for SSE events"""
        for i in range(8):
            # Simulate async work
            await asyncio.sleep(0.5)
            yield SSE_Message(f"Async message {i} - {time.strftime('%H:%M:%S')}", event="async", id=str(i))

    return SSE_Response(async_event_generator())


@app.get("/events/heartbeat")
def stream_heartbeat(request):
    """SSE endpoint that sends heartbeat messages"""

    def heartbeat_generator():
        """Generator that sends heartbeat pings"""
        counter = 0
        while counter < 20:  # Send 20 heartbeats
            yield SSE_Message(f"heartbeat {counter}", event="heartbeat", id=str(counter))
            counter += 1
            time.sleep(0.5)

        yield SSE_Message("heartbeat ended", event="end")

    return SSE_Response(heartbeat_generator())

Full Changelog: https://github.com/sparckles/Robyn/compare/v0.70.0...v0.71.0

v0.70.0 - Experimental AI Features (agents and mcp server)

What's Changed

Full write up https://sanskar.wtf/posts/the-future-of-robyn

Experimental AI Features

First web framework with built-in AI agents and memory.

from robyn import Robyn
from robyn.ai import agent, memory

app = Robyn(__file__)

@app.post("/chat")
async def chat(request):
    mem = memory(provider="inmemory", user_id="user")
    ai_agent = agent(runner="simple", memory=mem)

    result = await ai_agent.run(request.json().get("query"))
    return {"response": result["response"]}

MCP Support

Native Model Context Protocol integration.

# MCP Resources
@app.mcp.resource("time://current")
def current_time() -> str:
    return f"Current time: {datetime.now().isoformat()}"


@app.mcp.tool(
    name="echo",
    description="Echo back text",
    input_schema={"type": "object", "properties": {"text": {"type": "string", "description": "Text to echo"}}, "required": ["text"]},
)
def echo_tool(args):
    return args.get("text", "")


# MCP Prompts
@app.mcp.prompt(
    name="explain_code",
    description="Generate code explanation prompt",
    arguments=[
        {"name": "code", "description": "Code to explain", "required": True},
        {"name": "language", "description": "Programming language", "required": False},
    ],
)
def explain_code_prompt(args):
    code = args.get("code", "")
    language = args.get("language", "unknown")

    return f"""Please explain this {language} code:

{language}
{code}
Include:
1. What it does
2. How it works
3. Key concepts used
"""

Note

These features are very much experimental. Checkout the examples/ folder to see the new features in action.

Install: pip install robyn==0.70.0

Full Changelog: https://github.com/sparckles/Robyn/compare/v0.69.0...v0.70.0

v0.69.0 - make robyn ~80% faster

What's Changed

  • chore: optimize rust code by @sansyrox in https://github.com/sparckles/Robyn/pull/1178
  • feat: optimize robyn , performance boost by 80% by @sansyrox in https://github.com/sparckles/Robyn/pull/1180
  • feat: optimize robyn by @sansyrox in https://github.com/sparckles/Robyn/pull/1181

Full Changelog: https://github.com/sparckles/Robyn/compare/v0.68.0...v0.69.0

v0.68.0 - add python3.13 support

What's Changed

  • PyO3 Migration from v0.20.* to 0.24.* by @VishnuSanal in https://github.com/sparckles/Robyn/pull/1168
  • fix: robyn builds failing for python v3.13 by @VishnuSanal in https://github.com/sparckles/Robyn/pull/1006

Full Changelog: https://github.com/sparckles/Robyn/compare/v0.67.0...v0.68.0

v0.67.0 - flexible CORS configuration

What's Changed

  • fix #1138 - Add support for generic types such as List[Object] by @yzutyc in https://github.com/sparckles/Robyn/pull/1139
  • ci: fix Codspeed benchmark ci by @k4976 in https://github.com/sparckles/Robyn/pull/1169
  • chore: fix typos by @hasansezertasan in https://github.com/sparckles/Robyn/pull/1166
  • Flexible CORS Configuration Support by @Charlie-BU in https://github.com/sparckles/Robyn/pull/1159

New Contributors

  • @yzutyc made their first contribution in https://github.com/sparckles/Robyn/pull/1139
  • @hasansezertasan made their first contribution in https://github.com/sparckles/Robyn/pull/1166
  • @Charlie-BU made their first contribution in https://github.com/sparckles/Robyn/pull/1159

Full Changelog: https://github.com/sparckles/Robyn/compare/v0.66.2...v0.67.0

v0.66.2

What's Changed

  • add BaseRobyn class by @dave42w in https://github.com/sparckles/Robyn/pull/1100
  • docs: first version of chinese docs by @sansyrox in https://github.com/sparckles/Robyn/pull/1102
  • Reduce imports, minimize variables, and unify code style by @Jonney in https://github.com/sparckles/Robyn/pull/1123
  • dev_server should wait until the subprocess is complete by @Jonney in https://github.com/sparckles/Robyn/pull/1127
  • docs: fix typo in 'organisation' by @erees-embarkvet in https://github.com/sparckles/Robyn/pull/1135
  • fix: Fixed syntax error in mdx file. by @pythonhubdev in https://github.com/sparckles/Robyn/pull/1133
  • fix: fix the docs search by @sansyrox in https://github.com/sparckles/Robyn/pull/1144
  • ci: Fixing artifact conflict issue in ci by @k4976 in https://github.com/sparckles/Robyn/pull/1153
  • ci: Upgrading deprecated actions in workflow by @k4976 in https://github.com/sparckles/Robyn/pull/1156

New Contributors

  • @Jonney made their first contribution in https://github.com/sparckles/Robyn/pull/1123
  • @erees-embarkvet made their first contribution in https://github.com/sparckles/Robyn/pull/1135
  • @pythonhubdev made their first contribution in https://github.com/sparckles/Robyn/pull/1133
  • @k4976 made their first contribution in https://github.com/sparckles/Robyn/pull/1153

Full Changelog: https://github.com/sparckles/Robyn/compare/v0.65.0...v0.66.2

v0.65.0 - BREAKING 🚨 - deprecate views and some other updates

What's Changed

  • docs: fix a typo in the custom exceptions documentation by @sansyrox in https://github.com/sparckles/Robyn/pull/1055
  • add_route refactoring by @dave42w in https://github.com/sparckles/Robyn/pull/1060
  • Add missing function return types (mostly None) to reloader.py by @dave42w in https://github.com/sparckles/Robyn/pull/1058
  • remove redundant else statement in ws.py by @dave42w in https://github.com/sparckles/Robyn/pull/1052
  • chore: temporary kludge to make websocket test past on ci by @dave42w in https://github.com/sparckles/Robyn/pull/1070
  • chore: drop python 3.8 support by @sansyrox in https://github.com/sparckles/Robyn/pull/1079
  • chore: suppress clippy warnings by @sansyrox in https://github.com/sparckles/Robyn/pull/1086
  • fix: correction of "Closed" to "closed" in temporary ws test fix by @dave42w in https://github.com/sparckles/Robyn/pull/1078
  • ci: update macos to 13 by @sansyrox in https://github.com/sparckles/Robyn/pull/1088
  • chore: deprecate views by @sansyrox in https://github.com/sparckles/Robyn/pull/1096
  • refactor: openApi made lazy. by @dave42w in https://github.com/sparckles/Robyn/pull/1066

Full Changelog: https://github.com/sparckles/Robyn/compare/v0.64.2...v0.65.0

v0.64.2 - fix a bug in allow cors and internal refactors

What's Changed

  • Two tiny corrections found by mypy 1.13 by @dave42w in https://github.com/sparckles/Robyn/pull/1032
  • Update pyproject.toml by @dave42w in https://github.com/sparckles/Robyn/pull/1037
  • Update README.md to encourage all tests are run by @dave42w in https://github.com/sparckles/Robyn/pull/1036
  • Router refactor by @dave42w in https://github.com/sparckles/Robyn/pull/1043
  • Feat: integrate uv in the ci pipelines and the docs by @Mr-Sunglasses in https://github.com/sparckles/Robyn/pull/1040
  • Minimal mypy update to openapy.py, adding dict type by @dave42w in https://github.com/sparckles/Robyn/pull/1048
  • Minimum change to SubRouter so get, post etc have same signature as Robyn by @dave42w in https://github.com/sparckles/Robyn/pull/1049
  • fix: allow cors in robyn by @sansyrox in https://github.com/sparckles/Robyn/pull/1057

Full Changelog: https://github.com/sparckles/Robyn/compare/v0.64.1...v0.64.2

v0.64.1 - fix a bug in `--disable-openapi-path`

What's Changed

  • chore: reduce number of mypy warnings by @dave42w in https://github.com/sparckles/Robyn/pull/1023
  • fix: disable openapi path by @sansyrox in https://github.com/sparckles/Robyn/pull/1031

Full Changelog: https://github.com/sparckles/Robyn/compare/v0.64.0...v0.64.1

v0.64.0 - fix a bug in allow cors

What's Changed

  • chore: sync poetry lock by @sansyrox in https://github.com/sparckles/Robyn/pull/1014
  • docs: add better docs for local development by @sansyrox in https://github.com/sparckles/Robyn/pull/1018
  • docs: fix typos in API Reference documentation by @nicdgonzalez in https://github.com/sparckles/Robyn/pull/1015
  • Introducing Robyn Guru on Gurubase.io by @kursataktas in https://github.com/sparckles/Robyn/pull/1016
  • fix: allow cors in robyn by @sansyrox in https://github.com/sparckles/Robyn/pull/1019

New Contributors

  • @nicdgonzalez made their first contribution in https://github.com/sparckles/Robyn/pull/1015
  • @kursataktas made their first contribution in https://github.com/sparckles/Robyn/pull/1016

Full Changelog: https://github.com/sparckles/Robyn/compare/v0.63.0...v0.64.0

v0.63.0 - Introduce automatic OpenAPI docs generation

What's Changed

  • feat: openapi implementation by @VishnuSanal in https://github.com/sparckles/Robyn/pull/890
  • feat: introduce a disable openapi flag by @sansyrox in https://github.com/sparckles/Robyn/pull/929
  • feat: openapi response schema by @VishnuSanal in https://github.com/sparckles/Robyn/pull/932
  • fix: openapi regressions by @sansyrox in https://github.com/sparckles/Robyn/pull/942
  • feat: openapi request bodies by @VishnuSanal in https://github.com/sparckles/Robyn/pull/937
  • feat: openapi response schema by @VishnuSanal in https://github.com/sparckles/Robyn/pull/960
  • refactor: revamp add OpenAPI route by @kigawas in https://github.com/sparckles/Robyn/pull/979
  • feat: openapi config override by @VishnuSanal in https://github.com/sparckles/Robyn/pull/1002
  • feat: finalise openapi by @sansyrox in https://github.com/sparckles/Robyn/pull/1010

Full Changelog: https://github.com/sparckles/Robyn/compare/v0.58.2...v0.63.0

v0.62.0 - fix crashes on ctrl + c

What's Changed

  • fix: crashes on ctrl + c by @sansyrox in https://github.com/sparckles/Robyn/pull/973
  • feat(ci): add isort and black new by @VishnuSanal in https://github.com/sparckles/Robyn/pull/975
  • refactor: revamp add OpenAPI route by @kigawas in https://github.com/sparckles/Robyn/pull/979
  • fix: broken CI -- codspeed-benchmarks by @VishnuSanal in https://github.com/sparckles/Robyn/pull/981

New Contributors

  • @kigawas made their first contribution in https://github.com/sparckles/Robyn/pull/979

Full Changelog: https://github.com/sparckles/Robyn/compare/v0.61.2...v0.62.0

v0.61.2 - fix module params

What's Changed

  • chore: cleanup dead links by @sansyrox in https://github.com/sparckles/Robyn/pull/959
  • docs: fix link advanced features in scaling page by @kayqueGovetri in https://github.com/sparckles/Robyn/pull/971
  • fix: module params by @VishnuSanal in https://github.com/sparckles/Robyn/pull/967

New Contributors

  • @kayqueGovetri made their first contribution in https://github.com/sparckles/Robyn/pull/971

Full Changelog: https://github.com/sparckles/Robyn/compare/v0.61.1...v0.61.2

v0.61.1 - add a close method in websocket connectors

What's Changed

  • docs: add docs regarding extra params by @sansyrox in https://github.com/sparckles/Robyn/pull/944
  • docs: link(ify) the releases in the changelog by @sansyrox in https://github.com/sparckles/Robyn/pull/947
  • test: add tests for cli by @sansyrox in https://github.com/sparckles/Robyn/pull/948
  • feat: add a close method in websockets by @sansyrox in https://github.com/sparckles/Robyn/pull/946

Full Changelog: https://github.com/sparckles/Robyn/compare/v0.60.2...v0.61.1

v0.58.2 - make Robyn faster and fix bug in compile_rust_files

What's Changed

  • build: bump watchdog to 4.0.1 by @haoxins in https://github.com/sparckles/Robyn/pull/913
  • fix: :bug: Fix bug in compile_rust_files where it returns a list of t… by @Kade-Powell in https://github.com/sparckles/Robyn/pull/873
  • docs: fix global var docs behavior in multi-threading by @VishnuSanal in https://github.com/sparckles/Robyn/pull/904
  • feat: replace stdlib RwLock with parking_lot::RwLock by @sansyrox in https://github.com/sparckles/Robyn/pull/924

New Contributors

  • @haoxins made their first contribution in https://github.com/sparckles/Robyn/pull/913
  • @Kade-Powell made their first contribution in https://github.com/sparckles/Robyn/pull/873

Full Changelog: https://github.com/sparckles/Robyn/compare/v0.58.1...v0.58.2

v0.58.1 - fix headers causing panic in invalid value conversion

What's Changed

  • fix: headers causing panic in invalid value to string conversion by @sansyrox in https://github.com/sparckles/Robyn/pull/908
  • ci: update rust dependencies by @sansyrox in https://github.com/sparckles/Robyn/pull/918
  • chore: update pull_request_template.md by @sansyrox in https://github.com/sparckles/Robyn/pull/920

Full Changelog: https://github.com/sparckles/Robyn/compare/v0.58.0...v0.58.1

v0.58.0 - control dev mode with `ROBYN_DEV_MODE` env var

What's Changed

  • docs: fix styling of docs website by @sansyrox in https://github.com/sparckles/Robyn/pull/895
  • feat: control dev mode with env var by @VishnuSanal in https://github.com/sparckles/Robyn/pull/877

Full Changelog: https://github.com/sparckles/Robyn/compare/v0.57.1...v0.58.0

v0.57.1 - fixes bug in binary responses

What's Changed

  • fix: fix response type for json by @yomaaf in https://github.com/sparckles/Robyn/pull/888
  • refactor: PyResponse::new to delegate body type checking to check_body… by @asamaayako in https://github.com/sparckles/Robyn/pull/891
  • docs: fix a typo in the deployment docs by @sansyrox in https://github.com/sparckles/Robyn/pull/893
  • fix: bug Binary type Reponse causes a crash#874 by @asamaayako in https://github.com/sparckles/Robyn/pull/882

New Contributors

  • @yomaaf made their first contribution in https://github.com/sparckles/Robyn/pull/888

Full Changelog: https://github.com/sparckles/Robyn/compare/v0.57.0...v0.57.1

v0.57.0 - add QueryParams to WebSocket interface

What's Changed

  • perf: type check function does not need to take ownership by @asamaayako in https://github.com/sparckles/Robyn/pull/884
  • feat: add QueryParams to WebSocket by @VishnuSanal in https://github.com/sparckles/Robyn/pull/886

New Contributors

  • @asamaayako made their first contribution in https://github.com/sparckles/Robyn/pull/884

Full Changelog: https://github.com/sparckles/Robyn/compare/v0.56.3...v0.57.0

v0.56.3 - implement a `set_cookie` interface in Response struct

What's Changed

  • feat: implement set_cookie function by @VishnuSanal in https://github.com/sparckles/Robyn/pull/870
  • fix: typo error in postgres scaffold by @octaviusp in https://github.com/sparckles/Robyn/pull/883

New Contributors

  • @octaviusp made their first contribution in https://github.com/sparckles/Robyn/pull/883

Full Changelog: https://github.com/sparckles/Robyn/compare/v0.56.2...v0.56.3

v0.56.2 - fix file serving

What's Changed

  • docs: fix html docs by @sansyrox in https://github.com/sparckles/Robyn/pull/880
  • fix: file serving by @sansyrox in https://github.com/sparckles/Robyn/pull/881

Full Changelog: https://github.com/sparckles/Robyn/compare/v0.56.1...v0.56.2

v0.56.1 - remove repeated port checking in dev mode

What's Changed

  • chore: pre-commit autoupdate by @pre-commit-ci in https://github.com/sparckles/Robyn/pull/871
  • docs: add docs for all the robyn env variables by @VishnuSanal in https://github.com/sparckles/Robyn/pull/872
  • fix: disable repeated port checking in dev mode by @sansyrox in https://github.com/sparckles/Robyn/pull/875

Full Changelog: https://github.com/sparckles/Robyn/compare/v0.56.0...v0.56.1

v0.56.0 - [BREAKING 🚨] - allow generic names for callback args

What's Changed

  • docs: fix typo in the get_crimes route by @Amaljyothi44 in https://github.com/sparckles/Robyn/pull/852
  • docs: document redirection by @VishnuSanal in https://github.com/sparckles/Robyn/pull/846
  • chore: pre-commit autoupdate by @pre-commit-ci in https://github.com/sparckles/Robyn/pull/860
  • fix: allow generic names for callback args by @sansyrox in https://github.com/sparckles/Robyn/pull/861

New Contributors

  • @Amaljyothi44 made their first contribution in https://github.com/sparckles/Robyn/pull/852

Full Changelog: https://github.com/sparckles/Robyn/compare/v0.55.0...v0.56.0

v0.55.0 - add prompt for a new port when a port is occupied

What's Changed

  • chore: remove codesee yaml by @sansyrox in https://github.com/sparckles/Robyn/pull/820
  • chore: pre-commit autoupdate by @pre-commit-ci in https://github.com/sparckles/Robyn/pull/823
  • docs: fix form data typo by @sansyrox in https://github.com/sparckles/Robyn/pull/832
  • docs: update class Request documentation by @sansyrox in https://github.com/sparckles/Robyn/pull/834
  • chore: pre-commit autoupdate by @pre-commit-ci in https://github.com/sparckles/Robyn/pull/830
  • docs: better setup instructions by @VishnuSanal in https://github.com/sparckles/Robyn/pull/838
  • docs: split custom exception handler and scaling pages by @VishnuSanal in https://github.com/sparckles/Robyn/pull/843
  • chore: pre-commit autoupdate by @pre-commit-ci in https://github.com/sparckles/Robyn/pull/848
  • feat: prompt for a new port when a port is occupied by @sansyrox in https://github.com/sparckles/Robyn/pull/849

Full Changelog: https://github.com/sparckles/Robyn/compare/v0.54.5...v0.55.0