Skip to main content

Async ACME client implementation

Project description

aioacme

PyPI - Status PyPI PyPI - Python Version PyPI - License CI Status codecov docs

Simple async client for ACME protocol.

Installation

pip install aioacme

Usage

Issue certificate with DNS-01 challenge:

import asyncio

import aioacme
from cryptography import x509
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import ec, rsa

async def main():
    account_key = serialization.load_pem_private_key(...)
    
    async with aioacme.Client(
        account_key=account_key, 
        directory_url=aioacme.LETS_ENCRYPT_STAGING_DIRECTORY
    ) as client:
        order = await client.new_order([aioacme.Identifier("example.com")])
        
        for authorization_uri in order.authorizations:
            authorization = await client.get_authorization(authorization_uri)
            
            if authorization.status is aioacme.AuthorizationStatus.valid:
                # authorization reused
                continue
            
            challenge = next(
                c for c in authorization.challenges if c.type is aioacme.ChallengeType.dns01
            )
            
            domain = client.get_dns_challenge_domain(authorization.identifier.value)
            validation = client.get_dns_challenge_validation(challenge.token)
            
            print(f"Please add TXT record {domain} with the following content: {validation}")
            input("Press Enter when TXT record is created")
            
            await client.answer_challenge(challenge.url)
            
            while authorization.status not in (
                aioacme.AuthorizationStatus.valid,
                aioacme.AuthorizationStatus.invalid
            ):
                await asyncio.sleep(1)
                authorization = await client.get_authorization(authorization_uri)
            
            if authorization.status is aioacme.AuthorizationStatus.invalid:
                raise Exception(f"Authorization status is invalid: {authorization}")
            
        key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
        csr = (
            x509.CertificateSigningRequestBuilder()
            .subject_name(x509.Name([
                x509.NameAttribute(x509.NameOID.COMMON_NAME, "example.com")
            ]))
            .add_extension(x509.SubjectAlternativeName([
                x509.DNSName("example.com")
            ]), critical=False)
            .sign(key, hashes.SHA256())
        )
        order = await client.finalize_order(order.finalize, csr)
        
        while order.status not in {aioacme.OrderStatus.valid, aioacme.OrderStatus.invalid}:
            await asyncio.sleep(1)
            order = await client.get_order(order.uri)
            
        if order.status is aioacme.OrderStatus.invalid:
            raise Exception(f"Order status is invalid: {order}")
        
        cert = await client.get_certificate(order.certificate)
        print(cert.decode("ascii"))
        
        
asyncio.run(main())

License

This project is licensed under the MIT License - see the LICENSE file for details.

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

aioacme-0.5.1.tar.gz (81.1 kB view details)

Uploaded Source

Built Distribution

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

aioacme-0.5.1-py3-none-any.whl (14.6 kB view details)

Uploaded Python 3

File details

Details for the file aioacme-0.5.1.tar.gz.

File metadata

  • Download URL: aioacme-0.5.1.tar.gz
  • Upload date:
  • Size: 81.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for aioacme-0.5.1.tar.gz
Algorithm Hash digest
SHA256 a33a79d67201df0211a74b099fcdf1e548cb2792e067b9098bcf0489dc2e56c4
MD5 a9d267a72d249b89d72e44152da1f5a6
BLAKE2b-256 c36ee3f18a0be504c56f95d0efe560a519e8c9213c0a4d6a99c3d159db42bd0c

See more details on using hashes here.

Provenance

The following attestation bundles were made for aioacme-0.5.1.tar.gz:

Publisher: publish.yml on tkukushkin/aioacme

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

File details

Details for the file aioacme-0.5.1-py3-none-any.whl.

File metadata

  • Download URL: aioacme-0.5.1-py3-none-any.whl
  • Upload date:
  • Size: 14.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for aioacme-0.5.1-py3-none-any.whl
Algorithm Hash digest
SHA256 8fa05ce6d487b06992b700048b88d02285ba1113d95fb2d13bb96754038b2284
MD5 b30fa4cbf2ed7cc0d2b01659c6e3bbd7
BLAKE2b-256 63c8933c473bb3504f6d8c0d5fd364bd838033ee4a3c50fb724402554659fe07

See more details on using hashes here.

Provenance

The following attestation bundles were made for aioacme-0.5.1-py3-none-any.whl:

Publisher: publish.yml on tkukushkin/aioacme

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

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