Async ACME client implementation
Project description
aioacme
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a33a79d67201df0211a74b099fcdf1e548cb2792e067b9098bcf0489dc2e56c4
|
|
| MD5 |
a9d267a72d249b89d72e44152da1f5a6
|
|
| BLAKE2b-256 |
c36ee3f18a0be504c56f95d0efe560a519e8c9213c0a4d6a99c3d159db42bd0c
|
Provenance
The following attestation bundles were made for aioacme-0.5.1.tar.gz:
Publisher:
publish.yml on tkukushkin/aioacme
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
aioacme-0.5.1.tar.gz -
Subject digest:
a33a79d67201df0211a74b099fcdf1e548cb2792e067b9098bcf0489dc2e56c4 - Sigstore transparency entry: 732755895
- Sigstore integration time:
-
Permalink:
tkukushkin/aioacme@fda57d2f643eca4a61150907123908a2addde538 -
Branch / Tag:
refs/tags/v0.5.1 - Owner: https://github.com/tkukushkin
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@fda57d2f643eca4a61150907123908a2addde538 -
Trigger Event:
release
-
Statement type:
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8fa05ce6d487b06992b700048b88d02285ba1113d95fb2d13bb96754038b2284
|
|
| MD5 |
b30fa4cbf2ed7cc0d2b01659c6e3bbd7
|
|
| BLAKE2b-256 |
63c8933c473bb3504f6d8c0d5fd364bd838033ee4a3c50fb724402554659fe07
|
Provenance
The following attestation bundles were made for aioacme-0.5.1-py3-none-any.whl:
Publisher:
publish.yml on tkukushkin/aioacme
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
aioacme-0.5.1-py3-none-any.whl -
Subject digest:
8fa05ce6d487b06992b700048b88d02285ba1113d95fb2d13bb96754038b2284 - Sigstore transparency entry: 732755901
- Sigstore integration time:
-
Permalink:
tkukushkin/aioacme@fda57d2f643eca4a61150907123908a2addde538 -
Branch / Tag:
refs/tags/v0.5.1 - Owner: https://github.com/tkukushkin
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@fda57d2f643eca4a61150907123908a2addde538 -
Trigger Event:
release
-
Statement type: