Metadata-Version: 2.5
Name: opacte
Version: 0.2.0
Summary: SDK Python de l'API Opacte : attester, vérifier et faire signer des documents, sans qu'ils quittent votre serveur en clair.
Project-URL: Homepage, https://opacte.eu
Project-URL: Documentation, https://opacte.eu/api
Project-URL: Contrat HTTP, https://opacte.eu/api/openapi.json
Project-URL: Tutoriel, https://opacte.eu/api-tutorial
Author: Jean-Michel ARNAUD
License-Expression: MIT
License-File: LICENSE
Keywords: attestation,bitcoin,horodatage,opacte,opentimestamps,preuve,signature électronique
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Natural Language :: French
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Security :: Cryptography
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: cryptography>=42
Requires-Dist: httpx>=0.27
Provides-Extra: dev
Requires-Dist: pytest>=8; extra == 'dev'
Requires-Dist: ruff>=0.6; extra == 'dev'
Description-Content-Type: text/markdown

# opacte — SDK Python de l'API Opacte

Attestez, vérifiez et faites signer des documents depuis votre logiciel, sans captcha ni code. Comme sur
[opacte.eu](https://opacte.eu), le document ne quitte jamais votre serveur en clair : pour une attestation, Opacte n'en
garde que les empreintes, et la preuve est ancrée dans Bitcoin ; pour une signature, le SDK le chiffre chez vous et
la clé ne vient jamais chez Opacte.

## Installation

```
pip install opacte
```

Python 3.10 ou plus. Créez un compte sur [opacte.eu](https://opacte.eu/account), puis une clé API dans **Réglages**,
et rendez-la disponible dans la variable d'environnement `OPACTE_API_KEY` (jamais dans votre code).

## Exemple

```python
from opacte import Client, CreditsInsuffisants

client = Client()  # clé lue dans OPACTE_API_KEY
print(client.compte().solde)

# Attester un fichier : 1 crédit. Envoyé en flux, lu à la volée, jamais conservé.
attestation = client.attestations.creer("facture-2026-118.pdf", email_visible=False)
print(attestation.id_attestation, attestation.url_recu)  # gardez url_recu : accès pérenne au reçu

# Vérifier un document reçu : ses empreintes sont calculées ici, le fichier ne part pas. Gratuit.
for candidate in client.verifier("document-recu.pdf"):
    print(candidate["id_attestation"], candidate["horodatage"])
```

## Faire signer

```python
circuit = client.circuits.creer(
    "contrat.pdf",
    signataires=[{"email": "lea@exemple.fr", "prenom": "Léa", "nom": "MARTIN"}],
    zones=[
        {
            "signataire": "lea@exemple.fr",
            "page": 1,
            "x": 0.6,
            "y": 0.8,
            "largeur": 0.3,
            "hauteur": 0.08,
            "type": "signature",
        }
    ],
    initiateur={"prenom": "Claire", "nom": "MOREAU"},  # si votre compte ne signe pas
)
envoyer_par_ma_messagerie(circuit.lien)  # https://opacte.eu/sign/…#k=… : Opacte ne l'envoie jamais
conserver(circuit.id_circuit, circuit.cle)  # sans la clé, personne ne relit le document signé

# plus tard : statut, puis le document signé, déchiffré ici
if client.circuits.lire(circuit.id_circuit).statut == "complet":
    pdf = client.circuits.document(circuit.id_circuit, circuit.cle)
```

1 crédit par circuit. Le SDK fait chez vous ce que fait le navigateur sur le site : contrôles, clé AES-256-GCM,
chiffrement du PDF et des zones, empreintes ; les signataires signent sur la page `/sign` d'Opacte.

## Webhooks

```python
from opacte import webhooks

hook = client.webhooks.creer("https://crm.exemple.fr/opacte", ["circuit.signature", "circuit.complet"])
SECRET = hook.secret  # whsec_… : montré une seule fois

# à la réception, sur le corps brut :
evenement = webhooks.verifier(corps, entetes["Opacte-Signature"], SECRET)  # lève SignatureInvalide
```

Événements : `attestation.definitive`, `attestation.ancree`, `circuit.signature`, `circuit.complet`,
`circuit.expire`, `circuit.annule` — identifiants, statuts et dates seulement.

## Ce que fait le SDK

- **Fichiers en flux** : un fichier à attester est envoyé par blocs, jamais chargé en entier en mémoire.
- **Chiffrement chez vous** : même format que le navigateur (AES-256-GCM, données authentifiées par circuit et par
  version) ; la clé ne figure que dans le fragment du lien, qu'aucun navigateur n'envoie au serveur.
- **Nouvelles tentatives** : sur coupure, `429` ou `5xx`, l'appel est rejoué avec la même `Idempotency-Key` : jamais
  de second débit.
- **Erreurs typées** : `CleInvalide`, `CreditsInsuffisants` (avec `solde`), `TropDeDemandes`, `Introuvable`…
- **Typé** : annotations complètes, vérifiables par votre éditeur ou mypy.

## Liens

- Documentation et référence : [opacte.eu/api](https://opacte.eu/api)
- Tutoriel : [opacte.eu/api-tutorial](https://opacte.eu/api-tutorial)
- Contrat HTTP publié (OpenAPI) : [opacte.eu/api/openapi.json](https://opacte.eu/api/openapi.json) — le SDK n'en est
  qu'une mise en forme : vous pouvez vérifier ce qu'il envoie.

Licence MIT.
