Serving HTTPS
Pass a certificate and its private key. Uvicorn builds the SSLContext from the ssl_* parameters, all listed in the parameters reference. In most production setups a reverse proxy terminates TLS instead.
import uvicorn
if __name__ == "__main__":
uvicorn.run(
"app.main:app",
host="0.0.0.0",
port=8443,
ssl_keyfile="./ssl/key.pem",
ssl_certfile="./ssl/cert.pem",
ssl_keyfile_password=None, # set it if the key is encrypted
)
Client Certificates (Mutual TLS)
Require clients to present a certificate signed by your CA with ssl_cert_reqs and ssl_ca_certs.
import ssl
import uvicorn
if __name__ == "__main__":
uvicorn.run(
"app.main:app",
host="0.0.0.0",
port=8443,
ssl_keyfile="./ssl/key.pem",
ssl_certfile="./ssl/cert.pem",
ssl_cert_reqs=ssl.CERT_REQUIRED, # reject clients without a valid certificate
ssl_ca_certs="./ssl/client-ca.pem", # CA that signed the client certificates
)
Custom SSL Context
Since uvicorn 0.47.0, ssl_context_factory covers what the ssl_* parameters can't: a minimum TLS version, custom SSLContext.options, certificates loaded from memory. It receives the Config and a default factory that builds the usual context. The factory runs in each worker process, so with reload or workers it must be picklable (a top-level function, not a lambda).
import ssl
from collections.abc import Callable
import uvicorn
from uvicorn.config import Config
# Must be a top-level function so it can be pickled with reload/workers
def ssl_context_factory(config: Config, default_ssl_context_factory: Callable[[], ssl.SSLContext]) -> ssl.SSLContext:
context = default_ssl_context_factory() # built from the ssl_* parameters
context.minimum_version = ssl.TLSVersion.TLSv1_3
return context
if __name__ == "__main__":
uvicorn.run(
"app.main:app",
ssl_keyfile="./ssl/key.pem",
ssl_certfile="./ssl/cert.pem",
ssl_context_factory=ssl_context_factory,
)
Experimental HTTP/2
Since uvicorn 0.53.0, the zttp HTTP implementation can serve HTTP/2 with http2=True. Each connection is served as HTTP/1.1 or HTTP/2 depending on what the client speaks. Uvicorn 0.54.0 added response trailers and 103 Early Hints (needs zttp>=0.0.34). Upgrade-based h2c and WebSockets over HTTP/2 are not supported, and it is not ready for production traffic yet.
# pip install "uvicorn" "zttp>=0.0.34"
import uvicorn
if __name__ == "__main__":
uvicorn.run(
"app.main:app",
http="zttp", # experimental, not for production traffic yet
http2=True, # serves HTTP/1.1 and HTTP/2, depending on the client
)