{"id":18636665,"url":"https://github.com/localstack/rolo","last_synced_at":"2025-04-11T09:30:59.818Z","repository":{"id":218062138,"uuid":"739851728","full_name":"localstack/rolo","owner":"localstack","description":"A Python framework for building HTTP-based server applications","archived":false,"fork":false,"pushed_at":"2025-02-10T16:25:41.000Z","size":221,"stargazers_count":13,"open_issues_count":3,"forks_count":0,"subscribers_count":20,"default_branch":"main","last_synced_at":"2025-04-04T21:12:15.266Z","etag":null,"topics":["api","asgi","chain-of-responsibility","framework","http","pipeline","python","rest","server","web","wsgi"],"latest_commit_sha":null,"homepage":"https://rolo.localstack.cloud/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/localstack.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-01-06T18:31:06.000Z","updated_at":"2025-04-04T04:22:12.000Z","dependencies_parsed_at":"2024-07-19T00:13:00.934Z","dependency_job_id":"7719361f-b76d-4a17-8da0-93c0721ac12d","html_url":"https://github.com/localstack/rolo","commit_stats":null,"previous_names":["localstack/rolo"],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/localstack%2Frolo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/localstack%2Frolo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/localstack%2Frolo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/localstack%2Frolo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/localstack","download_url":"https://codeload.github.com/localstack/rolo/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248368206,"owners_count":21092317,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","asgi","chain-of-responsibility","framework","http","pipeline","python","rest","server","web","wsgi"],"created_at":"2024-11-07T05:31:02.826Z","updated_at":"2025-04-11T09:30:59.513Z","avatar_url":"https://github.com/localstack.png","language":"Python","readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://github.com/thrau/rolo/assets/3996682/268786a8-6335-412f-bc72-8080f97cbb5a\" alt=\"Rolo HTTP\"\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n  Rolo HTTP: A Python framework for building HTTP-based server applications.\n\u003c/p\u003e\n\n# Rolo HTTP\n\n\u003cp\u003e\n  \u003ca href=\"https://github.com/localstack/rolo/actions/workflows/build.yml\"\u003e\u003cimg alt=\"CI badge\" src=\"https://github.com/localstack/rolo/actions/workflows/build.yml/badge.svg\"\u003e\u003c/img\u003e\u003c/a\u003e\n  \u003ca href=\"https://pypi.org/project/rolo/\"\u003e\u003cimg alt=\"PyPI Version\" src=\"https://img.shields.io/pypi/v/rolo?color=blue\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://coveralls.io/github/localstack/rolo?branch=main\"\u003e\u003cimg src=\"https://coveralls.io/repos/github/localstack/rolo/badge.svg?branch=main\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://img.shields.io/pypi/l/rolo.svg\"\u003e\u003cimg alt=\"PyPI License\" src=\"https://img.shields.io/pypi/l/rolo.svg\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/psf/black\"\u003e\u003cimg alt=\"Code style: black\" src=\"https://img.shields.io/badge/code%20style-black-000000.svg\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\nRolo is a flexible framework and library to build HTTP-based server applications beyond microservices and REST APIs.\nYou can build HTTP-based RPC servers, websocket proxies, or other server types that typical web frameworks are not designed for.\n\nRolo extends [Werkzeug](https://github.com/pallets/werkzeug/), a flexible Python HTTP server library, for you to use concepts you are familiar with like `Router`, `Request`, `Response`, or `@route`.\nIt introduces the concept of a `Gateway` and `HandlerChain`, an implementation variant of the [chain-of-responsibility pattern](https://en.wikipedia.org/wiki/Chain-of-responsibility_pattern).\n\nRolo is designed for environments that do not use asyncio, but still require asynchronous HTTP features like HTTP2 SSE or Websockets.\nTo allow asynchronous communication, Rolo introduces an ASGI/WSGI bridge, that allows you to serve Rolo applications through ASGI servers like Hypercorn.\n\n## Usage\n\n### Default router example\n\nRouters are based on Werkzeug's [URL Map](https://werkzeug.palletsprojects.com/en/2.3.x/routing/), but dispatch to handler functions directly.\nThe `@route` decorator works similar to Flask or FastAPI, but they are not tied to an Application object.\nInstead, you can define routes on functions or methods, and then add them directly to the router.\n\n```python\nfrom rolo import Router, route, Response\nfrom werkzeug import Request\nfrom werkzeug.serving import run_simple\n\n@route(\"/users\")\ndef user(_request: Request, args):\n    assert not args\n    return Response(\"user\")\n\n@route(\"/users/\u003cint:user_id\u003e\")\ndef user_id(_request: Request, args):\n    assert args\n    return Response(f\"{args['user_id']}\")\n\nrouter = Router()\nrouter.add(user)\nrouter.add(user_id)\n\n# convert Router to a WSGI app and serve it through werkzeug\nrun_simple('localhost', 8080, router.wsgi(), use_reloader=True)\n```\n\n### Pydantic integration\n\nRouters use dispatchers to dispatch the request to functions.\nIn the previous example, the default dispatcher calls the function with the `Request` object and the request arguments as dictionary.\nThe \"handler dispatcher\" can transform functions into more Flask or FastAPI-like functions, that also allow you to integrate with Pydantic.\nHere's how the default example from the FastAPI documentation would look like with rolo:\n\n```python\nimport pydantic\nfrom werkzeug import Request\nfrom werkzeug.serving import run_simple\n\nfrom rolo import Router, route\n\n\nclass Item(pydantic.BaseModel):\n    name: str\n    price: float\n    is_offer: bool | None = None\n\n\n@route(\"/\", methods=[\"GET\"])\ndef read_root(request: Request):\n    return {\"Hello\": \"World\"}\n\n\n@route(\"/items/\u003cint:item_id\u003e\", methods=[\"GET\"])\ndef read_item(request: Request, item_id: int):\n    return {\"item_id\": item_id, \"q\": request.query_string}\n\n\n@route(\"/items/\u003cint:item_id\u003e\", methods=[\"PUT\"])\ndef update_item(request: Request, item_id: int, item: Item):\n    return {\"item_name\": item.name, \"item_id\": item_id}\n\n\nrouter = Router()\nrouter.add(read_root)\nrouter.add(read_item)\nrouter.add(update_item)\n\n# convert Router to a WSGI app and serve it through werkzeug\nrun_simple(\"localhost\", 8080, router.wsgi(), use_reloader=True)\n```\n\n### Gateway \u0026 Handler Chain\n\nA rolo `Gateway` holds a set of request, response, and exception handlers, as well as request finalizers.\nGateway instances can then be served as WSGI or ASGI applications by using the appropriate serving adapter.\nHere is a simple example of a Gateway with just one handler that returns the URL and method that was invoked.\n\n```python\nfrom werkzeug import run_simple\n\nfrom rolo import Response\nfrom rolo.gateway import Gateway, HandlerChain, RequestContext\nfrom rolo.gateway.wsgi import WsgiGateway\n\n\ndef echo_handler(chain: HandlerChain, context: RequestContext, response: Response):\n    response.status_code = 200\n    response.set_json({\"url\": context.request.url, \"method\": context.request.method})\n\n\ngateway = Gateway(request_handlers=[echo_handler])\n\napp = WsgiGateway(gateway)\nrun_simple(\"localhost\", 8080, app, use_reloader=True)\n```\n\nServing this will yield:\n\n```console\ncurl http://localhost:8080/hello-world\n{\"url\": \"http://localhost:8080/hello-world\", \"method\": \"GET\"}\n```\n\n\n## Develop\n\n### Quickstart\n\nto install the python and other developer requirements into a venv run:\n\n    make install\n\n### Format code\n\nWe use black and isort as code style tools.\nTo execute them, run:\n\n    make format\n\n### Build distribution\n\nTo build a wheel and source distribution, simply run\n\n    make dist\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flocalstack%2Frolo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flocalstack%2Frolo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flocalstack%2Frolo/lists"}