Skip to main content

Modern, async-native Python ACME client library for embedding TLS certificate automation.

Project description

lacme

CI Python 3.11+ License: Apache-2.0

Modern, async-native Python ACME client library for embedding TLS certificate automation.

What is lacme?

lacme fills the gap between full-featured CLI tools like certbot (not designed for embedding) and low-level ACME protocol libraries that leave orchestration to you. It provides a high-level Client.issue() one-liner alongside full access to every step of the ACME workflow. lacme has just two runtime dependencies -- httpx and cryptography -- and supports Python 3.11+.

Features

  • Async-native with sync wrapper -- Client for asyncio, SyncClient for blocking code
  • HTTP-01 and DNS-01 challenges -- built-in handlers with pluggable DNS providers (Cloudflare, Route 53, shell hooks)
  • Built-in Certificate Authority -- CertificateAuthority for issuing private CA certs, ideal for mTLS
  • ACME Responder -- ACMEResponder ASGI app backed by the built-in CA for internal PKI
  • Framework integrations -- first-class support for Starlette, FastAPI, and Uvicorn
  • CLI tool -- lacme issue, lacme renew, lacme revoke from the command line
  • Auto-renewal -- RenewalManager runs in the background and re-issues expiring certificates
  • Rate limit tracking -- client-side awareness of Let's Encrypt rate limits with warnings and blocking
  • Event system + Prometheus metrics -- EventDispatcher with typed events; optional MetricsCollector
  • MockACMEServer for testing -- in-process mock ACME server via httpx.MockTransport

Quick Start

pip install lacme
import asyncio
from lacme import Client
from lacme.challenges.http01 import HTTP01Handler

async def main():
    handler = HTTP01Handler()
    async with Client(
        directory_url="https://acme-v02.api.letsencrypt.org/directory",
        contact="mailto:you@example.com",
        challenge_handler=handler,
    ) as client:
        server = await handler.start_server()  # port 80
        bundle = await client.issue("example.com")
        server.close()
        await server.wait_closed()
    print(bundle.fullchain_pem.decode())

asyncio.run(main())

Private CA / mTLS

from lacme import CertificateAuthority, client_ssl_context, server_ssl_context

ca = CertificateAuthority()
ca.init()

server_cert = ca.issue("myservice.internal")
client_cert = ca.issue("worker-1", client=True)

server_ctx = server_ssl_context(
    cert_pem=server_cert.fullchain_pem,
    key_pem=server_cert.key_pem,
    ca_cert_pem=ca.root_cert_pem,  # require client certs
)
client_ctx = client_ssl_context(
    cert_pem=client_cert.cert_pem,
    key_pem=client_cert.key_pem,
    ca_cert_pem=ca.root_cert_pem,
)

CLI

# Issue a certificate via Let's Encrypt staging
lacme --staging --contact you@example.com issue example.com

# Renew all certificates expiring within 30 days
lacme renew --days 30

# Revoke a certificate
lacme revoke example.com

Documentation

Full documentation is available at turnstonelabs.github.io/lacme.

License

Apache-2.0

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

lacme-1.0.0.tar.gz (192.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

lacme-1.0.0-py3-none-any.whl (66.1 kB view details)

Uploaded Python 3

File details

Details for the file lacme-1.0.0.tar.gz.

File metadata

  • Download URL: lacme-1.0.0.tar.gz
  • Upload date:
  • Size: 192.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.18 {"installer":{"name":"uv","version":"0.9.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"25.10","id":"questing","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for lacme-1.0.0.tar.gz
Algorithm Hash digest
SHA256 df603bee78d87e989c037481d3d1008a4e1d7e447895bae9d0ddace6fcfb2c66
MD5 94c5c106223d304246863eca843937d7
BLAKE2b-256 5059fdc851415f17854df65d5a6b02c0ffbfdfda50593cac6fa9078d61de7841

See more details on using hashes here.

File details

Details for the file lacme-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: lacme-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 66.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.18 {"installer":{"name":"uv","version":"0.9.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"25.10","id":"questing","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for lacme-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1ee7736eccd33bef536941b30817c516e1f4f8194cf8f1ac68e115afbe11800f
MD5 365c5bb6c103a14c89910aa5f4a12d8b
BLAKE2b-256 626ed2a235fd31af7646481397170676471da648ed83a3a0a99a186b78ffab93

See more details on using hashes here.

Supported by

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