{"id":19935959,"url":"https://github.com/imbolc/django-raw-api","last_synced_at":"2025-05-03T12:31:34.010Z","repository":{"id":57421506,"uuid":"159519738","full_name":"imbolc/django-raw-api","owner":"imbolc","description":"Async-friendly straightforward Django API helpers","archived":false,"fork":false,"pushed_at":"2020-08-30T11:10:46.000Z","size":18,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-20T16:04:47.048Z","etag":null,"topics":["async","asyncio","django","json","json-api","json-validation","rest","rest-api"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/imbolc.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}},"created_at":"2018-11-28T15:03:20.000Z","updated_at":"2024-04-28T12:00:47.000Z","dependencies_parsed_at":"2022-09-07T11:51:42.492Z","dependency_job_id":null,"html_url":"https://github.com/imbolc/django-raw-api","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/imbolc%2Fdjango-raw-api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/imbolc%2Fdjango-raw-api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/imbolc%2Fdjango-raw-api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/imbolc%2Fdjango-raw-api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/imbolc","download_url":"https://codeload.github.com/imbolc/django-raw-api/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252191045,"owners_count":21709000,"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":["async","asyncio","django","json","json-api","json-validation","rest","rest-api"],"created_at":"2024-11-12T23:22:45.757Z","updated_at":"2025-05-03T12:31:33.552Z","avatar_url":"https://github.com/imbolc.png","language":"Python","readme":"django-raw-api\n==============\n[Async][async views]-friendly straightforward Django API helpers\n\nHello world\n-----------\n```python\nfrom raw_api import validate_json\n\n@validate_json({\"name\": str})\ndef hello(request):\n    name = request.json[\"name\"]\n    if name == \"death\":\n        return \"not today\", 403\n    return {\"hello\": request.json[\"name\"]}\n```\n\nSetup\n-----\n\n- Install in from pypi: `pip install django-raw-api`\n- Add `raw_api` into `INSTALLED_APPS` list of your `settings.py`\n- Add `raw_api.middleware` middleware into `MIDDLEWARE`\n\nAPI\n---\n\n### Middleware\n\nIt adds lazy `request.json` attribute and serializes raw responses such as:\n- `str` or `tuple(message: str, status: int)` - into plain text response\n- `dict` or `tuple(data: dict, status: int)` - into JSON response\n\n### Request\n\n- `request.json: dict` - parsed json\n- `request.query: dict` - parsed query (only after `@validate_query`)\n\n\n### Response\n\nYou can just return `str` or `dict` with an optional status code\n\n```python\ndef json_200ok(request):\n    return {\"hello\": \"world\"}\n\n\ndef plain_text_with_status(request):\n    return \"bad request\", 400\n```\n\n\n### Authorization\n\nDecorators `@user_required` and `@staff_required` is analogous to\n`@login_required` and  `@staff_member_required` with JSON-based errors instead\nof redirecting\n\nBoth decorators cache `request.user` so you can use it without `sync_to_async`\neven in async views.\n\n```python\nfrom raw_api import user_required, staff_required\n\n@user_required\nasync def user(request):\n    # no `sync_to_async` required\n    return request.user.username\n\n@staff_required\ndef staff(request):\n    return {\"admin\": \"zone\"}\n```\n\n\nData validation\n---------------\n`@validate_query` and `@validate_json` decorators are there to perform simple\nfirst-level validation of requests data. Internally they use the [trafaret][]\nlibrary.\n\n```python\nfrom raw_api import validate_json, validate_query\n\n@validate_json({\"ids\": [int], \"hello?\": str})\nasync def foo(request):\n    return request.json\n\n@validate_query({\"id\": int})\ndef bar(request):\n    assert isinstance(id, int)\n    return request.query\n```\n\nExamples\n--------\n\nThere's an example of using it with [async views][] in the `examples` folder.\n\nTests\n-----\n```bash\n    python -m venv .venv\n    source .venv/bin/activate\n    pip install -Ur requirements-dev.txt\n    python -m pytest tests\n```\n\n[async views]: https://docs.djangoproject.com/en/3.1/topics/async/#async-views\n[trafaret]: https://github.com/Deepwalker/trafaret\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fimbolc%2Fdjango-raw-api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fimbolc%2Fdjango-raw-api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fimbolc%2Fdjango-raw-api/lists"}