Skip to main content

ASGI Middleware for serving Static File.

Project description

ASGIMiddlewareStaticFile

GitHub Pytest Workflow Status codecov Code style: black PyPI - Downloads

ASGI Middleware for serving static file.

Why?

ASGIMiddlewareStaticFile is a solution when we need to distribute the whole project with static files in Docker; when the deployment environment has very limited resources.

Features

  • Standard ASGI middleware implement
  • Async file IO
  • Support ETag(base on md5(file_size + last_modified) )

Install

pip3 install -U ASGIMiddlewareStaticFile

Usage

Pure ASGI

Code demo_pure_asgi.py

import os
from asgi_middleware_static_file import ASGIMiddlewareStaticFile

BASE_DIR = os.path.dirname(__name__)
STATIC_DIRS = [os.path.join(BASE_DIR, 'demo_static')]


async def app(scope, receive, send):
  assert scope['type'] == 'http'

  await send({
    'type': 'http.response.start',
    'status': 200,
    'headers': [
      [b'content-type', b'text/plain'],
    ],
  })
  await send({
    'type': 'http.response.body',
    'body': b'Hello, world!',
  })


app = ASGIMiddlewareStaticFile(
  app, static_url='static', static_root_paths=STATIC_DIRS
)

Run Server

(venv)   asgi-middleware-static-file git:(master)  uvicorn demo_pure_asgi:app
INFO:     Started server process [21061]
INFO:     Waiting for application startup.
INFO:     ASGI 'lifespan' protocol appears unsupported.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO:     127.0.0.1:54529 - "GET /static/DEMO HTTP/1.1" 200 OK

Run wget

(venv)   asgi-middleware-static-file git:(master)  wget http://127.0.0.1:8000/static/DEMO
--2021-01-11 19:54:24--  http://127.0.0.1:8000/static/DEMO
正在连接 127.0.0.1:8000... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度:26 []
正在保存至: “DEMO.6”

DEMO.6                        100%[==============================================>]      26  --.-KB/s  用时 0s

2021-01-11 19:54:24 (540 KB/s) - 已保存 “DEMO.6” [26/26])

Django

Update file example/django_example/django_example/asgi.py

"""
ASGI config for django_example project.
It exposes the ASGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/3.1/howto/deployment/asgi/
"""

import os

from django.conf import settings
from django.core.asgi import get_asgi_application
from asgi_middleware_static_file import ASGIMiddlewareStaticFile

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'django_example.settings')

application = get_asgi_application()
application = ASGIMiddlewareStaticFile(
  application, static_url=settings.STATIC_URL,
  static_root_paths=[settings.STATIC_ROOT]
)

Do't forget execute

python manage.py collectstatic
133 static files copied to '/Users/rex/p/asgi-middleware-static-file/example/django_example/staticfiles'.

Run server

uvicorn django_example.asgi:application
INFO:     Started server process [93869]
INFO:     Waiting for application startup.
INFO:     ASGI 'lifespan' protocol appears unsupported.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO:     127.0.0.1:61925 - "GET /static/DEMO.txt HTTP/1.1" 200 OK

Quart (Flask like)

Code demo_quart.py

import os

from quart import Quart
from asgi_middleware_static_file import ASGIMiddlewareStaticFile

BASE_DIR = os.path.dirname(__name__)
STATIC_DIRS = [os.path.join(BASE_DIR, 'demo_static')]

app = Quart(__name__)


@app.route('/')
async def hello():
  return 'hello'


app = ASGIMiddlewareStaticFile(
  app, static_url='static', static_root_paths=STATIC_DIRS
)

Run Server

(venv)   asgi-middleware-static-file git:(master)  uvicorn demo_quart:app        
INFO:     Started server process [22289]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO:     127.0.0.1:56191 - "GET / HTTP/1.1" 200 OK
INFO:     127.0.0.1:56212 - "GET /static/DEMO HTTP/1.1" 200 OK

Run wget

(venv)   asgi-middleware-static-file git:(master)  wget http://127.0.0.1:8000/static/DEMO
--2021-01-11 20:17:46--  http://127.0.0.1:8000/static/DEMO
正在连接 127.0.0.1:8000... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度:26 []
正在保存至: “DEMO.7”

DEMO.7                        100%[==============================================>]      26  --.-KB/s  用时 0s

2021-01-11 20:17:46 (1.46 MB/s) - 已保存 “DEMO.7” [26/26])

Alternative

TODO

  • zero copy
  • file extension filter,
  • Cache Control

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ASGIMiddlewareStaticFile-0.3.2.tar.gz (7.7 kB view details)

Uploaded Source

Built Distribution

ASGIMiddlewareStaticFile-0.3.2-py2.py3-none-any.whl (6.6 kB view details)

Uploaded Python 2 Python 3

File details

Details for the file ASGIMiddlewareStaticFile-0.3.2.tar.gz.

File metadata

  • Download URL: ASGIMiddlewareStaticFile-0.3.2.tar.gz
  • Upload date:
  • Size: 7.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.7.1 importlib_metadata/4.10.0 pkginfo/1.8.2 requests/2.27.1 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.9.9

File hashes

Hashes for ASGIMiddlewareStaticFile-0.3.2.tar.gz
Algorithm Hash digest
SHA256 abd1032b38b9ccb26d9217a3c4c2203bb12be2f80ba198b4758a3dff8cb840b8
MD5 4dda02948eee73ae84d0f978dead2fc6
BLAKE2b-256 715a861d3fd7ef4e572bf41b18abb29a58280d55485ebcd5fa9305127f367acb

See more details on using hashes here.

File details

Details for the file ASGIMiddlewareStaticFile-0.3.2-py2.py3-none-any.whl.

File metadata

  • Download URL: ASGIMiddlewareStaticFile-0.3.2-py2.py3-none-any.whl
  • Upload date:
  • Size: 6.6 kB
  • Tags: Python 2, Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.7.1 importlib_metadata/4.10.0 pkginfo/1.8.2 requests/2.27.1 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.9.9

File hashes

Hashes for ASGIMiddlewareStaticFile-0.3.2-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 edd5cf8e6d0a9c80d4488cce9876e653b6559e40f16eb30c8a07ee175ab81d84
MD5 2e5f2a1948320cb2e50f9c1ee9f92ef3
BLAKE2b-256 7531d76b9a1d5141cf6f7177a4af99e2f154daee13238a2bdb9a6e0c6d604537

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page