{"id":21578708,"url":"https://github.com/julian-nash/respond","last_synced_at":"2025-04-10T17:41:40.360Z","repository":{"id":57461484,"uuid":"260982822","full_name":"Julian-Nash/respond","owner":"Julian-Nash","description":"A fast, effective \u0026 efficient way to return JSON, text and XML in Flask with the correct HTTP status code \u0026 headers.","archived":false,"fork":false,"pushed_at":"2020-09-11T20:52:53.000Z","size":56,"stargazers_count":7,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-08T08:21:16.729Z","etag":null,"topics":["api","flask","http","json","python","rest"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/respond/","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/Julian-Nash.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":"2020-05-03T17:22:57.000Z","updated_at":"2023-09-23T18:32:03.000Z","dependencies_parsed_at":"2022-09-10T04:04:53.353Z","dependency_job_id":null,"html_url":"https://github.com/Julian-Nash/respond","commit_stats":null,"previous_names":["julian-nash/jsonres"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Julian-Nash%2Frespond","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Julian-Nash%2Frespond/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Julian-Nash%2Frespond/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Julian-Nash%2Frespond/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Julian-Nash","download_url":"https://codeload.github.com/Julian-Nash/respond/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248262187,"owners_count":21074260,"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","flask","http","json","python","rest"],"created_at":"2024-11-24T13:11:25.427Z","updated_at":"2025-04-10T17:41:40.343Z","avatar_url":"https://github.com/Julian-Nash.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# respond\n\n![Python package](https://github.com/Julian-Nash/respond/workflows/Python%20package/badge.svg?branch=master)\n\n`respond` is a small, lightweight wrapper around Flask's `make_response` and `jsonify`, providing a fast and convenient\nway to return JSON, XML or plaintext data with the right HTTP status code and headers.\n\n`respond` utilizes the RFC HTTP status code descriptions as methods, you simply call a static method\nsuch as `ok`, `not_found` or `internal_server_error` against the data type you with to return, optionally passing in\n a dictionary of headers to set on the response.\n\n__Python v3.6 + (100% coverage)__\n\n```shell script\nName                           Stmts   Miss  Cover   Missing\n------------------------------------------------------------\nrespond/__init__.py                4      0   100%\nrespond/abs_http_response.py     188      0   100%\nrespond/json_response.py          11      0   100%\nrespond/responder.py               7      0   100%\nrespond/text_response.py          12      0   100%\nrespond/xml_response.py           12      0   100%\n------------------------------------------------------------\nTOTAL                            234      0   100%\n\n```\n\n## Installation\n\n```shell script\npip install respond\n```\n\n## Usage\n\nImport the `Responder` class\n\n```py3\nfrom respond import Responder\n```\n\nYou can now call one of many staticmethods of the class\n\nReturn a `200 OK` status code and a list\n\n```py3\n@app.route(\"/\")\ndef example():\n    \"\"\" Returns a list with an HTTP 200 OK status code \"\"\"\n    return Responder.json.ok([1, 2, 3])\n```\n\nReturn a `400 BAD REQUEST` status code and a dict\n\n```py3\n@app.route(\"/\")\ndef example():\n    \"\"\" Returns a dict with an HTTP 400 BAD REQUEST status code \"\"\"\n    return Responder.json.bad_request({\"error\": {\"message\": \"You did something wrong\"}})\n```\n\nReturn a `500 INTERNAL SERVER ERROR` status code\n\n```py3\n@app.route(\"/\")\ndef example():\n    \"\"\" Returns a dict with an HTTP 500 INTERNAL SERVER ERROR status code \"\"\"\n    return Responder.json.internal_server_error({\"error\": {\"message\": \"We did something wrong\"}})\n```\n\nPassing no data to the method returns an empty string\n\n```py3\n@app.route(\"/\")\ndef ok():\n    \"\"\" Return an empty HTTP 204 NO CONTENT response \"\"\"\n    return Responder.json.no_content()\n```\n\nYou can optionally pass in a headers dict if required\n\n```py3\n@app.route(\"/\")\ndef example():\n    \"\"\" Return a dict with custom headers \"\"\"\n    return Responder.json.ok(data={\"message\": \"ok\"}, headers={\"X-Custom-Header\": \"hello!\"})\n```\n\nOn inspecting the response, we can see our custom header:\n\n```shell script\nContent-Length: 17\nDate: Sun, 03 May 2020 16:49:41 GMT\nContent-Type: application/json\nServer: Werkzeug/1.0.1 Python/3.8.2\nX-Custom-Header: hello!\n```\n\nThe `Responder` class has methods for all HTTP status codes defined by the ietf - https://tools.ietf.org/html/rfc7231\n\nCommon status codes include, `404 NOT FOUND`, here being used in a Flask error handler\n\n```py3\ndef handle_not_found_error(e):\n    \"\"\" Handler for not found errors \"\"\"\n    app.logger.warning(e)\n    return Responder.json.not_found(data={\"message\": \"Not found\"})\n\napp.register_error_handler(404, handle_not_found_error)\n```\n\nAnd `500 INTERNAL SERVER ERROR`\n\n```py3\n@app.route(\"/internal-server-error\")\ndef internal_server_error():\n    data: dict = {\"error\": {\"message\": \"Whoops, we did something wrong\"}}\n    return Responder.json.internal_server_error(data)\n```\n\nVisiting this URL in the browser returns\n\n```shell script\n{\"error\": {\"message\": \"Whoops, we did something wrong\"}\n```\n\nYou may also import individual classes for the specific data types JSON, XML and text using `JSONResponse`, \n`XMLResponse` and `TextResponse` respectively.\n\n```py3\nfrom respond import JSONResponse\n\n@app.route(\"/internal-server-error\")\ndef internal_server_error():\n    data: dict = {\"error\": {\"message\": \"Whoops, we did something wrong\"}}\n    return JSONResponse.internal_server_error(data)\n```\n\n## Extending\n\nThe `HTTPResponse` abstract base class provides an interface for all of the HTTP status codes and defines a single\n abstract method called `_make_response`.\n \nUsers can implement their own class by inheriting from `HTTPResponse` and implementing the `_make_response` method\n, accepting 4 parameters `status`, `data`, `headers` and `**kwargs`.\n\n```py3\nclass HTTPResponse(abc.ABC):\n    \"\"\" HTTPResponse abstract base class \"\"\"\n\n    @classmethod\n    @abc.abstractmethod\n    def _make_response(cls, status: int, data: Optional[Any] = None, headers: Optional[dict] = None, **kwargs):\n        raise NotImplementedError\n```\n\n## Methods available\n\n**100 range (informational)**\n\n| method | HTTP Status code |\n| ------ | ---------------- |\n| `continue` | `100 `|\n| `switching_protocol` | `101 `|\n| `processing` | `102 `|\n| `early_hints` | `103 `|\n\n**200 range (success)**\n\n| method | HTTP Status code |\n| ------ | ---------------- |\n| `ok` | `200 `|\n| `created` | `201 `|\n| `accepted` | `202 `|\n| `non_authoritative_information` | `203 `|\n| `no_content` | `204 `|\n| `reset_content` | `205 `|\n| `partial_content` | `206 `|\n| `multi_status` | `207 `|\n| `already_reported` | `208 `|\n| `im_used` | `226 `|\n\n**300 range (redirection)**\n\n| method | HTTP Status code |\n| ------ | ---------------- |\n| `multiple_choice` | `300 `|\n| `moved_permanently` | `301 `|\n| `found` | `302 `|\n| `see_other` | `303 `|\n| `not_modified` | `304 `|\n| `use_proxy` | `305 `|\n| `unused` | `306 `|\n| `temporary_redirect` | `307 `|\n| `permanent_redirect` | `308 `|\n\n**400 range (client error)**\n\n| method | HTTP Status code |\n| ------ | ---------------- |\n| `bad_request` | `400 `|\n| `unauthorized` | `401 `|\n| `payment_required` | `402 `|\n| `forbidden` | `403 `|\n| `not_found` | `404 `|\n| `method_not_allowed` | `405 `|\n| `not_acceptable` | `406 `|\n| `proxy_authentication_required` | `407 `|\n| `request_timeout` | `408 `|\n| `conflict` | `409 `|\n| `gone` | `410 `|\n| `length_required` | `411 `|\n| `precondition_failed` | `412 `|\n| `payload_too_large` | `413 `|\n| `uri_too_long` | `414 `|\n| `unsupported_media_type` | `415 `|\n| `requested_range_not_satisfiable` | `416 `|\n| `expectation_failed` | `417 `|\n| `im_a_teapot` | `418 `|\n| `misdirected_request` | `421 `|\n| `unprocessable_entity` | `422 `|\n| `locked` | `423 `|\n| `failed_dependency` | `424 `|\n| `too_early` | `425 `|\n| `upgrade_required` | `426 `|\n| `precondition_required` | `428 `|\n| `too_many_requests` | `429 `|\n| `request_header_fields_too_large` | `431 `|\n| `unavailable_for_legal_reasons` | `451 `|\n\n**500 range (server error)**\n\n| method | HTTP Status code |\n| ------ | ---------------- |\n| `internal_server_error` | `500 `|\n| `not_implemented` | `501 `|\n| `bad_gateway` | `502 `|\n| `service_unavailable` | `503 `|\n| `gateway_timeout` | `504 `|\n| `http_version_not_supported` | `505 `|\n| `variant_also_negotiates` | `506 `|\n| `insufficient_storage` | `507 `|\n| `loop_detected` | `508 `|\n| `not_extended` | `510 `|\n| `network_authentication_required` | `511 `|","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjulian-nash%2Frespond","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjulian-nash%2Frespond","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjulian-nash%2Frespond/lists"}