Skip to content

Documentation SDK Python ​

SDK Python async moderne pour l'API Sharokey avec nommage des méthodes cohérent avec le CLI. Parfait pour les applications Python, projets de science des données et scripts d'automatisation.

🚀 Démarrage Rapide ​

Installation ​

bash
pip install sharokey

Ou avec poetry :

bash
poetry add sharokey

Configuration de Base ​

python
import asyncio
import sharokey

async def main():
    # Initialiser le client (équivalent à : sharokey config --token xxx)
    client = sharokey.SharokeyClient('YOUR_API_KEY')
    
    # Tester la connexion
    await client.test_connection()
    print("Connecté avec succès !")

# Exécuter la fonction async
asyncio.run(main())

Premier Secret ​

python
import asyncio
import sharokey

async def create_first_secret():
    client = sharokey.SharokeyClient('YOUR_API_KEY')
    
    # Créer un secret simple (syntaxe style CLI)
    secret = await client.create(
        "Mon premier secret",  # contenu
        24,                    # heures
        1                      # vues
    )
    
    print(f"URL du Secret : {secret.share_url}")
    print(f"Slug du Secret : {secret.slug}")
    print(f"Expire le : {secret.expires_at}")

asyncio.run(create_first_secret())

⚙️ Configuration du Client ​

Options du Constructeur ​

python
import sharokey

# Configuration basique
client = sharokey.SharokeyClient('YOUR_API_KEY')

# Avec toutes les options
client = sharokey.SharokeyClient(
    token='YOUR_API_KEY',              # Requis : Token d'authentification API
    api_url="https://api.sharokey.com/api/v1", # Optionnel : URL API personnalisée
    timeout=30                           # Optionnel : Timeout des requêtes en secondes
)

🔐 Créer des Secrets ​

Création de Secret Basique ​

python
# Secret texte simple (équivalent CLI : sharokey create "contenu" --hours 24 --views 3)
secret = await client.create(
    "Mot de passe base de données : secret123",
    hours=24,
    views=3
)

print(f"URL de Partage : {secret.share_url}")

Avec Description et Protection ​

python
# Avec options de protection supplémentaires
secret = await client.create(
    "Données financières sensibles",
    hours=48,
    views=5,
    description="Accès rapport financier T4",
    password="ProtectionSupplementaire2024!",
    otp_email="[email protected]"
)

print(f"Secret créé avec protection par mot de passe et OTP")
print(f"URL de Partage : {secret.share_url}")
print(f"A un mot de passe : {secret.has_password}")
print(f"A un OTP : {secret.has_otp}")

Limitation OTP

Les OTP par email et SMS sont mutuellement exclusifs - vous ne pouvez en utiliser qu'un par secret.

Avec Pièces Jointes ​

Le SDK Python accepte les chemins de fichiers pour les pièces jointes :

python
# Pièce jointe unique
secret = await client.create(
    "Documents contractuels",
    hours=168,  # 1 semaine
    views=5,
    description="Documents légaux pour révision",
    attachments=["contrat.pdf"]
)

# Pièces jointes multiples
secret = await client.create(
    "Livrables du projet",
    hours=72,   # 3 jours
    views=3,
    description="Fichiers finaux du projet",
    attachments=[
        "specifications.docx",
        "wireframes.pdf", 
        "schema_base_donnees.sql"
    ]
)

print(f"Secret créé avec {secret.attachment_count} pièces jointes")

Limites des pièces jointes : 10 fichiers maximum, 10 Mo au total

Exemple de Protection Complète ​

python
# Toutes les options de protection
secret = await client.create(
    "Données de fusion hautement confidentielles",
    hours=72,
    views=2,
    description="Documents M&A pour révision du conseil",
    password="ConseilAdministration2024!",
    otp_email="[email protected]",
    attachments=[
        "term_sheet.pdf",
        "due_diligence.xlsx",
        "avis_juridique.docx"
    ]
)

print(f"Secret hautement protégé créé :")
print(f"- URL de Partage : {secret.share_url}")
print(f"- Expire : {secret.expires_at}")
print(f"- Vues max : {secret.maximum_views}")
print(f"- Pièces jointes : {secret.attachment_count}")
print(f"- A un mot de passe : {secret.has_password}")
print(f"- A un OTP : {secret.has_otp}")

📝 Gestion des Secrets ​

Lister les Secrets ​

python
# Listage basique (équivalent CLI : sharokey list)
secrets = await client.list()

for secret in secrets:
    print(f"{secret.slug}: {secret.description} ({secret.status})")

# Avec filtres et pagination
filtered_secrets = await client.list(
    limit=20,
    status='active',
    creator='[email protected]'
)

print(f"Trouvé {len(filtered_secrets)} secrets actifs")

Fonctionnalité de Recherche ​

python
# Rechercher dans les descriptions et le contenu
results = await client.list(status='active', limit=100)
search_term = "base de données"
matching_secrets = [s for s in results if search_term.lower() in (s.description or '').lower()]

print(f"Trouvé {len(matching_secrets)} secrets contenant '{search_term}'")

Détails d'un Secret ​

python
# Obtenir par slug (équivalent CLI : sharokey get ABC123)
secret = await client.get('ABC123XYZ')

print(f"Détails du secret :")
print(f"- Description : {secret.description}")
print(f"- Statut : {secret.status}")
print(f"- Créé : {secret.created_at}")
print(f"- Expire : {secret.expires_at}")
print(f"- Vues restantes : {secret.remaining_views}/{secret.maximum_views}")
print(f"- A un mot de passe : {secret.has_password}")
print(f"- A un OTP : {secret.has_otp}")
print(f"- Nombre de pièces jointes : {secret.attachment_count}")

Supprimer des Secrets ​

python
# Supprimer un secret unique (équivalent CLI : sharokey delete ABC123)
await client.delete('ABC123XYZ')
print("Secret supprimé avec succès")

# Supprimer plusieurs secrets
slugs_to_delete = ['ABC123', 'DEF456', 'GHI789']
for slug in slugs_to_delete:
    try:
        await client.delete(slug)
        print(f"Supprimé {slug}")
    except sharokey.NotFoundError:
        print(f"Secret {slug} non trouvé")

🔧 Fonctions Utilitaires ​

Génération de Mots de Passe ​

python
# Générer un mot de passe sécurisé (équivalent CLI : sharokey generate-password)
password = await client.generate_password()
print(f"Mot de passe généré : {password}")  # 16 caractères par défaut

# Longueur personnalisée (8-32 caractères)
long_password = await client.generate_password(length=24)
print(f"Mot de passe long : {long_password}")

# Générer un mot de passe et créer un secret en un appel
password_secret = await client.create_password(
    length=20,
    hours=24,
    views=1,
    description="Nouveau mot de passe admin",
    otp_email="[email protected]"
)

print(f"Mot de passe généré : {password_secret.generated_password}")
print(f"URL de Partage : {password_secret.share_url}")

Test de Connectivité ​

python
# Tester la connectivité API (équivalent CLI : sharokey test)
try:
    is_connected = await client.test_connection()
    if is_connected:
        print("✅ Connexion API réussie")
        
        # Obtenir des informations de connexion supplémentaires
        print(f"URL API : {client.api_url}")
        print(f"Token configuré : {'Oui' if client.token else 'Non'}")
except Exception as error:
    print(f"❌ Échec de connexion : {error}")

Statistiques ​

python
# Obtenir les statistiques du compte (équivalent CLI : sharokey stats)
stats = await client.stats()

print("📊 Statistiques du Compte :")
print(f"- Total des secrets : {stats.total_secrets}")
print(f"- Secrets actifs : {stats.active_secrets}")
print(f"- Total des vues : {stats.total_views}")
print(f"- Stockage utilisé : {stats.storage_used / 1024 / 1024:.1f} Mo")

📧 Demandes de Secret ​

Demander à d'autres personnes de partager des secrets avec vous de manière sécurisée via des URL de demande générées.

Créer une Demande de Secret ​

python
# Demande de secret de base
request = await client.create_request(
    message="Veuillez partager les identifiants de base de données",
    description="Accès DB de production nécessaire"
)

print(f"Demande créée : {request.url}")
print(f"Envoyez cette URL au destinataire : {request.url}")

# Avec temps d'expiration et limites de vues
request = await client.create_request(
    message="Partager config VPN",
    description="Configuration accès distant",
    secret_expiration_hours=24,  # Le secret expirera dans 24h
    request_expiration_hours=48, # La demande expire dans 48h
    maximum_views=1              # Le secret peut être vu une seule fois
)

# Avec livraison par email
request = await client.create_request(
    message="Veuillez fournir les clés API",
    description="Configuration intégration",
    email_to="[email protected]",
    email_reply="[email protected]"
)

# Exemple complet avec toutes les options
request = await client.create_request(
    message="Veuillez partager les identifiants de production de manière sécurisée",
    description="Accès déploiement Q4 nécessaire",
    secret_expiration_hours=24,
    request_expiration_hours=48,
    maximum_views=1,
    email_to="[email protected]",
    email_reply="[email protected]"
)

print(f"Demande complète créée : {request.url}")

Lister les Demandes de Secret ​

python
# Lister toutes les demandes
requests = await client.list_requests()

for req in requests:
    print(f"Demande {req.token}: {req.description}")
    print(f"  Statut: {req.status}")
    print(f"  Expire: {req.request_expiration}")

# Avec filtres
active_requests = await client.list_requests(status='active', limit=10)
print(f"Demandes actives : {len(active_requests)}")

# Filtrer par différents critères
recent_requests = await client.list_requests(
    status='active',
    limit=5
)

print(f"Trouvé {len(recent_requests)} demandes actives récentes")

Obtenir les Détails d'une Demande ​

python
# Obtenir les détails d'une demande spécifique par ID
request = await client.get_request(123)

print(f"Détails de la demande :")
print(f"- Message : {request.message}")
print(f"- Description : {request.description}")
print(f"- Statut : {request.status}")
print(f"- Créé : {request.created_at}")
print(f"- Expire : {request.request_expiration}")
print(f"- Email destinataire : {request.email_to}")
print(f"- URL : {request.url}")

Supprimer une Demande ​

python
# Supprimer et invalider une demande
try:
    await client.delete_request(123)
    print("Demande supprimée avec succès")
except Exception as e:
    print(f"Erreur lors de la suppression : {e}")

# Supprimer plusieurs demandes
request_ids = [123, 124, 125]
for req_id in request_ids:
    try:
        await client.delete_request(req_id)
        print(f"Demande {req_id} supprimée")
    except Exception as e:
        print(f"Erreur pour demande {req_id} : {e}")

Statistiques des Demandes ​

python
# Obtenir les statistiques de vos demandes de secret
stats = await client.request_stats()

print("📊 Statistiques des Demandes :")
print(f"- Total demandes : {stats.total_requests}")
print(f"- Demandes actives : {stats.active_requests}")
print(f"- Demandes expirées : {stats.expired_requests}")
print(f"- Créées aujourd'hui : {stats.requests_created_today}")
print(f"- Créées cette semaine : {stats.requests_created_this_week}")
print(f"- Créées ce mois : {stats.requests_created_this_month}")
print(f"- Temps de réponse moyen : {stats.average_response_time_hours:.1f} heures")

Fonctions Utilitaires pour les Demandes ​

python
# Vérifier le statut d'une demande
def check_request_status(request):
    """Vérifier si une demande est encore active"""
    if request.status == 'active':
        return True
    elif request.status == 'expired':
        return False
    else:
        return None

# Gérer les demandes par lot
async def manage_requests_batch():
    """Gérer plusieurs demandes en une seule opération"""
    
    # Obtenir toutes les demandes actives
    active_requests = await client.list_requests(status='active')
    
    print(f"Gestion de {len(active_requests)} demandes actives")
    
    for request in active_requests:
        print(f"Demande {request.id}:")
        print(f"  - Description: {request.description}")
        print(f"  - Expire: {request.request_expiration}")
        print(f"  - URL: {request.url}")
        
        # Exemple de logique métier
        if request.description and "urgent" in request.description.lower():
            print(f"  ⚠️  Demande urgente détectée!")

# Exemple d'utilisation
await manage_requests_batch()

🚨 Gestion d'Erreurs ​

Le SDK Python fournit des exceptions typées pour différents scénarios d'erreur :

Types d'Exceptions ​

python
import sharokey
from sharokey import (
    ValidationError,
    AuthenticationError,
    NotFoundError,
    AttachmentError,
    NetworkError
)

try:
    secret = await client.create(
        "Mon contenu secret",
        hours=24,
        views=1
    )
except AuthenticationError as e:
    print(f"Échec de l'authentification : {e}")
    # Gérer token invalide ou expiré
except ValidationError as e:
    print(f"Erreur de validation : {e}")
    # Gérer paramètres invalides (heures, vues, etc.)
except AttachmentError as e:
    print(f"Erreur de pièce jointe : {e}")
    # Gérer limitations de taille/nombre de fichiers
except NetworkError as e:
    print(f"Erreur réseau : {e}")
    # Gérer problèmes de connexion
except Exception as e:
    print(f"Erreur inattendue : {e}")

Scénarios d'Erreur Spécifiques ​

python
# Erreurs de pièces jointes
try:
    await client.create(
        "Test de gros fichier",
        hours=24,
        views=1,
        attachments=["fichier_enorme.zip"]  # > 10Mo
    )
except AttachmentError as e:
    print(f"Fichier trop volumineux : {e}")

# Trop de pièces jointes
try:
    many_files = [f"fichier_{i}.txt" for i in range(15)]  # Plus de 10 fichiers
    await client.create(
        "Fichiers multiples",
        hours=24,
        views=1,
        attachments=many_files
    )
except AttachmentError as e:
    print(f"Trop de fichiers : {e}")

# Temps d'expiration invalide
try:
    await client.create(
        "Expiration invalide",
        hours=10000,  # > 1000 heures
        views=1
    )
except ValidationError as e:
    print(f"Heures invalides : {e}")

🔐 Fonctionnalités de Sécurité ​

Chiffrement Zero Knowledge ​

Tous les secrets utilisent un chiffrement côté client identique aux autres librairies :

  • Algorithme : AES-GCM-256
  • Dérivation de Clé : PBKDF2 avec 10 000 itérations
  • Système à deux clés : CléA (serveur) + CléB (fragment URL de partage)
  • Perfect Forward Secrecy : Chaque secret utilise des clés de chiffrement uniques

Bonnes Pratiques de Sécurité ​

python
import os
import getpass

# Gestion sécurisée des tokens
def get_api_token():
    """Obtenir le token API depuis l'environnement ou demander de manière sécurisée"""
    token = os.environ.get('SHAROKEY_TOKEN')
    if not token:
        token = getpass.getpass('Entrez le token API Sharokey : ')
    return token

# Utiliser le chargement sécurisé de token
client = sharokey.SharokeyClient(token=get_api_token())

# Gestion sécurisée des fichiers
import stat

def create_secure_secret_with_file(filepath, hours=24, views=1):
    """Créer un secret avec fichier, en s'assurant des permissions sécurisées"""
    
    # Vérifier les permissions du fichier
    file_stat = os.stat(filepath)
    if file_stat.st_mode & stat.S_IROTH:  # Lisible par tous
        print(f"Attention : {filepath} est lisible par tous")
    
    # Créer le secret
    return await client.create(
        f"Fichier confidentiel : {os.path.basename(filepath)}",
        hours=hours,
        views=views,
        attachments=[filepath]
    )

🛠️ Exemples d'Intégration ​

Intégration Django ​

python
# views.py
from django.http import JsonResponse
import json
import asyncio
import sharokey

# Configurer le client
client = sharokey.SharokeyClient('YOUR_API_KEY')

async def create_secret_api(request):
    if request.method == 'POST':
        try:
            data = json.loads(request.body)
            
            secret = await client.create(
                data['content'],
                hours=data.get('hours', 24),
                views=data.get('views', 1),
                description=data.get('description'),
                password=data.get('password')
            )
            
            return JsonResponse({
                'success': True,
                'share_url': secret.share_url,
                'slug': secret.slug,
                'expires_at': secret.expires_at
            })
            
        except Exception as e:
            return JsonResponse({
                'success': False,
                'error': str(e)
            }, status=400)
    
    return JsonResponse({'error': 'Méthode non autorisée'}, status=405)

Intégration FastAPI ​

python
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import sharokey

app = FastAPI()
client = sharokey.SharokeyClient('YOUR_API_KEY')

class SecretRequest(BaseModel):
    content: str
    hours: int = 24
    views: int = 1
    description: str = None
    password: str = None
    otp_email: str = None

@app.post("/secrets")
async def create_secret(request: SecretRequest):
    try:
        secret = await client.create(
            request.content,
            hours=request.hours,
            views=request.views,
            description=request.description,
            password=request.password,
            otp_email=request.otp_email
        )
        
        return {
            "slug": secret.slug,
            "share_url": secret.share_url,
            "expires_at": secret.expires_at,
            "maximum_views": secret.maximum_views
        }
        
    except sharokey.ValidationError as e:
        raise HTTPException(status_code=400, detail=str(e))
    except sharokey.AuthenticationError as e:
        raise HTTPException(status_code=401, detail=str(e))
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

@app.get("/secrets")
async def list_secrets(limit: int = 20, status: str = None):
    try:
        secrets = await client.list(limit=limit, status=status)
        return [
            {
                "slug": s.slug,
                "description": s.description,
                "status": s.status,
                "remaining_views": s.remaining_views,
                "maximum_views": s.maximum_views,
                "expires_at": s.expires_at
            }
            for s in secrets
        ]
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

Intégration Science des Données ​

python
import pandas as pd
import asyncio
import sharokey

async def share_analysis_results():
    """Partager les résultats d'analyse de données de manière sécurisée"""
    
    client = sharokey.SharokeyClient('YOUR_API_KEY')
    
    # Sauvegarder les résultats d'analyse dans des fichiers
    df = pd.read_csv('donnees.csv')
    analysis_results = df.describe()
    
    # Sauvegarder dans des fichiers temporaires
    analysis_results.to_csv('resume_analyse.csv')
    df.head(100).to_csv('echantillon_donnees.csv')
    
    # Créer des graphiques
    import matplotlib.pyplot as plt
    plt.figure(figsize=(10, 6))
    df.hist()
    plt.savefig('distribution_donnees.png')
    plt.close()
    
    # Partager les résultats de manière sécurisée
    secret = await client.create(
        "Résultats d'analyse de données pour T4 2024",
        hours=48,
        views=5,
        description="Analyse statistique et données d'échantillon",
        password="AnalyseDonnees2024!",
        attachments=[
            'resume_analyse.csv',
            'echantillon_donnees.csv', 
            'distribution_donnees.png'
        ]
    )
    
    print(f"Résultats d'analyse partagés : {secret.share_url}")
    
    # Nettoyer les fichiers temporaires
    import os
    for file in ['resume_analyse.csv', 'echantillon_donnees.csv', 'distribution_donnees.png']:
        os.remove(file)
    
    return secret.share_url

# Exécuter l'analyse
asyncio.run(share_analysis_results())

Script d'Automatisation ​

python
#!/usr/bin/env python3
"""
Script de gestion automatisée des secrets
"""
import asyncio
import argparse
import sys
import sharokey

async def main():
    parser = argparse.ArgumentParser(description='Script d\'automatisation Sharokey')
    parser.add_argument('action', choices=['create', 'list', 'delete', 'cleanup'])
    parser.add_argument('--content', help='Contenu du secret')
    parser.add_argument('--hours', type=int, default=24, help='Heures d\'expiration')
    parser.add_argument('--views', type=int, default=1, help='Vues maximum')
    parser.add_argument('--slug', help='Slug du secret pour opérations get/delete')
    parser.add_argument('--token', help='Token API')
    
    args = parser.parse_args()
    
    # Initialiser le client
    client = sharokey.SharokeyClient(args.token or 'YOUR_API_KEY')
    
    if args.action == 'create':
        if not args.content:
            print("Erreur : --content est requis pour l'action create")
            sys.exit(1)
            
        secret = await client.create(
            args.content,
            hours=args.hours,
            views=args.views
        )
        print(f"Créé : {secret.share_url}")
        
    elif args.action == 'list':
        secrets = await client.list(limit=50)
        print(f"{'Slug':<12} {'Statut':<10} {'Vues':<8} {'Description'}")
        print("-" * 60)
        for secret in secrets:
            views = f"{secret.remaining_views}/{secret.maximum_views}"
            desc = (secret.description or "Aucune description")[:30]
            print(f"{secret.slug:<12} {secret.status:<10} {views:<8} {desc}")
            
    elif args.action == 'delete':
        if not args.slug:
            print("Erreur : --slug est requis pour l'action delete")
            sys.exit(1)
            
        await client.delete(args.slug)
        print(f"Supprimé : {args.slug}")
        
    elif args.action == 'cleanup':
        # Supprimer les secrets expirés
        secrets = await client.list(limit=100)
        expired_secrets = [s for s in secrets if s.status == 'expired']
        
        print(f"Trouvé {len(expired_secrets)} secrets expirés")
        for secret in expired_secrets:
            await client.delete(secret.slug)
            print(f"Supprimé le secret expiré : {secret.slug}")

if __name__ == '__main__':
    asyncio.run(main())

📏 Cohérence des Méthodes ​

Le SDK Python maintient des noms de méthodes cohérents avec le CLI :

Commande CLIMéthode PythonDescription
sharokey config --token xxxSharokeyClient('YOUR_API_KEY')Configuration
sharokey createclient.create()Créer un secret
sharokey listclient.list()Lister les secrets
sharokey get SLUGclient.get(slug)Détails d'un secret
sharokey delete SLUGclient.delete(slug)Supprimer un secret
sharokey statsclient.stats()Obtenir les statistiques
sharokey generate-passwordclient.generate_password()Générer un mot de passe
sharokey testclient.test_connection()Tester la connectivité

🔗 Ressources Associées ​

📜 License ​

Le SDK Python Sharokey est distribué sous la Licence MIT.
Voir LICENSE pour plus de détails.

Released under the MIT License.