{"id":15654280,"url":"https://github.com/cbornet/python-httpproblem","last_synced_at":"2025-04-30T22:49:50.706Z","repository":{"id":55627069,"uuid":"120753386","full_name":"cbornet/python-httpproblem","owner":"cbornet","description":"Utility library to work with RFC7807 Problem Details for HTTP APIs","archived":false,"fork":false,"pushed_at":"2020-12-17T05:41:09.000Z","size":20,"stargazers_count":28,"open_issues_count":0,"forks_count":5,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-30T22:49:45.149Z","etag":null,"topics":["http","json","problem","rfc-7807","rfc7807"],"latest_commit_sha":null,"homepage":null,"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/cbornet.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-02-08T11:34:13.000Z","updated_at":"2025-02-16T08:34:35.000Z","dependencies_parsed_at":"2022-08-15T04:50:31.172Z","dependency_job_id":null,"html_url":"https://github.com/cbornet/python-httpproblem","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/cbornet%2Fpython-httpproblem","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cbornet%2Fpython-httpproblem/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cbornet%2Fpython-httpproblem/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cbornet%2Fpython-httpproblem/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cbornet","download_url":"https://codeload.github.com/cbornet/python-httpproblem/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251795387,"owners_count":21645019,"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":["http","json","problem","rfc-7807","rfc7807"],"created_at":"2024-10-03T12:50:24.019Z","updated_at":"2025-04-30T22:49:50.677Z","avatar_url":"https://github.com/cbornet.png","language":"Python","readme":"\n# python-httpproblem\n\nUtility library to work with [RFC7807 Problem Details for HTTP APIs](https://tools.ietf.org/html/rfc7807).\n\n[![Build Status][travis-image]][travis-url]\n[![sonar-quality-gate][sonar-quality-gate]][sonar-url]\n[![sonar-coverage][sonar-coverage]][sonar-url]\n[![sonar-bugs][sonar-bugs]][sonar-url]\n[![sonar-vulnerabilities][sonar-vulnerabilities]][sonar-url]\n\nThis library is very light-weight, with no external dependencies, fully-tested and works with both Python 2 and Python 3.\nIt has special support for [AWS lambda proxy integration output format](https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-output-format)\nbut it should be easy to map to any other format or framework.\nCurrently only JSON serialization is supported.\n\n# Installation\n```\npip install httpproblem\n```\n\n# Usage\n\n## Build a Problem dict\n\nThe `problem()` function that can be used to build a dict with the problem fields.\n```python\n\u003e\u003e\u003e pprint(problem(httplib.BAD_REQUEST, 'You do not have enough credit.', 'Your current balance is 30, but that costs 50.', '/account/12345/msgs/abc'))\n{'detail': 'Your current balance is 30, but that costs 50.',\n 'status': 400,\n 'title': 'You do not have enough credit.',\n 'type': '/account/12345/msgs/abc'}\n```\nYou can also use problem extensions\n```python\n\u003e\u003e\u003e pprint(problem(httplib.BAD_REQUEST, 'You do not have enough credit.', 'Your current balance is 30, but that costs 50.', '/account/12345/msgs/abc', balance=30, accounts=['/account/12345','/account/67890']))\n{'accounts': ['/account/12345', '/account/67890'],\n 'balance': 30,\n 'detail': 'Your current balance is 30, but that costs 50.',\n 'status': 400,\n 'title': 'You do not have enough credit.',\n 'type': '/account/12345/msgs/abc'}\n```\nAs specified by [Predefined Problem Types](https://tools.ietf.org/html/rfc7807#section-4.2):\n\n\u003e The \"about:blank\" URI, when used as a problem type,\n\u003e indicates that the problem has no additional semantics beyond that of\n\u003e the HTTP status code.\n  \n\u003e When \"about:blank\" is used, the title SHOULD be the same as the\n\u003e recommended HTTP status phrase for that code (e.g., \"Not Found\" for\n\u003e 404, and so on), although it MAY be localized to suit client\n\u003e preferences (expressed with the Accept-Language request header).\n\nSo if this library will automatically fill the title field if the type is not present or `about:blank`.\n```python\n\u003e\u003e\u003e problem(404)\n{'status': 404, 'title': 'Not Found'}\n\u003e\u003e\u003e problem(httplib.BAD_REQUEST, type='about:blank')\n{'status': 400, 'type': 'about:blank', 'title': 'Bad Request'}\n```\n\n## Build a Problem HTTP response\n\nThe `problem_http_response()` function helps to build HTTP responses using the format used by the AWS lambda proxy integration.\nThe method will automatically fill the `Content-Type` header with `application/problem+json` and the HTTP response code with the status.\n```python\n\u003e\u003e\u003e pprint(problem_http_response(httplib.BAD_REQUEST))\n{'body': '{\"status\": 400, \"type\": \"about:blank\", \"title\": \"Bad Request\"}',\n 'headers': {'Content-Type': 'application/problem+json'},\n 'statusCode': 400}\n```\nYou can map this to other frameworks. For instance for Flask (or Werkzeug):\n```python\n\u003e\u003e\u003e problem = problem_http_response(400)\n\u003e\u003e\u003e print(flask.Response(problem['body'], status=problem['statusCode'], headers=problem['headers']))\n\u003cResponse 39 bytes [400 BAD REQUEST]\u003e\n```\nBy default, `json.dumps` is used to serialize into JSON. This can be changed by using the `set_serialize_function`\n```\n\u003e\u003e\u003e httpproblem.set_serialize_method(lambda data: json.dumps(data, indent=4))\n\u003e\u003e\u003e print(problem_http_response(400)['body'])\n{\n    \"status\": 400,\n    \"title\": \"Bad Request\"\n}\n```\n## Raise a Problem exception\n\nThe `Problem` exception class can be used to simplify the error management with try/except.\nThe class has methods to convert it to a Problem dict or HTTP response.\n```python\n\u003e\u003e\u003e try:\n...     raise Problem(httplib.BAD_REQUEST)\n... except Problem as e:\n...     print(e.to_dict())\n...\n{'status': 400, 'title': 'Bad Request'}\n```\nThe `to_dict` and `to_http_response` take a `with_traceback` argument that can be used to include the traceback. You can also set it globally with the `activate_traceback()` function.\nFor security reasons, the default is to not include the traceback and it is recommended to not activate it in production.\n```python\n\u003e\u003e\u003e # Add traceback by call argument\n\u003e\u003e\u003e try:\n...     raise Problem(httplib.BAD_REQUEST)\n... except Problem as e:\n...     pprint(e.to_dict(with_traceback=True))\n...\n{'status': 400,\n 'title': 'Bad Request',\n 'traceback': 'Traceback (most recent call last):\\n  File \"\u003cstdin\u003e\", line 2, in \u003cmodule\u003e\\nProblem: {\\'status\\': 400, \\'title\\': \\'Bad Request\\'}\\n'}\n\u003e\u003e\u003e\n\u003e\u003e\u003e # Add traceback globally\n\u003e\u003e\u003e httpproblem.activate_traceback()\n\u003e\u003e\u003e try:\n...     raise Problem(httplib.BAD_REQUEST)\n... except Problem as e:\n...     pprint(e.to_dict())\n...\n{'status': 400,\n 'title': 'Bad Request',\n 'traceback': 'Traceback (most recent call last):\\n  File \"\u003cstdin\u003e\", line 2, in \u003cmodule\u003e\\nProblem: {\\'status\\': 400, \\'title\\': \\'Bad Request\\'}\\n'}\n```\n\n\n[travis-image]: https://travis-ci.org/cbornet/python-httpproblem.svg?branch=master\n[travis-url]: https://travis-ci.org/cbornet/python-httpproblem\n\n[sonar-url]: https://sonarcloud.io/dashboard?id=python-httpproblem\n[sonar-quality-gate]: https://sonarcloud.io/api/badges/gate?key=python-httpproblem\n[sonar-coverage]: https://sonarcloud.io/api/badges/measure?key=python-httpproblem\u0026metric=coverage\n[sonar-bugs]: https://sonarcloud.io/api/badges/measure?key=python-httpproblem\u0026metric=bugs\n[sonar-vulnerabilities]: https://sonarcloud.io/api/badges/measure?key=python-httpproblem\u0026metric=vulnerabilities\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcbornet%2Fpython-httpproblem","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcbornet%2Fpython-httpproblem","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcbornet%2Fpython-httpproblem/lists"}