Skip to main content

lacme

CI PyPI Python License

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 -- HTTPX2 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 httpx2.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. See the changelog for release notes and upgrade guidance.

License

Apache-2.0

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.1.0.tar.gz (214.6 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.1.0-py3-none-any.whl (72.6 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: lacme-1.1.0.tar.gz
  • Upload date:
  • Size: 214.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for lacme-1.1.0.tar.gz
Algorithm Hash digest
SHA256 d633bcb07391d5155ae0ac8883fdad6f86a89abfc3f0ee71ad44042ec11b63a8
MD5 081336f86e0677da1f9f8d3a988a8da4
BLAKE2b-256 128e7025a9f54f349fa564e59e8cd9ac6839d7071bcc592037f793f9a82bfced

See more details on using hashes here.

Provenance

The following attestation bundles were made for lacme-1.1.0.tar.gz:

Publisher: publish.yml on turnstonelabs/lacme

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

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

File metadata

  • Download URL: lacme-1.1.0-py3-none-any.whl
  • Upload date:
  • Size: 72.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for lacme-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 293774ec625bb03b5c3a443f679970396f89845bdc9af9013ffff2375f9f1116
MD5 d298d23cf86d90eafc74bb88740cb47e
BLAKE2b-256 db24e35353deb4cc4e449f953a8937e59f4810545d3284a06522cd340bde2a90

See more details on using hashes here.

Provenance

The following attestation bundles were made for lacme-1.1.0-py3-none-any.whl:

Publisher: publish.yml on turnstonelabs/lacme

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

1.2.0

2 files

1.1.1

2 files

This release

1.1.0 This release

2 files

1.0.5

2 files

1.0.4

2 files

1.0.3

2 files

1.0.2

2 files

1.0.1

2 files

1.0.0

2 files

Supported by

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