Robyn Documentation

repository·main·Indexed 27 days ago

https://github.com/sparckles/robyn

Robyn is a high-performance, async Python web framework featuring a Rust runtime. It supports synchronous and asynchronous functions, dynamic routing, WebSockets, and automatic OpenAPI generation. Key features include parameter injection, SubRouters for route organization, and a Model Context Protocol (MCP) implementation for AI agents. Requires Python 3.10 or higher.

Tokens
57.7K
Snippets
174
Records
298
Agent score
92%

What's inside Robyn

  1. Explore Robyn documentation

    main

    Robyn documentation is divided into two primary sections to help you get started:

    1. Example Application: A simple web application designed to demonstrate how to use the Robyn API in a practical context. This is recommended for users new to Robyn.
    2. API Reference: Detailed technical documentation of the Robyn API. This is recommended for users already familiar with the framework who need specific implementation details.
  2. Understand Robyn's Scaling Model

    main

    Robyn uses a shared-nothing multi-process model combined with worker threads to achieve high performance:

    • Multi-Process Architecture: Each process runs its own Python interpreter and memory space with its own Global Interpreter Lock (GIL). This allows for linear scaling across CPU cores and provides fault isolation.
    • Worker Threads: Within each process, multiple worker threads handle concurrency. These threads share the same memory space and are subject to the GIL for CPU-bound tasks, but they excel at I/O-bound operations (database calls, HTTP requests, file operations) by releasing the GIL.
  3. Implement a RESTful API with HTTP methods

    main

    Robyn supports all standard HTTP methods. You can define routes using decorators like @app.get(), @app.post(), @app.put(), @app.patch(), and @app.delete(). For POST, PUT, and PATCH requests, you can access the request body using request.json().

    from robyn import Robyn, Request
    
    app = Robyn(__file__)
    
    # GET - Retrieve data
    @app.get("/posts")
    def get_posts(query_params):
        return {"posts": []}
    
    # POST - Create data
    @app.post("/posts")
    def create_post(request: Request):
        data = request.json()
        return {"message": "Post created", "post": data}, 201
    
    # PUT - Update entire resource
    @app.put("/posts/:id")
    def update_post(request: Request, path_params):
        post_id = path_params["id"]
        data = request.json()
        return {"message": "Post updated"}
    
    # PATCH - Partial update
    @app.patch("/posts/:id")
    def patch_post(request: Request, path_params):
        post_id = path_params["id"]
        data = request.json()
        return {"message": "Post patched"}
    
    # DELETE - Remove resource
    @app.delete("/posts/:id")
    def delete_post(path_params):
        post_id = path_params["id"]
        return {"message": "Post deleted"}
  4. Optimize timeouts for different workloads

    main

    Adjust client_timeout and keep_alive_timeout based on your specific application needs:

    • High-Traffic Production: Use a lower keep_alive_timeout (5-15s) for faster connection turnover and a moderate client_timeout (15-30s).
    • Long-Running Operations: Use a higher client_timeout (60-300s) and standard keep_alive_timeout (20-30s).
    • Development/Debugging: Use long timeouts (e.g., client_timeout=300) to prevent connections from dropping while inspecting state.
    • Load Testing: Use quick timeouts (e.g., client_timeout=10, keep_alive_timeout=5) to simulate rapid connection turnover.
  5. Serve files and HTML

    main

    Robyn provides several ways to serve files:

    • serve_file(path): Sets Content-Disposition: attachment and auto-detects MIME type.
    • serve_html(path): Sets Content-Type: text/html.
    • FileResponse: Provides full control over file serving, including status codes and custom headers.
    • html(string): Wraps a raw HTML string in a Response with Content-Type: text/html and status 200.
    from robyn import Robyn
    from robyn.responses import serve_file, serve_html, html, FileResponse
    
    app = Robyn(__file__)
    
    @app.get("/download")
    def download():
        return serve_file("report.pdf")
    
    @app.get("/page")
    def page():
        return serve_html("templates/index.html")
    
    @app.get("/html-string")
    def html_string():
        return html("<h1>Hello</h1>")
    
    @app.get("/custom-file")
    def custom_file():
        return FileResponse(
            file_path="data/export.csv",
            status_code=200,
            headers=Headers({"Content-Type": "text/csv"}),
        )
  6. Configure and manage OpenAPI/Swagger documentation

    main

    Robyn automatically generates OpenAPI specifications and a Swagger UI.

    By default, the following endpoints are available:

    • /docs: The Swagger UI
    • /openapi.json: The JSON Specification

    Custom Configuration

    To use a custom configuration, you can:

    1. Place an openapi.json file in your project's root directory.
    2. Pass a file path to the openapi_file_path parameter in the Robyn() constructor (this takes priority).

    Disabling OpenAPI

    To disable OpenAPI generation, use the --disable-openapi flag when starting your application.

    python app.py --disable-openapi
  7. Manage shared variables in Multiprocess Execution

    main

    In a Robyn multiprocessing environment, variables are shared across multiple processes. However, when using multithreading, variables are not protected from concurrent access by default. To protect a variable within a process while accessing it from different threads, use multiprocessing.Value from Python's standard library.

    import threading
    import time
    from multiprocessing import Value
    
    from robyn import Robyn, Request
    
    app = Robyn(__file__)
    
    # Initialize a shared integer value with protection
    count: Value = Value("i", 0)
    
    def counter():
        while True:
            count.value += 1
            time.sleep(0.2)
            print(count.value, "added 1")
    
    @app.get("/")
    def index(request: Request):
        return f"{count.value}"
    
    # Start a background thread to modify the shared value
    threading.Thread(target=counter, daemon=True).start()
    
    app.start()
  8. Handle JSON responses and status codes

    main

    Robyn automatically serializes Python dictionaries and lists into JSON responses with the appropriate Content-Type headers. You can also return a tuple containing the response data and an integer status code to customize the HTTP response.

    from robyn import Robyn, Request
    
    app = Robyn(__file__)
    
    # Automatic JSON serialization
    @app.get("/api/status")
    def get_status():
        return {"status": "active"}
    
    # Custom status code with JSON
    @app.post("/api/posts")
    def create_post(request: Request):
        try:
            data = request.json()
            if not data.get("title"):
                return {"error": "Title is required"}, 400
            
            return {"message": "Created"}, 201
        except ValueError:
            return {"error": "Invalid JSON format"}, 400