Embed Python in NGINX, supporting ASGI, WSGI.
Wsgi tested with Django application.
Asgi tested with Starlette application.
forked from https://github.com/decentfox/nginxpy
- Free software: Apache Software License 2.0
- Documentation: https://nginxpy.readthedocs.io.
Overview
- Standard Python package with Cython extension
- Automatically build into NGINX dynamic module for current NGINX install
- Run embeded Python in NGINX worker processes
- Write NGINX modules in Python or Cython
- Python
logging
module redirected to NGINXerror.log
- (ongoing) NGINX event loop wrapped as Python
asyncio
interface - (ongoing) Asgi support. Currently can run some simple app. More works needs to be done to support full featured asgi application. currently file reading is blocking, next step is to implement asynchronious reading in thread pool.
- (ongoing) WSGI support by WSGI to ASGI adapting. Run wsgi app in thread pool.
- (ongoing) fix memory leak and add more test.
- (TBD) websocket support for asgi and wsgi.
- (TBD) socket support for event loop
- (TBD) Python and Cython interface to most NGINX code
- Install NGINX in whatever way, make sure
nginx
command is available. pip install nginxpy
, or get the source and runpip install .
. You may want to add the-v
option, because the process is a bit slow downloading Cython, NGINX source code and configuring it. The usualpython setup.py install
currently doesn't work separately - you should runpython setup.py build
first.- Run
python -c 'import nginx'
to get NGINX configuration hint. - Update NGINX configuration accordingly and reload NGINX.
- Visit your NGINX site, see NGINX
error.log
for now.
By example configuration:
http {
# python_path specifies pathes to search from (PYTHONPATH), before python initinallization.
# if not specified, the default PYTHONPATH is used
python_path "/usr/lib/python3.6:/usr/lib/python3.6/lib-dynload";
# currently only support thread pool
python_executor "type=thread workers=10";
server {
listen 80;
location / {
# same as openresty's content_by_xx. handle request by asgi app
# by default asgi version 3
asgi_pass asgi_helloworld:app;
# asgi_pass asgi_helloworld:app2 2; asgi version 2
}
location /wsgi {
# wsgi application, workers: number of workers in pool; type: thread or process
wsgi_pass wsgi_app:wsgi;
}
}
}
The asgi_helloworld app:
import asyncio
async def app(scope, recevie, send):
data = await recevie()
await send({
"type": "http.response.start",
"status":200,
"headers": []
})
await send({
"type": "http.response.body",
"body": b"Hello World!\n" str(data).encode() b"\n",
"more_body": True
})
await asyncio.sleep(5)
await send({
"type": "http.response.body",
"body": str(scope).encode()
})
The wsgi app:
def wsgi(env, start_response):
start_response('200 OK', [('Content-Type','text/plain')])
return [b"Hello World\n" str(env).encode()]
- Install NGINX in whatever way, make sure
nginx
command is available. - Checkout source code.
- Run
python setup.py build && python setup.py develop
. - Run
python -c 'import nginx'
to get NGINX configuration hint. - Update NGINX configuration accordingly and reload NGINX.
- Visit your NGINX site, see NGINX
error.log
for now. - Change code if result is not satisfying, or else go for pull request.
- Goto 3 if Cython code was changed, or else goto 5.
Surprisingly NGINX has a very simple but powerful architecture, learn about it here: http://nginx.org/en/docs/dev/development_guide.html
This package was created with Cookiecutter and the audreyr/cookiecutter-pypackage project template.