{ "info": { "author": "Kilerd Chan", "author_email": "", "bugtrack_url": null, "classifiers": [ "Development Status :: 3 - Alpha", "Environment :: Web Environment", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3.6" ], "description": "# Nougat\n\n\u57fa\u4e8e Python 3.6 \u7684\u5f02\u6b65\u6846\u67b6\u3002Nougat \u4f7f\u7528\u4e2d\u95f4\u4ef6\u7684\u5f62\u5f0f\u6765\u5904\u7406\u903b\u8f91\u3002\n\n![PyPI](https://img.shields.io/pypi/pyversions/nougat.svg) ![PyPI](https://img.shields.io/pypi/status/nougat.svg) ![PyPI](https://img.shields.io/pypi/v/nougat.svg) ![PyPI](https://img.shields.io/pypi/l/nougat.svg) [![Build Status](https://travis-ci.org/Kilerd/nougat.svg?branch=master)](https://travis-ci.org/Kilerd/nougat)\n\n## \u5b89\u88c5\n\nNougat \u76ee\u524d\u4ec5\u652f\u6301 Python3.6\uff0c\u6240\u4ee5\u4f60\u53ef\u4ee5\u901a\u8fc7 PYPI \u6765\u5b89\u88c5\uff1a\n\n```bash\npip3 install nougat # or pip install nougat\n```\n\n\u6216\u8005\u4f60\u53ef\u4ee5\u901a\u8fc7 pipenv \u6765\u5b89\u88c5(\u63a8\u8350)\uff1a\n\n```bash\npipenv install nougat\n```\n\n### \u5f00\u53d1\u7248\u672c\n\n\u5982\u679c\u4f60\u60f3\u4f7f\u7528 Nougat \u7684\u65b0\u7279\u6027\uff0c\u53ef\u4ee5\u9009\u62e9\u4f7f\u7528\u5f00\u53d1\u7248\u672c\u3002**\u6ce8\u610f\u8fd9\u540c\u65f6\u4e5f\u610f\u5473\u7740\u6846\u67b6\u4f1a\u5b58\u5728\u7740\u66f4\u591a\u7684BUG** \uff1a\n\n```bash\npip3 install git@github.com:Kilerd/nougat.git@develop\n```\n\n### Uvloop \u652f\u6301\n\nNougat \u4f9d\u8d56\u4e8e asyncio\uff0c\u6240\u4ee5\u5982\u679c\u4f60\u6253\u7b97\u628a Nougat \u8fd0\u884c\u5728 Linux \u4e0a\uff0c\u53ef\u4ee5\u9009\u62e9\u4f7f\u7528\u66f4\u597d\u7684\u5f02\u6b65\u5e93\u6765\u8fd0\u884c\n\n\u9996\u5148\u5b89\u88c5 `uvloop`:\n\n```bash\npip3 install uvloop\n```\n\n\u7136\u540e\u5728\u9879\u76ee\u4e2d\u6dfb\u52a0\u4ee5\u4e0b\u4ee3\u7801\u4ee5\u4f7f\u7528 uvloop:\n\n```python\nimport asyncio\nimport uvloop\nasyncio.set_event_loop_policy(uvloop.EventLoopPolicy())\n```\n\n## \u5feb\u901f\u4e0a\u624b\n\n```python\nfrom nougat import Nougat\n\napp = Nougat()\n\nasync def middleware(response):\n\n response.content = 'Hello world'\n\napp.use(middleware)\napp.run()\n```\n\n\u4e0a\u8ff0\u4ee3\u7801\u63cf\u8ff0\u4e86 Nougat \u7684\u6700\u57fa\u672c\u4f7f\u7528\u8fc7\u7a0b\uff1a\n\n- \u5f15\u7528 `Nougat` \u7c7b\n- \u5b9a\u4e49\u4e2d\u95f4\u4ef6\n- \u628a\u4e2d\u95f4\u4ef6\u5012\u5165\u5230 `Nougat` \u4e2d\n- \u8fd0\u884c `Nougat`\n\n### Nougat \u7c7b\n\n\u6846\u67b6\u4e2d\u6700\u91cd\u8981\u7684\u4fbf\u662f Nougat \u7c7b\u3002\u5b83\u50a8\u5b58\u4e86\u6240\u6709\u6ce8\u518c\u7684\u4e2d\u95f4\u4ef6\u548c\u4fe1\u53f7\u5904\u7406\u51fd\u6570\uff0c\u540c\u65f6\u7528\u4e8e\u542f\u52a8\u548c\u505c\u6b62\u670d\u52a1\u5668\n\n```\napp = Nougat()\n```\n\n\u5728 Nougat \u7c7b\u4e2d\uff0c\u6700\u91cd\u8981\u7684\u4fbf\u662f\u6ce8\u518c\u4e2d\u95f4\u4ef6\u548c\u6dfb\u52a0\u4fe1\u53f7\u5904\u7406\u51fd\u6570\n\n#### \u6ce8\u518c\u4e2d\u95f4\u4ef6 `app.use(middleware...)`\n\n`use` \u65b9\u6cd5\u53ef\u4ee5\u540c\u65f6\u4f20\u5165\u591a\u4e2a\u4e2d\u95f4\u4ef6\uff0c\u6ce8\u518c\u987a\u5e8f\u8ddf\u4f20\u5165\u987a\u5e8f\u4e00\u81f4\n\n```python\nasync def one_middleware():\n pass\n\nasync def another_middleware(response):\n response.content = 'Hello World'\n\napp.use(one_middleware)\napp.use(one_middleware, another_middleware)\n```\n\n\u7ea6\u5b9a\u7684\u4e2d\u95f4\u4ef6\u5fc5\u987b\u662f\u5f02\u6b65\u51fd\u6570\uff0c\u540c\u65f6\u53ef\u9009\u7684\u53c2\u6570\u6709\u56db\u4e2a\uff1a`app`, `request`, `response`, `next` \u3002\u53c2\u6570\u90fd\u662f\u53ef\u9009\u7684\uff0c\u53ef\u6839\u636e\u81ea\u5df1\u7684\u9700\u6c42\u9009\u62e9\n\n\u5177\u4f53\u7684\u4e2d\u95f4\u4ef6\u5b9a\u4e49\u548c\u6267\u884c\u6d41\u7a0b\u5728\u4e0b\u6587\u4f1a\u7ee7\u7eed\u63cf\u8ff0\n\n### \u914d\u7f6e\n\nNougat \u7c7b\u4e2d\u7684 `config` \u53d8\u91cf\u7528\u4e8e\u7ba1\u7406\u914d\u7f6e\u4fe1\u606f\n\n#### \u4ece Python \u5bf9\u8c61\u4e2d\u8bfb\u53d6\u914d\u7f6e\u4fe1\u606f\n\n`app.config` \u4e2d\u6709\u4e00\u4e2a\u65b9\u6cd5`load_from_object(object_name)` \u7528\u4e8e\u8bfb\u53d6\u6307\u5b9a\u5bf9\u8c61\u4e2d\u6240\u6709\u7684\u5927\u5199\u5b57\u6bcd\u7ec4\u6210\u7684\u53d8\u91cf\n\n```\nclass DefaultConfig:\n UPPER_WORD = 1\n normal = 2\n\napp.config.load_from_object(DefaultConfig)\n```\n\n\u5728\u8fd9\u4e2a\u4f8b\u5b50\u4e2d\uff0c`UPPER_WORD`\u4f1a\u88ab\u52a0\u8f7d\u8fdb\u914d\u7f6e`app.config`\u4e2d\uff0c\u4f46\u662f`normal` \u4e0d\u4f1a\n\n#### \u8bbf\u95ee\u914d\u7f6e\u4fe1\u606f\n\n`app.config` \u4e2d\u7684\u4fe1\u606f\u53ef\u4ee5\u901a\u8fc7 `object` \u7684\u65b9\u5f0f\u8bbf\u95ee\uff0c\u4e5f\u53ef\u4ee5\u901a\u8fc7`dict`\u7684\u65b9\u5f0f\u8bbf\u95ee\uff1a\n\n- \u5bf9\u8c61\u8bbf\u95ee\u65b9\u5f0f: `app.config.UPPER_WORD`\n- \u5b57\u5178\u8bbf\u95ee\u65b9\u5f0f: `app.config['UPPER_WORD']`\n\n\u6211\u4eec\u63a8\u8350\u4f7f\u7528\u5bf9\u8c61\u8bbf\u95ee\u65b9\u5f0f\uff0c\u56e0\u4e3a Nougat \u5728\u5904\u7406\u4e0d\u5b58\u5728\u7684\u4fe1\u606f\u65f6\uff0c\u4f1a\u8fd4\u56de`None`\uff0c\u800c\u4e0d\u4f1a\u62a5\u9519\n\n\u5982\u679c\u4f60\u6267\u610f\u8981\u7528\u5b57\u5178\u8bbf\u95ee\u65b9\u5f0f\uff0c\u8bf7\u4f7f\u7528`app.config.get(\"UPPER_WORD\", None)`\u6765\u907f\u514d\u89e6\u53d1 KeyError \u5f02\u5e38\n\n### \u4e2d\u95f4\u4ef6\n\n\u5728 Nougat \u4e2d\uff0c\u4e2d\u95f4\u4ef6\u5fc5\u987b\u662f\u4e00\u4e2a\u5f02\u6b65\u51fd\u6570\uff08\u6216\u8005\u5728\u7c7b\u4e2d\u5b9e\u73b0`async def __call__` \u65b9\u6cd5\uff09\uff0c\u540c\u65f6\u53c2\u6570\u53ea\u80fd\u5148\u5b9a\u5728`app`, `request`, `response`, `next` \u91cc\u9762\uff0c\u6309\u9700\u5b9a\u4e49\n\n```Python\nasync def middleware(app, request, response, next):\n # doing before request\n await next()\n # doing after after\n```\n\n- `app` \u4e3a `Nougat` \u7684\u5b9e\u4f8b\n- `request` \u4e3a `Request` \u5b9e\u4f8b\uff0c\u5f53\u524d\u8bf7\u6c42\u4e0a\u4e0b\u6587\u7684\u8bf7\u6c42\u5bf9\u8c61\n- `response` \u4e3a `Response`\u5b9e\u4f8b\uff0c\u5f53\u524d\u8bf7\u6c42\u4e0a\u4e0b\u6587\u7684\u54cd\u5e94\u5bf9\u8c61\n- `next` \u4e3a\u4e2d\u95f4\u4ef6\u94fe\u7684\u4e0b\u4e00\u4e2a\u4e2d\u95f4\u4ef6\uff0c\u7ecf\u7531\u5305\u88c5\u540e\u7684\u65e0\u53c2\u6570\u65b9\u6cd5\uff0c\u53ef\u76f4\u63a5`await next() ` \u8c03\u7528\n\n**\u6ce8\u610f\uff0c\u4e3a\u4e86\u53ef\u4ee5\u5f97\u5230\u66f4\u597d\u7684\u4ee3\u7801\u63d0\u793a\uff0c\u5efa\u8bae\u5728\u7f16\u5199\u4e2d\u95f4\u4ef6\u53c2\u6570\u65f6\uff0c\u4f7f\u7528 Type Hints\u3002 `async def middleware(app: Nougat, request: Request, response: Response, next)`**\n\n```python\nasync def middleware(app, request, next):\n if request.headers.get('Authentication'):\n print('get user token')\n await next()\n\napp.use(middleware)\n```\n\n\u4e0a\u8ff0\u4e2d\u95f4\u4ef6\u4f7f\u7528\u4e86\u4e09\u4e2a\u53c2\u6570\uff0c\u5e76\u6ca1\u6709\u4f7f\u7528\u5230`response`\n\n\u6216\u8005\uff0c\u6211\u4eec\u53ef\u4ee5\u7f16\u5199\u4e00\u4e2a\u7c7b\u4f5c\u4e3a\u4e2d\u95f4\u4ef6\n\n```python\nclass Middleware:\n\n async def __call__(next): \n await next()\n\napp.use(Middleware())\n```\n\n#### \u4e2d\u95f4\u4ef6\u6267\u884c\u987a\u5e8f\n\n```\n\n\n Request\n + ^\n | |\n +------|-----------------|-------+\n | | | |\n | | middleware 1 | |\n | | | |\n +------|-----------------|-------+\n | |\n +------|-----------------|-------+\n | | | |\n | | middleware 2 | |\n | | | |\n +------|-----------------|-------+\n | |\n | |\n +-----------------+\n```\n\n`await next()` \u628a\u4e00\u4e2a\u4e2d\u95f4\u4ef6\u5206\u6210\u4e24\u4e2a\u90e8\u5206\uff08\u5f53\u627e\u4e0d\u5230\u8be5\u8bed\u53e5\u65f6\uff0c\u6574\u4e2a\u4e2d\u95f4\u4ef6\u9ed8\u8ba4\u88ab\u7406\u89e3\u4e3a\u4e0a\u534a\u90e8\u5206\uff09\uff0cNougat \u5728\u5904\u7406\u4e2d\u95f4\u4ef6\u65f6\uff0c\u4f1a\u6b63\u5411\u5904\u7406\u4e2d\u95f4\u4ef6\u94fe\u7684\u4e0a\u534a\u90e8\u5206\uff0c\u9006\u5411\u5904\u7406\u4e0b\u534a\u90e8\u5206\n\n```python\nv = []\nasync def m1(next):\n v.append(1)\n await next()\n v.append(2)\n\nasync def m2(next):\n v.append(3)\n await next()\n v.append(4)\n\napp.use(m1, m2)\n```\n\n\u5f53\u7ecf\u5386\u8fc7\u4e00\u6b21HTTP\u8bf7\u6c42\u540e\uff0cv\u7684\u5185\u5bb9\u4e3a`[1, 3, 4, 2]` \n\n#### \u8bb0\u5f55\u5904\u7406\u65f6\u95f4\u7684\u4f8b\u5b50\n\n```Python\nasync def logging_time(response, next):\n start_time = time()\n await next()\n process_time = time() - start_time\n response.set_header(\"Time\": \"{}s\".format(process_time))\n```\n\n### \u4fe1\u53f7\n\n\u4fe1\u53f7\u7528\u4e8e Nougat \u670d\u52a1\u5668\u542f\u52a8\u524d\u540e\u5904\u7406\u7684\u4e8b\u60c5\uff0c\u4f8b\u5982\u5efa\u7acb\u6570\u636e\u5e93\u8fde\u63a5\uff0c\u6570\u636e\u7684\u9884\u5904\u7406\u7b49\u7b49\n\n\u76ee\u524d\uff0cNougat \u53ea\u652f\u6301\u4e24\u79cd\u4fe1\u53f7\uff0c\u542f\u52a8\u670d\u52a1\u5668\u524d\u4fe1\u53f7 `before_start` \u548c \u5173\u95ed\u670d\u52a1\u5668\u540e\u4fe1\u53f7`after_start`\n\n```python\n@app.signal('before_start')\nasync def handle(app):\n pass\n```\n\n\u4f7f\u7528 `app.signal` \u88c5\u9970\u5668\u53ef\u4ee5\u5b8c\u6210\u8be5\u5de5\u4f5c\uff0c\u53c2\u6570\u4e3a\u4fe1\u53f7\u503c\u3002 \u88c5\u9970\u5668\u51fd\u6570\u53ef\u4ee5\u4e3a\u5f02\u6b65\u51fd\u6570\uff0c\u4e5f\u53ef\u4ee5\u4e3a\u666e\u901a\u51fd\u6570\u3002\u53c2\u6570\u4e3a `app`\uff0c\u5176\u7c7b\u578b\u4e3a Nougat \u7c7b\u7684\u5b9e\u4f8b\n\n\u4fe1\u53f7\u7684\u5177\u4f53\u5e94\u7528\u8bf7\u81ea\u884c\u60f3\u8c61\n\n## \u9ad8\u7ea7\u4f7f\u7528\u8bf4\u660e\n\n### \u8bf7\u6c42\u7c7b Request\n\nRequest \u7c7b\u7528\u4e8e\u50a8\u5b58 HTTP \u8bf7\u6c42\u7684\u76f8\u5173\u4fe1\u606f\n\n#### request.method\nHTTP \u8bbf\u95ee\u65b9\u6cd5\uff0c\u4e3a\u5927\u5199\u5b57\u7b26\u4e32 `GET`, `POST` \u7b49\n#### request.version\nHTTP \u534f\u8bae\u7248\u672c\n#### request.url\n\nHTTP \u8bf7\u6c42\u7684URL\uff0c\u4e3a `yarl.URL` \u5b9e\u4f8b\uff0c\u4ee5\u4e0b\u662f\u4e00\u4e9b\u64cd\u4f5c\u5b9e\u4f8b\n\n```Python\nurl = yarl.URL(\"https://example.com/foo/bar?hello=world\")\nprint(url.host) # example.com\nprint(url.path) # /foo/bar\nprint(url.query) # \nprint(url.query.get('hello')) # world\n```\n\n#### request.content_type\nHTTP \u7684 `Content-Type`\n\n#### request.query\n`request.url.query` \u7684\u5feb\u6377\u8bbf\u95ee\u65b9\u5f0f\n#### request.form\nHTTP \u975e GET \u65b9\u6cd5\u4e2d FORM \u6570\u636e\u50a8\u5b58\u3002\n\n#### request.ip\nHTTP \u8bbf\u95ee\u8005\u7684 IP\n#### request.headers\nHTTP \u8bf7\u6c42\u5934\u90e8\u4fe1\u606f\n#### request.cookies\nHTTP \u8bf7\u6c42\u7684 Cookies\n\n### \u54cd\u5e94\u7c7b Response\n\n#### response.code = \n\n\u54cd\u5e94\u7684HTTP CODE\uff0c \u9ed8\u8ba4\u4e3a 200\n\n#### response.status = \n\u5bf9\u5e94HTTP CODE\u7684\u6587\u672c\u4fe1\u606f\uff0c200 \u5bf9\u5e94 OK\uff0c\u9ed8\u8ba4\u4f1a\u4ece\u8868\u4e2d\u67e5\u8be2\u51fa\u9ed8\u8ba4\u503c\u3002\n\n#### response.content =\n\n\u54cd\u5e94\u5185\u5bb9\n\n#### response.type = \n\u54cd\u5e94\u5185\u5bb9\u7684\u7c7b\u578b\uff0c\u9ed8\u8ba4\u4e3a`text/html`\n\n#### response.charset =\n\u54cd\u5e94\u5185\u5bb9\u7684\u7f16\u7801\uff0c\u9ed8\u8ba4\u4e3a `utf-8`\n\n#### response.set_header(key, value)\n\u6dfb\u52a0\u54cd\u5e94\u5934\n#### response.set_cookies(self, name, value, expires=None, domain=None, path=None, secure=False, http_only=False, same_site=None)\n\u6dfb\u52a0 Cookie\n - `name`: \u540d\u5b57\n - `value`: \u503c\n - `expires`: \u8fc7\u671f\u65f6\u95f4\uff0c\u5355\u4f4d\u79d2\n\n### \u7528HttpException\u4e2d\u65ad\u4e2d\u95f4\u4ef6\u94fe\n\n\u5728\u4e2d\u95f4\u4ef6\u5904\u7406\u4e1a\u52a1\u903b\u8f91\u65f6\uff0c\u5728\u67d0\u4e9b\u60c5\u51b5\u4e0b\uff0c\u6211\u4eec\u5e0c\u671b\u63d0\u524d\u4e2d\u65ad\u4e2d\u95f4\u4ef6\u94fe\u7684\u6267\u884c\uff0c\u4f8b\u5982\u5f53\u7528\u6237\u8ba4\u8bc1\u5931\u8d25\u65f6\uff0c\u76f4\u63a5\u8fd4\u56de HTTP 401 Unauthorized\u3002 Nougat \u63d0\u4f9b\u4e86`nougat.exceptions.HttpException` \u6765\u5b9e\u73b0\u8fd9\u4e2a\u529f\u80fd\n\n```python\nasync def login_required(request, next):\n if request.headers.get('Authentication'):\n ...\n if not is_auth:\n raise HttpException(401, 'you need to login first')\n ... \n```\n\n`HttpException` \u63a5\u53d7\u4e24\u4e2a\u53c2\u6570\uff1a\n\n- `code` HTTP CODE\n- `body` HTTP \u54cd\u5e94\u5185\u5bb9\n\n### \u5982\u4f55\u5199\u5355\u5143\u6d4b\u8bd5\n\nNougat \u63d0\u4f9b\u4e86\u4e00\u4e2a\u975e\u5e38\u65b9\u4fbf\u7684\u5e93\uff0c\u7528\u4e8e\u6267\u884c\u5355\u5143\u6d4b\u8bd5\u3002\u5f53\u7136\u4e86\uff0c\u6211\u4eec\u4f9d\u8d56\u4e8e`pytest` \u548c `pytest-asyncio` \u6765\u63d0\u4f9b\u57fa\u7840\u914d\u4ef6\n\n```python\nimport pytest\nfrom app import app\nfrom nougat import TestClient\n\n@pytest.mark.asyncio\nasync def test_app(unused_tcp_port):\n # doing before test\n\n async with TestClient(app, unused_tcp_port) as client:\n res = await client.get('/')\n assert res.text == 'Hello world'\n```\n\n## \u76f8\u5173\u5e94\u7528\n\n- [Nougat Router](https://github.com/Kilerd/nougat-router) \u4e00\u4e2a\u9002\u7528\u4e8e Restful API \u5e76\u4e14\u5e26\u53c2\u6570\u683c\u5f0f\u5316\u7684\u8def\u7531\u5668\n- [Nougat Utils](https://github.com/Kilerd/nougat-utils) \u63d0\u4f9b\u4e86 CLI \u652f\u6301\u548c\u8c03\u8bd5\u6a21\u5f0f\u7b49\u9002\u7528\u4e8e\u5f00\u53d1\u65f6\u7684\u5de5\u5177\u5e93\n\n## \u5f00\u6e90\u534f\u8bae\n\n\u672c\u9879\u76ee\u4f7f\u7528 MIT \u5f00\u6e90\uff0c\u8be6\u60c5\u8bf7\u67e5\u770b [LICENSE](https://github.com/NougatWeb/nougat/blob/master/LICENSE) \u6587\u4ef6\n\n", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/Kilerd/nougat", "keywords": "web framework async", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "nougat", "package_url": "https://pypi.org/project/nougat/", "platform": "", "project_url": "https://pypi.org/project/nougat/", "project_urls": { "Homepage": "https://github.com/Kilerd/nougat" }, "release_url": "https://pypi.org/project/nougat/0.3.3/", "requires_dist": [ "aiohttp", "httptools", "yarl (>=0.13.0)", "websockets" ], "requires_python": ">=3.6", "summary": "Async web framework", "version": "0.3.3" }, "last_serial": 3964953, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "e870bb6c2a8845d2012337aca93fc41a", "sha256": "20c0e6a0c0e458ce001c557db3d2ab4b50cbb8c3ae4c703ab83ffaf23e9b2803" }, "downloads": -1, "filename": "nougat-0.1.0.tar.gz", "has_sig": false, "md5_digest": "e870bb6c2a8845d2012337aca93fc41a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11392, "upload_time": "2017-05-25T11:19:34", "url": "https://files.pythonhosted.org/packages/12/a7/da5c7132fc34103cda0e2a2bbf37bdf0ca2bf313979cfbd4264b9f1e89b2/nougat-0.1.0.tar.gz" } ], "0.1.0a1": [ { "comment_text": "", "digests": { "md5": "dcc3244afa3680829d8319cc973d3941", "sha256": "b7df63d62506c6ae7129b37026ade1fecfbb52aa5adf77a2dcdb0cec3805c18e" }, "downloads": -1, "filename": "nougat-0.1.0a1.tar.gz", "has_sig": false, "md5_digest": "dcc3244afa3680829d8319cc973d3941", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11206, "upload_time": "2017-05-25T13:05:26", "url": "https://files.pythonhosted.org/packages/04/eb/3e390c0e9a4b0c2e2bd26c02d64d4836237c016b5be38a6a30c6af21444a/nougat-0.1.0a1.tar.gz" } ], "0.1.0a2": [ { "comment_text": "", "digests": { "md5": "61f31882680a25781d2a51fb551ef7d1", "sha256": "d1a295c52f01a7dda4d52f942c5f7a9bb4e99608986c07d96e050d5664946849" }, "downloads": -1, "filename": "nougat-0.1.0a2.tar.gz", "has_sig": false, "md5_digest": "61f31882680a25781d2a51fb551ef7d1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11193, "upload_time": "2017-06-01T15:42:06", "url": "https://files.pythonhosted.org/packages/2a/b4/2788647fe995e9894633f1db0e266c82cb3b38e8ba1b9ee4a0e341cb229f/nougat-0.1.0a2.tar.gz" } ], "0.1.1a1": [ { "comment_text": "", "digests": { "md5": "677f04666245a408973b2f4ca226012e", "sha256": "d0340dbb137cb066f9777da8ec056a7a91728ddde94bf4c20bfff550992e7f9d" }, "downloads": -1, "filename": "nougat-0.1.1a1.tar.gz", "has_sig": false, "md5_digest": "677f04666245a408973b2f4ca226012e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12016, "upload_time": "2017-06-23T15:44:07", "url": "https://files.pythonhosted.org/packages/ed/22/288b92e99a2647a7d507c48e15e32381f9bec2523d8edded330c9b422ec4/nougat-0.1.1a1.tar.gz" } ], "0.2.0": [ { "comment_text": "", "digests": { "md5": "64e979624a9ae10b3c898f122ed93a95", "sha256": "b1477e480cf78ba02f34d99f643eb47b44efb7de239d7ecb04233c30b3cec6ca" }, "downloads": -1, "filename": "nougat-0.2.0-py3-none-any.whl", "has_sig": false, "md5_digest": "64e979624a9ae10b3c898f122ed93a95", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 23149, "upload_time": "2017-11-05T09:07:50", "url": "https://files.pythonhosted.org/packages/f8/48/b742e08f9099dd075bc3e99b58da9ea23745dd6d3f5599bcde28859719d6/nougat-0.2.0-py3-none-any.whl" } ], "0.2.1": [ { "comment_text": "", "digests": { "md5": "bc064b041d46a40eee66dde13f852f37", "sha256": "3991504433470bd1db97801e0f4c47ac5468a43f55ca3d7d73cf2cf1e3958452" }, "downloads": -1, "filename": "nougat-0.2.1-py3-none-any.whl", "has_sig": false, "md5_digest": "bc064b041d46a40eee66dde13f852f37", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 21352, "upload_time": "2017-11-20T12:21:11", "url": "https://files.pythonhosted.org/packages/1f/4b/dd211d940cb48240344a77d091f9e2e0477d55a51145824d962bcbfe7c85/nougat-0.2.1-py3-none-any.whl" } ], "0.2.3": [ { "comment_text": "", "digests": { "md5": "66dea7b5d1c8f4e386e785c1a4dcb5b9", "sha256": "905df45b72c37efa0467cba691d22d70541a3f20a483041b6ed05a09cef8daf1" }, "downloads": -1, "filename": "nougat-0.2.3-py3-none-any.whl", "has_sig": false, "md5_digest": "66dea7b5d1c8f4e386e785c1a4dcb5b9", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 15390, "upload_time": "2018-01-01T10:00:31", "url": "https://files.pythonhosted.org/packages/06/8e/3fed7a9a6d7a809722a17281d6db03b675716fa21f962bb1e023ee6a235f/nougat-0.2.3-py3-none-any.whl" } ], "0.2.4": [ { "comment_text": "", "digests": { "md5": "32a3a6a4849c0d6eded5f7c8de38403b", "sha256": "eee4ebfe82db2867ef56ee3a90e3fca711aa82a226f89087e6b582d23bc6afd9" }, "downloads": -1, "filename": "nougat-0.2.4-py3-none-any.whl", "has_sig": false, "md5_digest": "32a3a6a4849c0d6eded5f7c8de38403b", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 11251, "upload_time": "2018-04-08T10:45:37", "url": "https://files.pythonhosted.org/packages/22/72/d135ab4a89901b0abcfe780375439db644650c01452d9786d290a44285b0/nougat-0.2.4-py3-none-any.whl" } ], "0.2.5": [ { "comment_text": "", "digests": { "md5": "efe5b620c3be6219b7d00bf1fd07ef16", "sha256": "4a174b77f6106d1b4144c4a49603868eeb2cdbea8477888c97367e7accc377ba" }, "downloads": -1, "filename": "nougat-0.2.5-py3-none-any.whl", "has_sig": false, "md5_digest": "efe5b620c3be6219b7d00bf1fd07ef16", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 17474, "upload_time": "2018-04-08T11:22:01", "url": "https://files.pythonhosted.org/packages/b0/d9/bb4e37dc1c10263947cdd52d304c27f470c707937eafd1f4e0e843d10389/nougat-0.2.5-py3-none-any.whl" } ], "0.2.5.dev1": [ { "comment_text": "", "digests": { "md5": "86d45e9fc095b0a846c3ae69c598d240", "sha256": "9f744000e615bba4c0698074cf34a60679096f78bad14fc0884e032b0b556662" }, "downloads": -1, "filename": "nougat-0.2.5.dev1-py3-none-any.whl", "has_sig": false, "md5_digest": "86d45e9fc095b0a846c3ae69c598d240", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 17534, "upload_time": "2018-04-08T11:11:30", "url": "https://files.pythonhosted.org/packages/f1/cf/8a1517a4cda2da4feada2ffb1067c2341bb61e84ae33c01429bdcb053a75/nougat-0.2.5.dev1-py3-none-any.whl" } ], "0.3.0": [ { "comment_text": "", "digests": { "md5": "df38851a78d23369b99d27d6a255c6af", "sha256": "252d436ba1fb806eb5cfc8d0c285e9ac8e99262992303211bf43f5017a156fa6" }, "downloads": -1, "filename": "nougat-0.3.0-py3-none-any.whl", "has_sig": false, "md5_digest": "df38851a78d23369b99d27d6a255c6af", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 13528, "upload_time": "2018-04-29T14:46:46", "url": "https://files.pythonhosted.org/packages/24/ec/9231b2b4354cd9e84ea57710c8254971ed099a1f74a8d560660b08b2844f/nougat-0.3.0-py3-none-any.whl" } ], "0.3.1": [ { "comment_text": "", "digests": { "md5": "f23968f11606034f1398eae9c6cd2c39", "sha256": "37e7547d90b216674abead1e170270d80f1f5013b83c3c71e7305598ef6e94ed" }, "downloads": -1, "filename": "nougat-0.3.1-py3-none-any.whl", "has_sig": false, "md5_digest": "f23968f11606034f1398eae9c6cd2c39", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 13575, "upload_time": "2018-04-30T14:32:36", "url": "https://files.pythonhosted.org/packages/5a/9b/1d485d7db0fc38ed4903f6b9518657200f9d10dca8adf31ebe1d2251fe5f/nougat-0.3.1-py3-none-any.whl" } ], "0.3.2": [ { "comment_text": "", "digests": { "md5": "c0a89b2d5085cac4df118f150fda7fa8", "sha256": "74d782844393540a7baa31c7d930b0adb5584f7b338b98e03897c1dfce6f6690" }, "downloads": -1, "filename": "nougat-0.3.2-py3-none-any.whl", "has_sig": false, "md5_digest": "c0a89b2d5085cac4df118f150fda7fa8", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 13609, "upload_time": "2018-04-30T16:03:52", "url": "https://files.pythonhosted.org/packages/0a/7f/6f4491b8ba32dec8c65f9c7b760e86b5ff670fb6ddce6e1b629cd7acbd6f/nougat-0.3.2-py3-none-any.whl" } ], "0.3.3": [ { "comment_text": "", "digests": { "md5": "79170e64605d9b3d2ca28bd37f105753", "sha256": "499c7fe5cb9b573ad9fada6c78ebbccb91cf24f72f6816f233f146e91df1f0bd" }, "downloads": -1, "filename": "nougat-0.3.3-py3-none-any.whl", "has_sig": false, "md5_digest": "79170e64605d9b3d2ca28bd37f105753", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 15211, "upload_time": "2018-06-15T13:51:06", "url": "https://files.pythonhosted.org/packages/de/62/64abcbfcace9f14f299ad5471bb8aaf9dfed675118d9f42b379641cb4bc0/nougat-0.3.3-py3-none-any.whl" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "79170e64605d9b3d2ca28bd37f105753", "sha256": "499c7fe5cb9b573ad9fada6c78ebbccb91cf24f72f6816f233f146e91df1f0bd" }, "downloads": -1, "filename": "nougat-0.3.3-py3-none-any.whl", "has_sig": false, "md5_digest": "79170e64605d9b3d2ca28bd37f105753", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 15211, "upload_time": "2018-06-15T13:51:06", "url": "https://files.pythonhosted.org/packages/de/62/64abcbfcace9f14f299ad5471bb8aaf9dfed675118d9f42b379641cb4bc0/nougat-0.3.3-py3-none-any.whl" } ] }