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
pip install sharokeyOu avec poetry :
poetry add sharokeyConfiguration de Base
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
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
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
# 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
# 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 :
# 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
# 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
# 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
# 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
# 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
# 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
# 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é
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
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
# 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é
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
# 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
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
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
#!/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 CLI | Méthode Python | Description |
|---|---|---|
sharokey config --token xxx | SharokeyClient('YOUR_API_KEY') | Configuration |
sharokey create | client.create() | Créer un secret |
sharokey list | client.list() | Lister les secrets |
sharokey get SLUG | client.get(slug) | Détails d'un secret |
sharokey delete SLUG | client.delete(slug) | Supprimer un secret |
sharokey stats | client.stats() | Obtenir les statistiques |
sharokey generate-password | client.generate_password() | Générer un mot de passe |
sharokey test | client.test_connection() | Tester la connectivité |
🔗 Ressources Associées
- Comparaison des Fonctionnalités - Comparer avec d'autres librairies
- CLI C# - Interface en ligne de commande avec même syntaxe
- Référence API - Documentation directe de l'API REST
- Exemples - Plus d'exemples d'utilisation et tutoriels
- JavaScript SDK - Pour les applications Node.js
- JavaScript CDN - Pour les applications navigateur
📜 License
Le SDK Python Sharokey est distribué sous la Licence MIT.
Voir LICENSE pour plus de détails.
