{ "info": { "author": "Matt Cooper", "author_email": "vtbassmatt@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 3 - Alpha", "Environment :: Web Environment", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3.6", "Topic :: Internet :: WWW/HTTP :: WSGI", "Topic :: Internet :: WWW/HTTP :: WSGI :: Server" ], "description": "# azf-wsgi - WSGI apps on Azure Functions\n\nAn adapter package to let you run WSGI apps (Django, Flask, etc.) on Azure Functions.\n\nExample:\n```python\nimport azure.functions as func\n\n# note that the package is \"azf-wsgi\" but the import is \"azf_wsgi\"\nfrom azf_wsgi import AzureFunctionsWsgi\n# Django, for example, but works with any WSGI app\nfrom my_django_app.wsgi import application\n\n\ndef main(req: func.HttpRequest, context: func.Context) -> func.HttpResponse:\n return AzureFunctionsWsgi(application).main(req, context)\n```\n\n## Usage\n\n### Install Azure Functions\nFollow the instructions [here](https://docs.microsoft.com/azure/azure-functions/functions-create-first-function-python) to get set up locally.\nI created a Function called \"DjangoTrigger\", but you can call yours whatever.\n\n### Install your WSGI app\nI found it's easiest if you package your WSGI app using a setup.py script, then `pip install` it.\nIf you don't want to do that, you'll have to make sure your WSGI entrypoint is importable from the module where you define your Azure Function.\nI'm no Python imports expert, so I just added `sys.path.insert(0, './my_proj')` right before I try to import the package.\n\n### Install this package\n`pip install azf-wsgi` - no need to put this in Django's `INSTALLED_APPS` or anything like that.\nBe sure to update `requirements.txt` to include `azf-wsgi` as a requirement.\n\n### Configure Azure Functions to hand off to your WSGI app\nFirst, we want to delegate routing to your WSGI app. Edit your `function.json` to include a catch-all route called \"{*route}\":\n\n```json\n{\n \"scriptFile\": \"__init__.py\",\n \"bindings\": [\n {\n \"authLevel\": \"anonymous\",\n \"type\": \"httpTrigger\",\n \"direction\": \"in\",\n \"name\": \"req\",\n \"methods\": [\n \"get\",\n \"post\"\n ],\n \"route\": \"app/{*route}\"\n },\n {\n \"type\": \"http\",\n \"direction\": \"out\",\n \"name\": \"$return\"\n }\n ]\n}\n```\n\nI also didn't want the default 'api/' path on all my routes, so I fixed my `host.json` to look like this:\n\n```json\n{\n \"version\": \"2.0\",\n \"extensions\": {\n \"http\": {\n \"routePrefix\": \"\"\n }\n }\n}\n```\n\nWithout this configuration, the only paths your WSGI app would ever see would start with \"api/\\/\".\nThat works, but it would require you to repeat those boilerplate prefixes on every route you configured.\n**However**, you don't want to completely take over all routes (by having an empty `routePrefix` _and_ a catch-all route in your function) because this disables important Azure machinery.\n\nFinally, setup your Function's `__init__.py` to delegate to the WSGI adapter:\n\n```python\nimport azure.functions as func\n\nfrom azf_wsgi import AzureFunctionsWsgi\nfrom my_django_app.wsgi import application\n\n\ndef main(req: func.HttpRequest) -> func.HttpResponse:\n return AzureFunctionsWsgi(application).main(req)\n```\n\nThe adapter optionally takes the `Context` object as well:\n\n```python\ndef main(req: func.HttpRequest, context: func.Context) -> func.HttpResponse:\n return AzureFunctionsWsgi(application).main(req, context)\n```\n\n\nThe adapter will stuff in the OS's environment block much like a CGI request. If for some reason you don't want that, you can pass `False` to `include_os_environ`:\n\n```python\ndef main(req: func.HttpRequest, context: func.Context) -> func.HttpResponse:\n return AzureFunctionsWsgi(application, False).main(req, context)\n```\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/vtbassmatt/azf-wsgi", "keywords": "", "license": "", "maintainer": "", "maintainer_email": "", "name": "azf-wsgi", "package_url": "https://pypi.org/project/azf-wsgi/", "platform": "", "project_url": "https://pypi.org/project/azf-wsgi/", "project_urls": { "Homepage": "https://github.com/vtbassmatt/azf-wsgi" }, "release_url": "https://pypi.org/project/azf-wsgi/0.3.0/", "requires_dist": [ "azure-functions" ], "requires_python": "", "summary": "Azure Functions WSGI implementation", "version": "0.3.0" }, "last_serial": 4858926, "releases": { "0.1": [ { "comment_text": "", "digests": { "md5": "1b730fffb0f1d8ab224d64b527f19392", "sha256": "10992476ba0f60f7d21ec0e488b461f97a5982ce29a15d6b7e2566e7576eeef2" }, "downloads": -1, "filename": "azf_wsgi-0.1-py3-none-any.whl", "has_sig": false, "md5_digest": "1b730fffb0f1d8ab224d64b527f19392", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 4904, "upload_time": "2018-12-26T13:28:46", "url": "https://files.pythonhosted.org/packages/7c/a4/eabe1f6677dcbb947450a8cf97eb3a5bf3227f23e3a3ce7d3238cc11906b/azf_wsgi-0.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "0d044eb657c4afa59abd3671ec180d27", "sha256": "2db88b8c4c70c938b4bec70edc0651dc9ff1eecfc80607a5a1c3cdd01f450268" }, "downloads": -1, "filename": "azf-wsgi-0.1.tar.gz", "has_sig": false, "md5_digest": "0d044eb657c4afa59abd3671ec180d27", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 3589, "upload_time": "2018-12-26T13:28:48", "url": "https://files.pythonhosted.org/packages/a4/b1/1ce30adba5e0e8d41bc5b2120713d42819ecce2b1e1ad9f01bd227eac7f6/azf-wsgi-0.1.tar.gz" } ], "0.1.1": [ { "comment_text": "", "digests": { "md5": "45f680e64573dd2b69c50c531a6106e6", "sha256": "1f116e99b910cf1d3ee03bb2aaceb9ad818b1734161dd25835e15152a832dced" }, "downloads": -1, "filename": "azf_wsgi-0.1.1-py3-none-any.whl", "has_sig": false, "md5_digest": "45f680e64573dd2b69c50c531a6106e6", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 5045, "upload_time": "2018-12-28T22:38:23", "url": "https://files.pythonhosted.org/packages/ff/2a/39c8c8f26c91ce70487b944356fe39e09d89dae65d076a0c233ef390dd66/azf_wsgi-0.1.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "db493d5ad491fd340c4a1193b55e1e04", "sha256": "a6d3e392636210d177d39c599c90935dd38c45d5608b89f83f64a55e4a48c76c" }, "downloads": -1, "filename": "azf-wsgi-0.1.1.tar.gz", "has_sig": false, "md5_digest": "db493d5ad491fd340c4a1193b55e1e04", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 3724, "upload_time": "2018-12-28T22:38:24", "url": "https://files.pythonhosted.org/packages/28/8a/c836bc915b12eb30dcca216208f621f8b7894d913cf6061b31723badf420/azf-wsgi-0.1.1.tar.gz" } ], "0.1.2": [ { "comment_text": "", "digests": { "md5": "e66a6cc2d34845e28800b1c1048fae2c", "sha256": "ce8fa8a21286e71038073307462a9cdaab4709b372afebaa82e0d146d1891ef8" }, "downloads": -1, "filename": "azf_wsgi-0.1.2-py3-none-any.whl", "has_sig": false, "md5_digest": "e66a6cc2d34845e28800b1c1048fae2c", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 5064, "upload_time": "2018-12-28T22:46:40", "url": "https://files.pythonhosted.org/packages/f9/a9/516a935f17dd1c202d7e0dc77d56eb1175f7c1c5893bfc1f2281b8550758/azf_wsgi-0.1.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "0d0d0b3d510ae3a685968e8f7dbde35e", "sha256": "5a7378315d2d3b775cc52086e19c1adf0e67fa1e9d9d157754035745cd7004e5" }, "downloads": -1, "filename": "azf-wsgi-0.1.2.tar.gz", "has_sig": false, "md5_digest": "0d0d0b3d510ae3a685968e8f7dbde35e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 3742, "upload_time": "2018-12-28T22:46:41", "url": "https://files.pythonhosted.org/packages/7a/9e/c8ca32d95d77bd1060ab12eeb00777401dfd26c08110911fdf06af338042/azf-wsgi-0.1.2.tar.gz" } ], "0.1.3": [ { "comment_text": "", "digests": { "md5": "a837a5eff0e34a3d6f5c192473b10f77", "sha256": "47feef1e883c3a721f35b7b4b022df263ae58b0cd3b08891876da2b0685ca3b7" }, "downloads": -1, "filename": "azf_wsgi-0.1.3-py3-none-any.whl", "has_sig": false, "md5_digest": "a837a5eff0e34a3d6f5c192473b10f77", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 5085, "upload_time": "2018-12-28T22:51:11", "url": "https://files.pythonhosted.org/packages/ac/8e/c179c1d4e3261e1a3374f042761773a236ec0d3c99f5e15cd789f9af6ee4/azf_wsgi-0.1.3-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "cfd32fe2613f05132c794f57c1483204", "sha256": "68155f72eb285312fd5e1bd0f8b25609106563356c5f5ce9020a0df9d3f03d41" }, "downloads": -1, "filename": "azf-wsgi-0.1.3.tar.gz", "has_sig": false, "md5_digest": "cfd32fe2613f05132c794f57c1483204", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 3766, "upload_time": "2018-12-28T22:51:12", "url": "https://files.pythonhosted.org/packages/67/71/68633ea29e5ab997174895994daf3a49c4d792154cd2ffd503890d8930c9/azf-wsgi-0.1.3.tar.gz" } ], "0.2.0": [ { "comment_text": "", "digests": { "md5": "1b714345d905a189bea236e02e59051f", "sha256": "a371f30098af373d2cded646ad8b3627e043d8d60f19352104c52d8b5fcdb6c5" }, "downloads": -1, "filename": "azf_wsgi-0.2.0-py3-none-any.whl", "has_sig": false, "md5_digest": "1b714345d905a189bea236e02e59051f", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 5101, "upload_time": "2018-12-28T23:10:22", "url": "https://files.pythonhosted.org/packages/8b/c9/deeee7f67ec21fe18fa1bb4896caee186992769dbee2d53860b46666dcd8/azf_wsgi-0.2.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "918de3df3b8c9dc6a24065b74799ba8b", "sha256": "50a7f41454a02c0f0058fc66d016486a0912b29bd0dede81b5e7d40a1f88e263" }, "downloads": -1, "filename": "azf-wsgi-0.2.0.tar.gz", "has_sig": false, "md5_digest": "918de3df3b8c9dc6a24065b74799ba8b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 3778, "upload_time": "2018-12-28T23:10:23", "url": "https://files.pythonhosted.org/packages/d2/c6/7399436a7ccd4da34092e042707a2e587c06235e20cf86352bad3cd5928e/azf-wsgi-0.2.0.tar.gz" } ], "0.3.0": [ { "comment_text": "", "digests": { "md5": "c30f5cf411802a033c4c7ce74effd0d0", "sha256": "d1254ff4a74c19a7ff71369d4c6c51e40947475857b4349a315c70cc88341837" }, "downloads": -1, "filename": "azf_wsgi-0.3.0-py3-none-any.whl", "has_sig": false, "md5_digest": "c30f5cf411802a033c4c7ce74effd0d0", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 5179, "upload_time": "2019-02-23T18:31:23", "url": "https://files.pythonhosted.org/packages/63/22/5988edeb38ad523936de1b13a130ac4fe7335b808f593c91c9512436c908/azf_wsgi-0.3.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "84e77e34219c3d783841803f1e7c5d67", "sha256": "c63dcb841222065ef979ba054bcdbdd185e8c91f3d06749ab62be178c806ac0e" }, "downloads": -1, "filename": "azf-wsgi-0.3.0.tar.gz", "has_sig": false, "md5_digest": "84e77e34219c3d783841803f1e7c5d67", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 3854, "upload_time": "2019-02-23T18:31:25", "url": "https://files.pythonhosted.org/packages/d6/72/ca30e6062f3a79643c265dd9aa8e2e3a4317ea5b3d082a5a55dc92c722f2/azf-wsgi-0.3.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "c30f5cf411802a033c4c7ce74effd0d0", "sha256": "d1254ff4a74c19a7ff71369d4c6c51e40947475857b4349a315c70cc88341837" }, "downloads": -1, "filename": "azf_wsgi-0.3.0-py3-none-any.whl", "has_sig": false, "md5_digest": "c30f5cf411802a033c4c7ce74effd0d0", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 5179, "upload_time": "2019-02-23T18:31:23", "url": "https://files.pythonhosted.org/packages/63/22/5988edeb38ad523936de1b13a130ac4fe7335b808f593c91c9512436c908/azf_wsgi-0.3.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "84e77e34219c3d783841803f1e7c5d67", "sha256": "c63dcb841222065ef979ba054bcdbdd185e8c91f3d06749ab62be178c806ac0e" }, "downloads": -1, "filename": "azf-wsgi-0.3.0.tar.gz", "has_sig": false, "md5_digest": "84e77e34219c3d783841803f1e7c5d67", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 3854, "upload_time": "2019-02-23T18:31:25", "url": "https://files.pythonhosted.org/packages/d6/72/ca30e6062f3a79643c265dd9aa8e2e3a4317ea5b3d082a5a55dc92c722f2/azf-wsgi-0.3.0.tar.gz" } ] }