{ "info": { "author": "Denis Makogon", "author_email": "lildee1991@gmail.com", "bugtrack_url": null, "classifiers": [ "Intended Audience :: Information Technology", "Intended Audience :: System Administrators", "License :: OSI Approved :: Apache Software License", "Operating System :: POSIX :: Linux", "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6" ], "description": "[![Build Status](https://travis-ci.org/denismakogon/hotfn-py.svg?branch=master)](https://travis-ci.org/denismakogon/hotfn-py)\n\nHTTP over STDIN/STDOUT lib parser\n=================================\n\nPurpose of this library to provide simple interface to parse HTTP 1.1 requests represented as string\n\nRaw HTTP request\n----------------\n\nParses raw HTTP request that contains:\n - method\n - route + query\n - headers\n - protocol version\n Optionally:\n - data\n\nRaw HTTP request may have next look:\n\n GET /v1/apps?something=something&etc=etc HTTP/1.1\n Host: localhost:8080\n Content-Length: 5\n Content-Type: application/x-www-form-urlencoded\n User-Agent: curl/7.51.0\n\n hello\n\nEach new line define by set of special characters:\n\n \\n\n \\r\n\nand combination is:\n\n \\r\\n\n\nThis type of class stands for HTTP request parsing to a sane structure of:\n\n - HTTP request method\n - HTTP request URL\n - HTTP request query string represented as map\n - HTTP request headers represented as map\n - HTTP protocol version represented as tuple of major and minor versions\n - HTTP request body\n\n```python\nimport os\nimport sys\n\nfrom hotfn.http import request\n\nwith os.fdopen(sys.stdin.fileno(), 'rb') as stdin:\n req = request.RawRequest(stdin)\n method, url, query_parameters, headers, (major, minor), body = req.parse_raw_request()\n```\n\nRaw HTTP response\n-----------------\n\nThis type of class stands for transforming HTTP request object into valid string representation\n\n```python\nimport sys\nimport os\n\nfrom hotfn.http import request\nfrom hotfn.http import response\n\nwith os.fdopen(sys.stdin.fileno(), 'rb') as stdin:\n req = request.RawRequest(stdin)\n method, url, query_parameters, headers, (major, minor), body = req.parse_raw_request()\n resp = response.RawResponse((major, minor), 200, \"OK\", response_data=body)\n with os.fdopen(sys.stdout.fileno(), 'wb') as stdout:\n resp.dump(stdout)\n```\n\nExample\n-------\n\nAssume we have HTTP 1.1 request:\n```bash\nGET /v1/apps?something=something&etc=etc HTTP/1.1\nHost: localhost:8080\nContent-Length: 11\nContent-Type: application/x-www-form-urlencoded\nUser-Agent: curl/7.51.0\n\nhello:hello\n\n```\nThis request can be transformed into data structure described above.\nUsing code snippet mentioned above request data can be used to assemble a response object of the following view:\n```bash\nHTTP/1.1 200 OK\nContent-Length: 11\nContent-Type: text/plain; charset=utf-8\n\nhello:hello\n\n```\nThis is totally valid HTTP response object.\n\nNotes\n-----\n\nPlease be aware that response object by default sets content type as `text/plain; charset=utf-8`. If you need to change it use following code:\n```python\nimport os\nimport sys\n\nfrom hotfn.http import request\nfrom hotfn.http import response\n\nwith os.fdopen(sys.stdin.fileno(), 'rb') as stdin:\n req = request.RawRequest(stdin)\n method, url, query_parameters, headers, (major, minor), body = req.parse_raw_request()\n resp = response.RawResponse((major, minor), 200, \"OK\", response_data=body)\n resp.headers[\"Content-Type\"] = \"application/json\"\n with os.fdopen(sys.stdout.fileno(), 'wb') as stdout:\n resp.dump(stdout)\n\n```\n\nHandling Hot Functions\n----------------------\n\nA main loop is supplied that can repeatedly call a user function with a series of HTTP requests.\n(TODO: should this use the WSGI API?)\n\nIn order to utilise this, you can write your `app.py` as follows:\n\n```python\nfrom hotfn.http import worker\nfrom hotfn.http import response\n\n\ndef app(context, **kwargs):\n body = kwargs.get('data')\n return response.RawResponse(context.version, 200, \"OK\", body.readall())\n\n\nif __name__ == \"__main__\":\n worker.run(app)\n\n```\n\nAutomatic input coercions\n-------------------------\n\nDecorators are provided that will attempt to coerce input values to Python types.\nSome attempt is made to coerce return values from these functions also:\n\n```python\nfrom hotfn.http import worker\n\n\n@worker.coerce_input_to_content_type\ndef app(context, **kwargs):\n \"\"\"\n body is a request body, it's type depends on content type\n \"\"\"\n return kwargs.get('data')\n\n\nif __name__ == \"__main__\":\n worker.run(app)\n\n```\n\nWorking with async automatic input coercions\n--------------------------------------------\n\nLatest version (from 0.0.6) supports async coroutines as a request body processors:\n```python\n\nimport asyncio\n\nfrom hotfn.http import worker\nfrom hotfn.http import response\n\n\n@worker.coerce_input_to_content_type\nasync def app(context, **kwargs):\n headers = {\n \"Content-Type\": \"plain/text\",\n }\n return response.RawResponse(\n context.version, 200, \"OK\",\n http_headers=headers,\n response_data=\"OK\")\n\n\nif __name__ == \"__main__\":\n loop = asyncio.get_event_loop()\n worker.run(app, loop=loop)\n\n```\nAs you can see `app` function is no longer callable, because its type: coroutine, so we need to bypass event loop inside\n\n\n\n", "description_content_type": null, "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/denismakogon/hotfn-py", "keywords": "", "license": "", "maintainer": "", "maintainer_email": "", "name": "hotfn", "package_url": "https://pypi.org/project/hotfn/", "platform": "", "project_url": "https://pypi.org/project/hotfn/", "project_urls": { "Homepage": "https://github.com/denismakogon/hotfn-py" }, "release_url": "https://pypi.org/project/hotfn/0.0.6/", "requires_dist": [ "pbr (!=2.1.0,>=2.0.0)" ], "requires_python": "", "summary": "Library to provide HTTP over STDIN/STDOUT", "version": "0.0.6" }, "last_serial": 3219556, "releases": { "0.0.1": [ { "comment_text": "", "digests": { "md5": "fc21db775a120ee6af79c32ca6ba20a5", "sha256": "00be6626fb15ebd2fe6479255cacf84e3dfba633a3b828fed7f200918e393af8" }, "downloads": -1, "filename": "hotfn-0.0.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "fc21db775a120ee6af79c32ca6ba20a5", "packagetype": "bdist_wheel", "python_version": "3.5", "requires_python": null, "size": 5807, "upload_time": "2017-03-26T10:13:42", "url": "https://files.pythonhosted.org/packages/d4/67/bbae0830faef964f84147ae19482b6a90f38ff3165ac47874f8e27b9a73d/hotfn-0.0.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "7d19b727e0ad69d381d505cccda20030", "sha256": "d521c4341d609ff73aba3d7921dc3bf897815674d77c9fbd3f72a38391110dcf" }, "downloads": -1, "filename": "hotfn-0.0.1.tar.gz", "has_sig": false, "md5_digest": "7d19b727e0ad69d381d505cccda20030", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 3535, "upload_time": "2017-03-26T18:45:03", "url": "https://files.pythonhosted.org/packages/66/63/d783489e9501c714eada115f4783d4d279c80a28f6097280915ea5a78667/hotfn-0.0.1.tar.gz" } ], "0.0.1.dev22": [ { "comment_text": "", "digests": { "md5": "cda3c4f10a3595b256d665a9633ce6ca", "sha256": "f4be0bbc8deedf3a7660f660df953034fd4617ad1edb229f59bb1515028bbc52" }, "downloads": -1, "filename": "hotfn-0.0.1.dev22-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "cda3c4f10a3595b256d665a9633ce6ca", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 9448, "upload_time": "2017-09-25T21:23:44", "url": "https://files.pythonhosted.org/packages/db/18/8ae147842d730f9e9f07f03471912874e429385ac9446ddcd68a3e914af8/hotfn-0.0.1.dev22-py2.py3-none-any.whl" } ], "0.0.1.dev23": [ { "comment_text": "", "digests": { "md5": "734105d6d4e0b6fa68401cee093637b2", "sha256": "60891304f810f9fd43e6a5df678fa0f951f9309622fcdbd1c1d114f87d1c64a6" }, "downloads": -1, "filename": "hotfn-0.0.1.dev23.tar.gz", "has_sig": false, "md5_digest": "734105d6d4e0b6fa68401cee093637b2", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9150, "upload_time": "2017-09-25T21:34:13", "url": "https://files.pythonhosted.org/packages/85/3b/7a70bcb997c1723b09bafc580c7707edb72e978b0a5d6904c53b651bf68e/hotfn-0.0.1.dev23.tar.gz" } ], "0.0.2": [ { "comment_text": "", "digests": { "md5": "3904c6db15994dec7e1bdde5251a0778", "sha256": "5b0a26667f72bb68d4aa2f47cc20ad63c6fbacac69d4e55e4d73e72d8807414e" }, "downloads": -1, "filename": "hotfn-0.0.2-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "3904c6db15994dec7e1bdde5251a0778", "packagetype": "bdist_wheel", "python_version": "3.5", "requires_python": null, "size": 5845, "upload_time": "2017-03-27T08:56:41", "url": "https://files.pythonhosted.org/packages/e1/a6/32428b424acabc6375a60cc94d2c2d0b9f09983ea883a92f39fcaf53f6de/hotfn-0.0.2-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "334a1ea8638128037df2f4ef5732da2f", "sha256": "a267cfd65500e369951c9b593d49790fa7fcc08bda0bc78f454fa3762a0bf089" }, "downloads": -1, "filename": "hotfn-0.0.2.tar.gz", "has_sig": false, "md5_digest": "334a1ea8638128037df2f4ef5732da2f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 3566, "upload_time": "2017-03-27T08:59:07", "url": "https://files.pythonhosted.org/packages/2f/f9/4010de159b3b516930b425a2fe3bf88e5c89488e5de29f0d842b62a5fd5a/hotfn-0.0.2.tar.gz" } ], "0.0.3": [ { "comment_text": "", "digests": { "md5": "6879f37c411771fcd87e39c269ac08d3", "sha256": "412ffb54ed58800ea738a7b7eb1691c3cfba1fd652920a4dc2e0c6d6e6b72e63" }, "downloads": -1, "filename": "hotfn-0.0.3.tar.gz", "has_sig": false, "md5_digest": "6879f37c411771fcd87e39c269ac08d3", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 4257, "upload_time": "2017-09-25T20:55:40", "url": "https://files.pythonhosted.org/packages/24/07/25185c2c2c081baf067cdb139d95b429aa6612ae6e7b8a8abf0d826d9cca/hotfn-0.0.3.tar.gz" } ], "0.0.4": [ { "comment_text": "", "digests": { "md5": "6f2e65536018338a58bc4af856567a54", "sha256": "187806db330199cf45dc2fe1f23f026938bdf359226b6c238a3c3d0d3dab65af" }, "downloads": -1, "filename": "hotfn-0.0.4-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "6f2e65536018338a58bc4af856567a54", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 9305, "upload_time": "2017-09-25T21:27:12", "url": "https://files.pythonhosted.org/packages/ec/8f/62b78ac0406851e0c020bdf859875b6fcdc726b49b07ffa4525966a6a33c/hotfn-0.0.4-py2.py3-none-any.whl" } ], "0.0.5": [ { "comment_text": "", "digests": { "md5": "1feb4d94d0aeae440b20ee20f88eb9ce", "sha256": "643b2fa66ff407383eaf1311e7a61c024b53ca2d0ba75798c58db6613cc7f6f6" }, "downloads": -1, "filename": "hotfn-0.0.5-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "1feb4d94d0aeae440b20ee20f88eb9ce", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 14849, "upload_time": "2017-10-01T08:33:43", "url": "https://files.pythonhosted.org/packages/92/8a/150c3c49334e234ae8bc66cd92f5bab996aac25fcbe3ea97709e3d4f3875/hotfn-0.0.5-py2.py3-none-any.whl" } ], "0.0.5.dev39": [ { "comment_text": "", "digests": { "md5": "b52c03d090a05f679b73ca2eebd4f29c", "sha256": "6e5f521cf6fdb2c667dc45211fa6f1a75b940aa4b21a56734d888eecd333fdd2" }, "downloads": -1, "filename": "hotfn-0.0.5.dev39-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "b52c03d090a05f679b73ca2eebd4f29c", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 14954, "upload_time": "2017-10-01T08:33:47", "url": "https://files.pythonhosted.org/packages/cf/b3/a7fe053a1b961498ee08e39e70538ab2017f87a7108c7592e6751c4e8b6c/hotfn-0.0.5.dev39-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "6e9720271bdef1d568acad2ab4f8c997", "sha256": "bbf3835407b2a93915caa526b4890e70fc4bb7346884c2227a96a8aa9de21c9a" }, "downloads": -1, "filename": "hotfn-0.0.5.dev39.tar.gz", "has_sig": false, "md5_digest": "6e9720271bdef1d568acad2ab4f8c997", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12644, "upload_time": "2017-10-01T08:44:46", "url": "https://files.pythonhosted.org/packages/0d/93/4d2b37f04275b907d377ecbeb9f5f18a9820f5ae6c03b1d0d87ebf4e1af4/hotfn-0.0.5.dev39.tar.gz" } ], "0.0.6": [ { "comment_text": "", "digests": { "md5": "705ba879391645ea4c8451466dd66d45", "sha256": "1750ee331c89ec02c6cf0b6dadfe171451aabe3235726b60955f45579e684cb1" }, "downloads": -1, "filename": "hotfn-0.0.6-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "705ba879391645ea4c8451466dd66d45", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 15638, "upload_time": "2017-10-02T15:31:08", "url": "https://files.pythonhosted.org/packages/bc/20/e64da0707e1736690c6514623f145cd68601c204e01f1d327b5e55172a66/hotfn-0.0.6-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "945befe611e52076c1184521d7d4b731", "sha256": "052402be2e2d871dab9187f6682f7c7d3c2d09dd02b14ae59cb10cf4cdfd65b3" }, "downloads": -1, "filename": "hotfn-0.0.6.tar.gz", "has_sig": false, "md5_digest": "945befe611e52076c1184521d7d4b731", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14807, "upload_time": "2017-10-02T15:31:12", "url": "https://files.pythonhosted.org/packages/03/4d/05b941238ca70c6d3c78f433d1242f894c4110a55a854a2ffca57296f679/hotfn-0.0.6.tar.gz" } ], "0.0.6.dev47": [ { "comment_text": "", "digests": { "md5": "469aa713c6b06d795f65c6e54b9a91a6", "sha256": "217495723f00c56b9a554255a25bce5326e145cc1fa1187dc2be91e406ce48e9" }, "downloads": -1, "filename": "hotfn-0.0.6.dev47.tar.gz", "has_sig": false, "md5_digest": "469aa713c6b06d795f65c6e54b9a91a6", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15621, "upload_time": "2017-10-02T15:33:19", "url": "https://files.pythonhosted.org/packages/4e/98/fe482a24696d3f8a44b93ff0a168fad9a9283742fe5eb2cce41426d3b8cf/hotfn-0.0.6.dev47.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "705ba879391645ea4c8451466dd66d45", "sha256": "1750ee331c89ec02c6cf0b6dadfe171451aabe3235726b60955f45579e684cb1" }, "downloads": -1, "filename": "hotfn-0.0.6-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "705ba879391645ea4c8451466dd66d45", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 15638, "upload_time": "2017-10-02T15:31:08", "url": "https://files.pythonhosted.org/packages/bc/20/e64da0707e1736690c6514623f145cd68601c204e01f1d327b5e55172a66/hotfn-0.0.6-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "945befe611e52076c1184521d7d4b731", "sha256": "052402be2e2d871dab9187f6682f7c7d3c2d09dd02b14ae59cb10cf4cdfd65b3" }, "downloads": -1, "filename": "hotfn-0.0.6.tar.gz", "has_sig": false, "md5_digest": "945befe611e52076c1184521d7d4b731", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14807, "upload_time": "2017-10-02T15:31:12", "url": "https://files.pythonhosted.org/packages/03/4d/05b941238ca70c6d3c78f433d1242f894c4110a55a854a2ffca57296f679/hotfn-0.0.6.tar.gz" } ] }