{"id":22203325,"url":"https://github.com/archmonger/servestatic","last_synced_at":"2026-04-02T22:45:51.942Z","repository":{"id":247900026,"uuid":"827047439","full_name":"Archmonger/ServeStatic","owner":"Archmonger","description":"Production-grade static file server for Python web apps.","archived":false,"fork":false,"pushed_at":"2024-10-30T00:39:05.000Z","size":2427,"stargazers_count":20,"open_issues_count":6,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-10-30T02:52:19.720Z","etag":null,"topics":["asgi","django","http","http-server","static","staticfiles","wsgi"],"latest_commit_sha":null,"homepage":"https://archmonger.github.io/ServeStatic/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Archmonger.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":".github/SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["archmonger"],"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":null}},"created_at":"2024-07-10T23:17:09.000Z","updated_at":"2024-10-28T22:23:41.000Z","dependencies_parsed_at":"2024-07-11T07:57:32.059Z","dependency_job_id":"80b0bb5a-0a3d-4b0a-b8f8-a364414467a2","html_url":"https://github.com/Archmonger/ServeStatic","commit_stats":null,"previous_names":["archmonger/servestatic"],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Archmonger%2FServeStatic","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Archmonger%2FServeStatic/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Archmonger%2FServeStatic/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Archmonger%2FServeStatic/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Archmonger","download_url":"https://codeload.github.com/Archmonger/ServeStatic/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":227765998,"owners_count":17816704,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["asgi","django","http","http-server","static","staticfiles","wsgi"],"created_at":"2024-12-02T16:48:49.538Z","updated_at":"2026-04-02T22:45:51.931Z","avatar_url":"https://github.com/Archmonger.png","language":"Python","readme":"\u003c!--desc-start--\u003e\n\n# ServeStatic\n\n\u003cp\u003e\n    \u003ca href=\"https://github.com/Archmonger/ServeStatic/actions?query=workflow%3ACI+branch%3Amain\"\u003e\n        \u003cimg src=\"https://github.com/Archmonger/ServeStatic/actions/workflows/ci.yml/badge.svg\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://pypi.python.org/pypi/servestatic\"\u003e\n        \u003cimg src=\"https://img.shields.io/pypi/v/servestatic.svg?label=PyPI\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://github.com/Archmonger/ServeStatic/blob/main/LICENSE.md\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/License-MIT-purple.svg\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://archmonger.github.io/ServeStatic/\"\u003e\n        \u003cimg alt=\"Website\" src=\"https://img.shields.io/website?url=https%3A%2F%2Farchmonger.github.io%2FServeStatic%2F\u0026up_message=online\u0026logo=readthedocs\u0026logoColor=white\u0026label=docs\"\u003e\n    \u003c/a\u003e\n\u003c/p\u003e\n\n_Production-grade static file server for Python WSGI \u0026 ASGI._\n\n_This project is a [fork](https://github.com/evansd/whitenoise/pull/359#issuecomment-2226889088) of [WhiteNoise](https://github.com/evansd/whitenoise) for [ASGI support, bug fixes, security updates, new features, and performance upgrades](https://archmonger.github.io/ServeStatic/latest/changelog/)._\n\n---\n\n`ServeStatic` simplifies static file serving with minimal lines of configuration. It enables you to create a self-contained unit without requiring external services like Nginx or Amazon S3. This can simplify any production deployment, but is especially useful for platforms like Heroku, OpenShift, and other PaaS providers.\n\nIt is designed to work seamlessly with CDNs to ensure high performance for traffic-intensive sites. It can be run in \"standalone\" mode, or alongside any preexisting ASGI/WSGI app. A command-line interface is provided to perform common tasks such as multi-format compression, file-name hashing, and manifest generation. Extra features and auto-configuration are available for [Django](https://www.djangoproject.com/) users.\n\nWhen using `ServeStatic`, best practices are automatically handled such as:\n\n- Automatically serving compressed content\n- Proper handling of `Accept-Encoding` and `Vary` headers\n- Setting far-future cache headers for immutable static files.\n\nVisit the [documentation](https://archmonger.github.io/ServeStatic/) to get started or learn more about `ServeStatic` .\n\n## Frequently Asked Questions\n\n### Isn't serving static files from Python horribly inefficient?\n\nThe short answer to this is that if you care about performance and efficiency then you should be using `ServeStatic` behind a CDN (such as CloudFront). Due to the caching headers `ServeStatic` sends, the vast majority of static requests will be served directly by the CDN without touching your application, so it really doesn't make much difference how efficient `ServeStatic` is.\n\nThat said, `ServeStatic` is pretty efficient. Because it only has to serve a fixed set of files it does all the work of finding files and determining the correct headers upfront on initialization. Requests can then be served with little more than a dictionary lookup to find the appropriate response. Also, when used with gunicorn (and most other WSGI servers) the actual business of pushing the file down the network interface is handled by the kernel's very efficient `sendfile` syscall, not by Python.\n\n### Shouldn't I be pushing my static files to S3 (using Django-Storages)?\n\nNo, you shouldn't. The main problem with this approach is that Amazon S3 cannot currently selectively serve compressed content to your users. Compression using gzip, zstd (Python 3.14+), or brotli can make dramatic reductions in load time and bandwidth usage. But, in order to do this correctly the server needs to examine the `Accept-Encoding` header of the request to determine which compression formats are supported, and return an appropriate `Vary` header so that intermediate caches know to do the same. This is exactly what `ServeStatic` does, but Amazon S3 currently provides no means of doing this.\n\nThe second problem with a push-based approach to handling static files is that it adds complexity and fragility to your deployment process: extra libraries specific to your storage backend, extra configuration and authentication keys, and extra tasks that must be run at specific points in the deployment in order for everything to work. With the CDN-as-caching-proxy approach that `ServeStatic` takes there are just two bits of configuration: your application needs the URL of the CDN, and the CDN needs the URL of your application. Everything else is just standard HTTP semantics. This makes your deployments simpler, your life easier, and you happier.\n\n### What's the point in `ServeStatic` when I can use `apache`/`nginx`?\n\nThere are two answers here. One is that ServeStatic is designed to work in situations where `apache`, `nginx`, and the like aren't easily available. But more importantly, it's easy to underestimate what's involved in serving static files correctly. Does your few lines of nginx configuration distinguish between files which might change and files which will never change and set the cache headers appropriately? Did you add the right CORS headers so that your fonts load correctly when served via a CDN? Did you turn on the special nginx setting which allows it to send gzip content in response to an `HTTP/1.0` request? Did you install, enable, and configure support for zstd and brotli compression?\n\nNone of this is rocket science, but it's fiddly and annoying and `ServeStatic` takes care of all it for you.\n\n\u003c!--desc-end--\u003e\n","funding_links":["https://github.com/sponsors/archmonger"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farchmonger%2Fservestatic","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Farchmonger%2Fservestatic","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farchmonger%2Fservestatic/lists"}