{"id":20280358,"url":"https://github.com/yezz123/yasgi","last_synced_at":"2025-04-11T06:35:58.944Z","repository":{"id":59105814,"uuid":"534848090","full_name":"yezz123/yasgi","owner":"yezz123","description":"yasgi is a tiny ASGI framework ✨","archived":false,"fork":false,"pushed_at":"2024-04-29T23:21:58.000Z","size":46,"stargazers_count":8,"open_issues_count":5,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-05-01T16:25:27.706Z","etag":null,"topics":["asgi","framework","http","python","requests","uvicorn","websocket"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yezz123.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["yezz123"]}},"created_at":"2022-09-10T00:34:01.000Z","updated_at":"2024-07-29T20:29:11.000Z","dependencies_parsed_at":"2024-04-30T00:30:27.356Z","dependency_job_id":"7df031cf-827d-42f0-9a6d-9113b923b4c9","html_url":"https://github.com/yezz123/yasgi","commit_stats":{"total_commits":11,"total_committers":1,"mean_commits":11.0,"dds":0.0,"last_synced_commit":"baff50095034ae9fc2152cd2ff5b503e511b46cd"},"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yezz123%2Fyasgi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yezz123%2Fyasgi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yezz123%2Fyasgi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yezz123%2Fyasgi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yezz123","download_url":"https://codeload.github.com/yezz123/yasgi/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248358295,"owners_count":21090400,"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":["asgi","framework","http","python","requests","uvicorn","websocket"],"created_at":"2024-11-14T13:35:25.225Z","updated_at":"2025-04-11T06:35:58.921Z","avatar_url":"https://github.com/yezz123.png","language":"Python","funding_links":["https://github.com/sponsors/yezz123"],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n    \u003cem\u003eYasgi framework a tiny, small, easy to learn, fast to code ⚡️\u003c/em\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n\u003ca href=\"https://github.com/yezz123/yasgi/actions/workflows/test.yaml\" target=\"_blank\"\u003e\n    \u003cimg src=\"https://github.com/yezz123/yasgi/actions/workflows/test.yaml/badge.svg\" alt=\"Test\"\u003e\n\u003c/a\u003e\n\u003ca href=\"https://app.codecov.io/gh/yezz123/yasgi\" target=\"_blank\"\u003e\n    \u003cimg src=\"https://img.shields.io/codecov/c/github/yezz123/yasgi?color=%2334D058\" alt=\"Coverage\"\u003e\n\u003c/a\u003e\n\u003ca href=\"https://pypi.org/project/yasgi\" target=\"_blank\"\u003e\n    \u003cimg src=\"https://img.shields.io/pypi/v/yasgi?color=%2334D058\u0026label=pypi%20package\" alt=\"Package version\"\u003e\n\u003c/a\u003e\n\u003ca href=\"https://pypi.org/project/yasgi\" target=\"_blank\"\u003e\n    \u003cimg src=\"https://img.shields.io/pypi/pyversions/yasgi.svg?color=%2334D058\" alt=\"Supported Python versions\"\u003e\n\u003c/a\u003e\n\u003c/p\u003e\n\nYasgi is a tiny, small (high-performance), web framework for building APIs with Python 3.9+ using orjson.\n\nThe key features are:\n\n* **Tiny**: Small size and performance.\n* **Fewer bugs**: Reduce about 40% of human (developer) induced errors.\n* **Intuitive**: Great editor support. \u003cabbr title=\"also known as auto-complete, autocompletion, IntelliSense\"\u003eCompletion\u003c/abbr\u003e everywhere. Less time debugging.\n* **Easy**: Designed to be easy to use, Play and Plug.\n* **Short**: Minimize code duplication. Multiple features from each parameter declaration. Fewer bugs.\n\n## Installation\n\n\u003cdiv class=\"termy\"\u003e\n\n```console\n$ pip install yasgi\n\n---\u003e 100%\n```\n\n\u003c/div\u003e\n\nYou will also need an ASGI server, for production such as \u003ca href=\"https://www.uvicorn.org\" class=\"external-link\" target=\"_blank\"\u003eUvicorn\u003c/a\u003e or \u003ca href=\"https://github.com/pgjones/hypercorn\" class=\"external-link\" target=\"_blank\"\u003eHypercorn\u003c/a\u003e.\n\n\u003cdiv class=\"termy\"\u003e\n\n```console\n$ pip install \"uvicorn[standard]\"\n\n---\u003e 100%\n```\n\n\u003c/div\u003e\n\n## Example\n\n### Create it\n\n* Create a file `main.py` with:\n\n```py\nfrom yasgi import YASGI, Routing\n\napp = YASGI(content_type=\"text/html\")\n\n\n@Routing(\"/endpoint\", methods=[\"GET\", \"POST\"])\nasync def endpoint(Request, Response):\n     # set response header\n     Response.add_header(\"X-header\", \"hello\")\n     # set response cookie\n     Response.set_cookie(\"cookie_from_server\", \"384\")\n     # set response body\n     return \"hello world\"\n```\n\nNow you should run it!\n\n### Run it\n\nRun the server with:\n\n\u003cdiv class=\"termy\"\u003e\n\n```console\n$ uvicorn main:app --reload\n\nINFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)\nINFO:     Started reloader process [28720]\nINFO:     Started server process [28722]\nINFO:     Waiting for application startup.\nINFO:     Application startup complete.\n```\n\nThe command `uvicorn main:app` refers to:\n\n* `main`: the file `main.py` (the Python \"module\").\n* `app`: the object created inside of `main.py` with the line `app = YASGI()`.\n* `--reload`: make the server restart after code changes. Only do this for development.\n\n\u003c/div\u003e\n\n### Initializing\n\n```py\nfrom yasgi import YASGI\n\napplication = YASGI(content_type=\"application/json\", allow=\"*\", charset=\"UTF-8\")\n\n```\n\n#### ASGI parameters\n\n* `content_type` - specifies the default content type of generated responses (optional, default: `application/json`)\n* `charset` - specifies the default charset generated responses (optional, default: `UTF-8`)\n* `allow` - specifies global setting for `Access-Control-Allow-Origin` header - can be overwrite by passing that header to response headers (optional, default `None` - for public API should be set to `*`)\n\n### Routing\n\n#### Routers parameters\n\n* `endpoint` - object should contain str or regex Pattern to match request path (mandatory)\n* `type` - defines that routed is serving HTTP or WebSocket protocol (possible values: `http`, `websocket`; default: `http`)\n* `methods` - list of HTTP methods to match request method - higher priority than method (optional, default: [`GET`], should be only be specified on `http` type routes)\n* \\*kwargs - other arguments - can be accessed by middleware in states `routed` and `end`\n* `content-type`\n\n#### Usage\n\nRoute is used as a decorator callable object you want to use as router method.\nRouter method takes two mandatory arguments `Request` and `Response` (explained below in a separate section).\nRouter method can also take variables from router regex match (if used).\n\n#### HTTP Examples\n\n```py\nimport re\nfrom yasgi import Routing\n\n# simple route\n@Routing(\"/endpoint\", method=\"GET\")\n# simple route method\nasync def routed_method_1(request, response):\n     # response return without status code \u0026 mime type\n     return \"Response from route 1\"\n\n# re package import needed\n@Routing(re.compile(\"/endpoint/(\\d+)$\"), methods=[\"GET\", \"POST\"])\n# regex route, with multiple methods\nasync def routed_method_2(request, response, number):\n     # full response return\n     return f\"Response from route - url_number is: {number}\", \"200 OK\", \"text/html\"\n\n@Routing(\"/endpoint3\", methods=[\"GET\", \"POST\"])\n#simple route, with multiple methods\nasync def routed_method_2(request, response):\n     # alternatively can be called response method set to set response\n     response.set(\"Response by set\")\n\n```\n\n### Raise HTTP status\n\nRaise HTTPStatus is used to raise HTTP status code, and optional message.\n\n```py\nfrom http import HTTPStatus\nfrom yasgi import Routing\n\n@Routing(\"/raise_endpoint\", methods=[\"POST\"])\nasync def routed_method_2(request, response):\n     if not request.data:\n          raise HTTPStatus(\"400 BAD REQUEST\", \"400 BAD REQUEST\")\n     return \"data sent\"\n```\n\n### Request \u0026 Response objects\n\nInstances of these object are given to every function that is called with `@Routing` decorator.\n\n```py\nfrom yasgi import Routing\n\n@Routing(\"/endpoint\", method=\"GET\")\nasync def endpoint(Request, Response):\n # instances of Request and Response objects\n pass\n```\n\n#### Request items and methods (HTTP)\n\n* `method` - request method (GET, POST etc.) : read only\n* `path` - request path: read only\n* `query_params` - `dict` of query_string parameters\n* `data` - request parsed data (json, -www-form-urlencoded, multipart/form-data) : read only\n* `headers` - HTTP headers : read only (may contain `content_length` and `content_type` in post requests)\n* `cookies` - dict contains `SimpleCookie` object of every cookie loaded\n* `scope` - raw asgi scope object\n* `event` - raw asgi event object\n\n#### Response  items and methods (HTTP)\n\n* `content_type` - response content-type : read only - can be specified in route\n* `charset` - response encoding; default: `UTF-8`\n* `headers` - `list` of response headers:\n  * `redirect(location, status)` - redirects response to (`location`, `status` if not provide is set to `302`)\n  * `set_cookie(name, value, expires=None, maxAge=None, **kwargs)` - adds cookie to response with obvious parameters, you can alow add additional arguments (`kwargs`) such as `Domain`, `Path`, `Secure`, `HttpOnly`\n  * `add_header(name, value)` - adds header to response\n  * `process(data, status=200)` - allow to manual process response\n\n## Development 🚧\n\n### Setup environment 📦\n\nYou should create a virtual environment and activate it:\n\n```bash\npython -m venv venv/\n```\n\n```bash\nsource venv/bin/activate\n```\n\nAnd then install the development dependencies:\n\n```bash\n# Install Flit\npip install flit\n\n# Install dependencies\nflit install --symlink\n```\n\n### Run tests 🌝\n\nYou can run all the tests with:\n\n```bash\nbash scripts/test.sh\n```\n\n\u003e Note: You can also generate a coverage report with:\n\n```bash\nbash scripts/test_html.sh\n```\n\n### Format the code 🍂\n\nExecute the following command to apply `pre-commit` formatting:\n\n```bash\nbash scripts/format.sh\n```\n\nExecute the following command to apply `mypy` type checking:\n\n```bash\nbash scripts/lint.sh\n```\n\n## License\n\nThis project is licensed under the terms of the [GNU GENERAL PUBLIC LICENSE Version 3](https://www.gnu.org/licenses/gpl-3.0.en.html).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyezz123%2Fyasgi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyezz123%2Fyasgi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyezz123%2Fyasgi/lists"}