Source code for scripts.create_data_via_api

#!/usr/bin/env python3
"""
Script pour créer des données via l'API en utilisant le générateur Faker.

Ce script utilise l'API unifiée pour créer des utilisateurs et des VMs
avec des données générées par Faker, permettant de peupler la base de données
avec des données réalistes.
"""

import typer
import time
import sys
from typing import Optional, List, Dict, Any
from pathlib import Path
import json
from datetime import datetime
from rich.console import Console
from rich.progress import (
    Progress,
    SpinnerColumn,
    TextColumn,
    BarColumn,
    TimeElapsedColumn,
)
from rich.table import Table
from rich.panel import Panel

# Ajouter le répertoire parent au path pour les imports
sys.path.append(str(Path(__file__).parent.parent))

from utils.api import ApiClient, create_authenticated_client
from utils.data_generator import UserDataGenerator, VMDataGenerator
from utils.logging_config import get_logger

logger = get_logger(__name__)
console = Console()

app = typer.Typer(
    name="create-data-via-api",
    help="🚀 CrĂ©ateur de donnĂ©es via API avec Faker",
    rich_markup_mode="rich",
    add_completion=False,
    no_args_is_help=True,
)


# =============================================================================
# PARTIE REPRÉSENTATION / AFFICHAGE
# =============================================================================


[docs] def display_header(title: str, subtitle: str = "") -> None: """Affiche l'en-tĂȘte principal""" header_text = f"[bold blue]{title}[/bold blue]" if subtitle: header_text += f"\n[dim]{subtitle}[/dim]" console.print( Panel.fit( header_text, border_style="blue", ) )
[docs] def display_api_config(client: ApiClient) -> None: """Affiche la configuration de l'API""" config_table = Table(title="🔗 Configuration API") config_table.add_column("Paramùtre", style="cyan") config_table.add_column("Valeur", style="magenta") config_table.add_row("Base URL", client.base_url) config_table.add_row("Mode", "Client simple") console.print(config_table) console.print()
[docs] def display_operation_config( operation: str, count: int, batch_size: int, delay: float ) -> None: """Affiche la configuration des opĂ©rations""" config_table = Table(title=f"🔧 Configuration - {operation}") config_table.add_column("ParamĂštre", style="cyan") config_table.add_column("Valeur", style="magenta") config_table.add_row("Nombre total", str(count)) config_table.add_row("Taille des lots", str(batch_size)) config_table.add_row("DĂ©lai entre lots", f"{delay}s") console.print(config_table) console.print()
[docs] def display_batch_progress(batch_num: int, start: int, end: int, total: int) -> None: """Affiche le progrĂšs d'un lot""" console.print( f"[bold cyan]📝 Lot {batch_num}:[/bold cyan] Ă©lĂ©ments {start + 1}-{end} sur {total}" )
[docs] def display_success_message( item_type: str, item_name: str, item_details: str = "" ) -> None: """Affiche un message de succĂšs""" message = f"[green]✅ {item_type} créé:[/green] [bold]{item_name}[/bold]" if item_details: message += f" [dim]({item_details})[/dim]" console.print(message)
[docs] def display_error_message(item_type: str, item_index: int, error: str) -> None: """Affiche un message d'erreur""" console.print(f"[red]❌ Erreur {item_type} {item_index + 1}:[/red] {error}")
[docs] def display_statistics(title: str, stats: Dict[str, Any]) -> None: """Affiche les statistiques dans un tableau""" stats_table = Table(title=f"📊 {title}") stats_table.add_column("MĂ©trique", style="cyan") stats_table.add_column("Valeur", style="green") for key, value in stats.items(): stats_table.add_row(key, str(value)) console.print(stats_table) console.print()
[docs] def display_preview( title: str, items: List[Dict[str, Any]], max_items: int = 5 ) -> None: """Affiche un aperçu des Ă©lĂ©ments créés""" if not items: return console.print(f"[bold cyan]🔍 {title}:[/bold cyan]") for i, item in enumerate(items[:max_items]): if "name" in item and "email" in item: # Utilisateur console.print(f" {i + 1}. [bold]{item['name']}[/bold] ({item['email']})") elif "name" in item and "operating_system" in item: # VM console.print( f" {i + 1}. [bold]{item['name']}[/bold] ({item['operating_system']})" ) else: console.print(f" {i + 1}. {item}") if len(items) > max_items: console.print(f" ... et {len(items) - max_items} autres Ă©lĂ©ments") console.print()
[docs] def display_dataset_saved(file_path: Path) -> None: """Affiche le message de sauvegarde du dataset""" console.print( Panel.fit( f"[bold green]đŸ’Ÿ Dataset sauvegardĂ©:[/bold green]\n{file_path.absolute()}", border_style="green", ) )
[docs] def display_api_status(all_data: Dict[str, Any], api_url: str) -> None: """Affiche le statut de l'API""" status_table = Table(title="📊 Statut de l'API") status_table.add_column("MĂ©trique", style="cyan") status_table.add_column("Valeur", style="green") status_table.add_row("URL de l'API", api_url) status_table.add_row("Utilisateurs total", str(all_data["total_users"])) status_table.add_row("VMs totales", str(all_data["total_vms"])) status_table.add_row("Utilisateurs avec VMs", str(all_data["users_with_vms"])) if all_data["total_users"] > 0: avg_vms = all_data["total_vms"] / all_data["total_users"] status_table.add_row("Moyenne VMs/utilisateur", f"{avg_vms:.1f}") console.print(status_table) console.print()
# ============================================================================= # PARTIE LOGIQUE MÉTIER / DONNÉES # =============================================================================
[docs] def create_users_via_api( api_client: ApiClient, user_count: int, batch_size: int = 10, delay_between_batches: float = 0.5, ) -> List[Dict[str, Any]]: """ CrĂ©e des utilisateurs via l'API en utilisant le gĂ©nĂ©rateur Faker. Args: api_client: Client API authentifiĂ© user_count: Nombre d'utilisateurs Ă  crĂ©er batch_size: Nombre d'utilisateurs Ă  crĂ©er par lot delay_between_batches: DĂ©lai entre les lots (en secondes) Returns: Liste des utilisateurs créés """ logger.info( "CrĂ©ation d'utilisateurs via API", count=user_count, batch_size=batch_size ) created_users = [] created_count = 0 with Progress( SpinnerColumn(), TextColumn("[progress.description]{task.description}"), BarColumn(), TextColumn("[progress.percentage]{task.percentage:>3.0f}%"), TimeElapsedColumn(), console=console, ) as progress: task = progress.add_task( f"CrĂ©ation de {user_count} utilisateurs...", total=user_count ) for batch_start in range(0, user_count, batch_size): batch_end = min(batch_start + batch_size, user_count) batch_size_actual = batch_end - batch_start display_batch_progress( batch_start // batch_size + 1, batch_start, batch_end, user_count ) for i in range(batch_size_actual): try: # GĂ©nĂ©rer les donnĂ©es utilisateur avec Faker user_data = UserDataGenerator.generate_user(created_count + 1) created_user = api_client.users.create_user( name=user_data["name"], email=user_data["email"], password="password123", # Mot de passe par dĂ©faut ) # VĂ©rifier que l'utilisateur a Ă©tĂ© créé avec succĂšs if ( created_user and isinstance(created_user, dict) and "id" in created_user ): created_users.append(created_user) created_count += 1 display_success_message( "Utilisateur", user_data["name"], user_data["email"] ) else: logger.error( "Échec de crĂ©ation d'utilisateur - donnĂ©es invalides", user_data=user_data, created_user=created_user, created_user_type=type(created_user), ) display_error_message( "utilisateur", i, f"DonnĂ©es utilisateur invalides: {created_user}", ) except Exception as e: logger.error( "Erreur lors de la crĂ©ation d'un utilisateur", error=str(e), error_type=type(e).__name__, ) display_error_message( "utilisateur", i, f"{type(e).__name__}: {str(e)}" ) progress.update(task, advance=1) # DĂ©lai entre chaque crĂ©ation d'utilisateur if i < batch_size_actual - 1 or batch_end < user_count: time.sleep(delay_between_batches / 2) # DĂ©lai entre les lots pour Ă©viter de surcharger l'API if batch_end < user_count: time.sleep(delay_between_batches) logger.info("Utilisateurs créés avec succĂšs", count=len(created_users)) return created_users
[docs] def create_vms_via_api( api_client: ApiClient, vm_count: int, user_ids: List[int], batch_size: int = 10, delay_between_batches: float = 0.5, ) -> List[Dict[str, Any]]: """ CrĂ©e des VMs via l'API en utilisant le gĂ©nĂ©rateur Faker. Args: api_client: Client API authentifiĂ© vm_count: Nombre de VMs Ă  crĂ©er user_ids: Liste des IDs d'utilisateurs disponibles batch_size: Nombre de VMs Ă  crĂ©er par lot delay_between_batches: DĂ©lai entre les lots (en secondes) Returns: Liste des VMs créées """ # VĂ©rifier que user_ids est valide if not user_ids: logger.error("Liste d'IDs d'utilisateurs vide ou None", user_ids=user_ids) raise ValueError("Aucun ID d'utilisateur valide fourni pour la crĂ©ation de VMs") logger.info( "CrĂ©ation de VMs via API", count=vm_count, available_users=len(user_ids) ) created_vms = [] created_count = 0 with Progress( SpinnerColumn(), TextColumn("[progress.description]{task.description}"), BarColumn(), TextColumn("[progress.percentage]{task.percentage:>3.0f}%"), TimeElapsedColumn(), console=console, ) as progress: task = progress.add_task(f"CrĂ©ation de {vm_count} VMs...", total=vm_count) for batch_start in range(0, vm_count, batch_size): batch_end = min(batch_start + batch_size, vm_count) batch_size_actual = batch_end - batch_start display_batch_progress( batch_start // batch_size + 1, batch_start, batch_end, vm_count ) for i in range(batch_size_actual): try: # VĂ©rifier que user_ids est valide avant utilisation if not user_ids or len(user_ids) == 0: logger.error(f"user_ids invalide: {user_ids}") raise ValueError("Liste d'IDs d'utilisateurs vide ou None") selected_user_id = user_ids[created_count % len(user_ids)] if selected_user_id is None: logger.error( f"ID utilisateur None trouvĂ© dans user_ids: {user_ids}" ) raise ValueError("ID utilisateur None trouvĂ©") # GĂ©nĂ©rer les donnĂ©es VM avec Faker vm_data = VMDataGenerator.generate_vm( user_id=selected_user_id, vm_id=created_count + 1, ) created_vm = api_client.vms.create( user_id=vm_data["user_id"], name=vm_data["name"], operating_system=vm_data["operating_system"], cpu_cores=vm_data["cpu_cores"], ram_gb=vm_data["ram_gb"], disk_gb=vm_data["disk_gb"], status=vm_data["status"], ) # VĂ©rifier que la VM a Ă©tĂ© créée avec succĂšs if ( created_vm and isinstance(created_vm, dict) and "id" in created_vm ): created_vms.append(created_vm) created_count += 1 vm_details = f"{vm_data['operating_system']} - {vm_data['cpu_cores']}c/{vm_data['ram_gb']}GB" display_success_message("VM", vm_data["name"], vm_details) else: logger.error( "Échec de crĂ©ation de VM - donnĂ©es invalides", vm_data=vm_data, created_vm=created_vm, created_vm_type=type(created_vm), ) display_error_message( "VM", i, f"DonnĂ©es VM invalides: {created_vm}" ) except Exception as e: logger.error( "Erreur lors de la crĂ©ation d'une VM", error=str(e), error_type=type(e).__name__, ) display_error_message("VM", i, f"{type(e).__name__}: {str(e)}") progress.update(task, advance=1) # DĂ©lai entre chaque crĂ©ation de VM if i < batch_size_actual - 1 or batch_end < vm_count: time.sleep(delay_between_batches / 2) # DĂ©lai entre les lots pour Ă©viter de surcharger l'API if batch_end < vm_count: time.sleep(delay_between_batches) logger.info("VMs créées avec succĂšs", count=len(created_vms)) return created_vms
# ============================================================================= # COMMANDES TYPER AVEC AFFICHAGE RICH # =============================================================================
[docs] @app.command() def users( count: int = typer.Option( 10, "--count", "-c", help="Nombre d'utilisateurs Ă  crĂ©er", min=1, max=100 ), batch_size: int = typer.Option( 5, "--batch-size", "-b", help="Taille des lots", min=1, max=20 ), delay: float = typer.Option( 2.0, "--delay", "-d", help="DĂ©lai entre les lots (secondes)", min=0.5, max=10.0 ), verbose: bool = typer.Option(False, "--verbose", "-v", help="Mode verbeux"), ) -> None: """ đŸ‘„ CrĂ©er des utilisateurs via l'API avec des donnĂ©es Faker GĂ©nĂšre des utilisateurs rĂ©alistes avec Faker et les crĂ©e via l'API. Exemples: .. code-block:: shell python create_data_via_api.py users --count 20 python create_data_via_api.py users -c 50 --batch-size 10 --delay 3.0 --max-retries 7 python create_data_via_api.py users --verbose """ display_header( "đŸ‘„ CrĂ©ation d'utilisateurs via l'API", f"GĂ©nĂ©ration de {count} utilisateurs avec Faker", ) try: # CrĂ©er le client API avec authentification automatique console.print( "[bold yellow]🔐 Authentification automatique en cours...[/bold yellow]" ) api_client = create_authenticated_client() if api_client.is_authenticated(): console.print("[bold green]✅ Authentification rĂ©ussie ![/bold green]") else: console.print("[bold red]❌ Échec de l'authentification[/bold red]") console.print( "[dim]💡 Configurez DEMO_API_EMAIL et DEMO_API_PASSWORD dans votre fichier .env[/dim]" ) raise typer.Exit(1) console.print( f"[bold green]🔗 Connexion Ă  l'API sur {api_client.base_url}[/bold green]" ) console.print() # Afficher la configuration display_api_config(api_client) display_operation_config("Utilisateurs", count, batch_size, delay) # CrĂ©er les utilisateurs created_users = create_users_via_api( api_client=api_client, user_count=count, batch_size=batch_size, delay_between_batches=delay, ) # Statistiques stats = { "Utilisateurs créés": len(created_users), "Taux de succĂšs": f"{len(created_users) / count * 100:.1f}%", } display_statistics("RĂ©sultat de la crĂ©ation", stats) if verbose and created_users: display_preview("Aperçu des utilisateurs créés", created_users) console.print( Panel.fit( "[bold green]✅ CRÉATION TERMINÉE AVEC SUCCÈS ![/bold green]", border_style="green", ) ) except Exception as e: logger.error("Erreur lors de la crĂ©ation des utilisateurs", error=str(e)) console.print( Panel.fit( f"[bold red]❌ Erreur lors de la crĂ©ation:[/bold red]\n{e}", border_style="red", ) ) raise typer.Exit(1)
[docs] @app.command() def vms( count: int = typer.Option( 20, "--count", "-c", help="Nombre de VMs Ă  crĂ©er", min=1, max=200 ), batch_size: int = typer.Option( 5, "--batch-size", "-b", help="Taille des lots", min=1, max=20 ), delay: float = typer.Option( 2.0, "--delay", "-d", help="DĂ©lai entre les lots (secondes)", min=0.5, max=10.0 ), verbose: bool = typer.Option(False, "--verbose", "-v", help="Mode verbeux"), ) -> None: """ đŸ–„ïž CrĂ©er des VMs via l'API avec des donnĂ©es Faker GĂ©nĂšre des VMs rĂ©alistes avec Faker et les crĂ©e via l'API. Les VMs sont associĂ©es Ă  des utilisateurs existants. Exemples: .. code-block:: shell python create_data_via_api.py vms --count 50 python create_data_via_api.py vms -c 100 --batch-size 10 --delay 3.0 python create_data_via_api.py vms --verbose """ display_header( "đŸ–„ïž CrĂ©ation de VMs via l'API", f"GĂ©nĂ©ration de {count} VMs avec Faker" ) try: # CrĂ©er le client API avec authentification automatique console.print( "[bold yellow]🔐 Authentification automatique en cours...[/bold yellow]" ) api_client = create_authenticated_client() if api_client.is_authenticated(): console.print("[bold green]✅ Authentification rĂ©ussie ![/bold green]") else: console.print("[bold red]❌ Échec de l'authentification[/bold red]") console.print( "[dim]💡 Configurez DEMO_API_EMAIL et DEMO_API_PASSWORD dans votre fichier .env[/dim]" ) raise typer.Exit(1) console.print( f"[bold green]🔗 Connexion Ă  l'API sur {api_client.base_url}[/bold green]" ) console.print() # Afficher la configuration display_api_config(api_client) # RĂ©cupĂ©rer les utilisateurs existants with console.status("[bold green]RĂ©cupĂ©ration des utilisateurs existants..."): existing_users = api_client.users.get() if not existing_users: console.print( Panel.fit( "[bold red]❌ Aucun utilisateur trouvĂ© dans l'API[/bold red]\n" "[dim]💡 CrĂ©ez d'abord des utilisateurs avec la commande 'users'[/dim]", border_style="red", ) ) raise typer.Exit(1) user_ids = [user["id"] for user in existing_users] console.print( f"[bold cyan]đŸ‘„ {len(user_ids)} utilisateurs disponibles pour l'association des VMs[/bold cyan]" ) console.print() display_operation_config("VMs", count, batch_size, delay) # CrĂ©er les VMs created_vms = create_vms_via_api( api_client=api_client, vm_count=count, user_ids=user_ids, batch_size=batch_size, delay_between_batches=delay, ) # Statistiques stats = { "VMs créées": len(created_vms), "Taux de succĂšs": f"{len(created_vms) / count * 100:.1f}%", "Utilisateurs concernĂ©s": len(user_ids), } display_statistics("RĂ©sultat de la crĂ©ation", stats) if verbose and created_vms: display_preview("Aperçu des VMs créées", created_vms) console.print( Panel.fit( "[bold green]✅ CRÉATION TERMINÉE AVEC SUCCÈS ![/bold green]", border_style="green", ) ) except Exception as e: logger.error("Erreur lors de la crĂ©ation des VMs", error=str(e)) console.print( Panel.fit( f"[bold red]❌ Erreur lors de la crĂ©ation:[/bold red]\n{e}", border_style="red", ) ) raise typer.Exit(1)
[docs] @app.command() def full_dataset( user_count: int = typer.Option( 20, "--users", "-u", help="Nombre d'utilisateurs Ă  crĂ©er", min=1, max=100 ), vm_count: int = typer.Option( 50, "--vms", "-v", help="Nombre de VMs Ă  crĂ©er", min=1, max=200 ), batch_size: int = typer.Option( 5, "--batch-size", "-b", help="Taille des lots", min=1, max=20 ), delay: float = typer.Option( 2.0, "--delay", "-d", help="DĂ©lai entre les lots (secondes)", min=0.5, max=10.0 ), output_file: Optional[str] = typer.Option( None, "--output", "-o", help="Fichier de sortie pour sauvegarder les donnĂ©es créées", ), verbose: bool = typer.Option(False, "--verbose", "-v", help="Mode verbeux"), ) -> None: """ 🎯 CrĂ©er un dataset complet via l'API avec des donnĂ©es Faker CrĂ©e des utilisateurs et des VMs rĂ©alistes avec Faker via l'API. Optionnellement sauvegarde les donnĂ©es créées dans un fichier JSON. Exemples: .. code-block:: shell python create_data_via_api.py full-dataset --users 20 --vms 50 python create_data_via_api.py full-dataset -u 30 -v 100 --delay 3.0 --output dataset.json python create_data_via_api.py full-dataset --verbose """ display_header( "🎯 CrĂ©ation d'un dataset complet", f"{user_count} utilisateurs + {vm_count} VMs avec Faker", ) try: # CrĂ©er le client API avec authentification automatique console.print( "[bold yellow]🔐 Authentification automatique en cours...[/bold yellow]" ) api_client = create_authenticated_client() if api_client.is_authenticated(): console.print("[bold green]✅ Authentification rĂ©ussie ![/bold green]") else: console.print("[bold red]❌ Échec de l'authentification[/bold red]") console.print( "[dim]💡 Configurez DEMO_API_EMAIL et DEMO_API_PASSWORD dans votre fichier .env[/dim]" ) raise typer.Exit(1) console.print( f"[bold green]🔗 Connexion Ă  l'API sur {api_client.base_url}[/bold green]" ) console.print() # Afficher la configuration display_api_config(api_client) display_operation_config( "Dataset complet", user_count + vm_count, batch_size, delay ) # Étape 1: CrĂ©er les utilisateurs console.print( Panel.fit( f"[bold blue]đŸ‘„ Étape 1/2: CrĂ©ation de {user_count} utilisateurs[/bold blue]", border_style="blue", ) ) created_users = create_users_via_api( api_client=api_client, user_count=user_count, batch_size=batch_size, delay_between_batches=delay, ) # Étape 2: CrĂ©er les VMs console.print( Panel.fit( f"[bold blue]đŸ–„ïž Étape 2/2: CrĂ©ation de {vm_count} VMs[/bold blue]", border_style="blue", ) ) if created_users is None: logger.error("created_users est None!") console.print( Panel.fit( "[bold red]❌ Erreur: created_users est None[/bold red]\n" "[dim]💡 ProblĂšme dans la crĂ©ation des utilisateurs[/dim]", border_style="red", ) ) raise typer.Exit(1) # VĂ©rifier qu'on a des utilisateurs créés avec succĂšs if not created_users: console.print( Panel.fit( "[bold red]❌ Aucun utilisateur créé avec succĂšs[/bold red]\n" "[dim]💡 Impossible de crĂ©er des VMs sans utilisateurs[/dim]", border_style="red", ) ) raise typer.Exit(1) # Analyser chaque utilisateur avant extraction des IDs valid_users = [] for i, user in enumerate(created_users): if user and isinstance(user, dict) and "id" in user: valid_users.append(user) else: logger.warning(f"Utilisateur {i} invalide: {user} (type: {type(user)})") user_ids = [user["id"] for user in valid_users] if not user_ids: console.print( Panel.fit( "[bold red]❌ Aucun ID d'utilisateur valide trouvĂ©[/bold red]\n" "[dim]💡 Impossible de crĂ©er des VMs[/dim]", border_style="red", ) ) raise typer.Exit(1) created_vms = create_vms_via_api( api_client=api_client, vm_count=vm_count, user_ids=user_ids, batch_size=batch_size, delay_between_batches=delay, ) # Statistiques finales stats = { "Utilisateurs créés": len(created_users), "VMs créées": len(created_vms), "Taux de succĂšs utilisateurs": f"{len(created_users) / user_count * 100:.1f}%", "Taux de succĂšs VMs": f"{len(created_vms) / vm_count * 100:.1f}%", } display_statistics("Statistiques finales", stats) # Sauvegarder les donnĂ©es si demandĂ© if output_file: dataset = { "created_at": datetime.now().isoformat(), "users": created_users, "vms": created_vms, "statistics": { "total_users": len(created_users), "total_vms": len(created_vms), "user_success_rate": len(created_users) / user_count * 100, "vm_success_rate": len(created_vms) / vm_count * 100, }, } output_path = Path(output_file) with open(output_path, "w", encoding="utf-8") as f: json.dump(dataset, f, indent=4, ensure_ascii=False, default=str) display_dataset_saved(output_path) if verbose: display_preview("Aperçu des utilisateurs créés", created_users, 3) display_preview("Aperçu des VMs créées", created_vms, 3) console.print( Panel.fit( "[bold green]✅ DATASET CRÉÉ AVEC SUCCÈS ![/bold green]", border_style="green", ) ) except Exception as e: logger.error("Erreur lors de la crĂ©ation du dataset", error=str(e)) console.print( Panel.fit( f"[bold red]❌ Erreur lors de la crĂ©ation:[/bold red]\n{e}", border_style="red", ) ) raise typer.Exit(1)
[docs] @app.command() def status() -> None: """ 📊 Afficher le statut actuel de l'API RĂ©cupĂšre et affiche les statistiques actuelles des utilisateurs et VMs. Exemples: .. code-block:: shell python create_data_via_api.py status """ display_header("📊 Statut de l'API", "RĂ©cupĂ©ration des statistiques actuelles") try: # CrĂ©er le client API simple api_client = ApiClient() console.print( f"[bold green]🔗 Connexion Ă  l'API sur {api_client.base_url}[/bold green]" ) console.print() # Afficher la configuration display_api_config(api_client) # RĂ©cupĂ©rer toutes les donnĂ©es with console.status("[bold green]RĂ©cupĂ©ration des donnĂ©es..."): all_data = api_client.get_all_data() # Afficher les statistiques display_api_status(all_data, api_client.base_url) console.print( Panel.fit( "[bold green]✅ STATUT RÉCUPÉRÉ AVEC SUCCÈS ![/bold green]", border_style="green", ) ) except Exception as e: logger.error("Erreur lors de la rĂ©cupĂ©ration du statut", error=str(e)) console.print( Panel.fit( f"[bold red]❌ Erreur lors de la rĂ©cupĂ©ration:[/bold red]\n{e}", border_style="red", ) ) raise typer.Exit(1)
[docs] @app.command() def version() -> None: """📋 Afficher la version du crĂ©ateur de donnĂ©es""" console.print( Panel.fit( "[bold blue]create-data-via-api v1.0.0[/bold blue]\n" "[dim]Powered by Faker đŸŽČ + API unifiĂ©e 🚀[/dim]", border_style="blue", ) )
[docs] def main(): """Point d'entrĂ©e principal""" # GĂ©rer -h comme alias pour --help if "-h" in sys.argv and "--help" not in sys.argv: sys.argv[sys.argv.index("-h")] = "--help" try: app() except KeyboardInterrupt: console.print( Panel.fit( "[bold yellow]⚠ CrĂ©ation interrompue[/bold yellow]", border_style="yellow", ) ) except Exception as e: console.print( Panel.fit( f"[bold red]❌ Erreur:[/bold red]\n{e}", border_style="red", ) ) raise typer.Exit(1)
if __name__ == "__main__": main()