Spaces:
Sleeping
Sleeping
| #!/usr/bin/env python3 | |
| """ | |
| QCrypt RNG - Test API Endpoints | |
| Script to test all API endpoints | |
| """ | |
| import asyncio | |
| import json | |
| from typing import Dict, Any | |
| import sys | |
| from pathlib import Path | |
| # Add project root to path | |
| sys.path.append(str(Path(__file__).parent)) | |
| try: | |
| import httpx | |
| from rich.console import Console | |
| from rich.table import Table | |
| from rich.progress import Progress, SpinnerColumn, TextColumn | |
| from rich.panel import Panel | |
| except ImportError: | |
| print("Installing required packages...") | |
| import subprocess | |
| subprocess.check_call([sys.executable, "-m", "pip", "install", "httpx", "rich"]) | |
| import httpx | |
| from rich.console import Console | |
| from rich.table import Table | |
| from rich.progress import Progress, SpinnerColumn, TextColumn | |
| from rich.panel import Panel | |
| console = Console() | |
| # API Base URL | |
| BASE_URL = "http://localhost:8000" | |
| API_V2 = f"{BASE_URL}/api/v2" | |
| async def test_root(): | |
| """Test root endpoint""" | |
| async with httpx.AsyncClient() as client: | |
| response = await client.get(f"{BASE_URL}/") | |
| return response.status_code == 200, response.json() | |
| async def test_health(): | |
| """Test health endpoint""" | |
| async with httpx.AsyncClient() as client: | |
| response = await client.get(f"{BASE_URL}/health") | |
| return response.status_code == 200, response.json() | |
| async def test_generate_bytes(): | |
| """Test byte generation endpoint""" | |
| async with httpx.AsyncClient() as client: | |
| payload = { | |
| "length": 32, | |
| "format": "hex", | |
| "quantum_bits": 8 | |
| } | |
| response = await client.post(f"{API_V2}/generate/bytes", json=payload) | |
| return response.status_code == 200, response.json() | |
| async def test_generate_key(): | |
| """Test key generation endpoint""" | |
| async with httpx.AsyncClient() as client: | |
| payload = { | |
| "algorithm": "AES", | |
| "key_size": 256, | |
| "format": "hex" | |
| } | |
| response = await client.post(f"{API_V2}/generate/key", json=payload) | |
| return response.status_code == 200, response.json() | |
| async def test_generate_token(): | |
| """Test token generation endpoint""" | |
| async with httpx.AsyncClient() as client: | |
| payload = { | |
| "length": 32, | |
| "url_safe": True, | |
| "expires_in": 3600 | |
| } | |
| response = await client.post(f"{API_V2}/generate/token", json=payload) | |
| return response.status_code == 200, response.json() | |
| async def test_generate_uuid(): | |
| """Test UUID generation endpoint""" | |
| async with httpx.AsyncClient() as client: | |
| payload = { | |
| "version": 4, | |
| "count": 1, | |
| "format": "standard" | |
| } | |
| response = await client.post(f"{API_V2}/generate/uuid", json=payload) | |
| return response.status_code == 200, response.json() | |
| async def test_generate_password(): | |
| """Test password generation endpoint""" | |
| async with httpx.AsyncClient() as client: | |
| payload = { | |
| "length": 16, | |
| "include_uppercase": True, | |
| "include_lowercase": True, | |
| "include_numbers": True, | |
| "include_symbols": True, | |
| "exclude_ambiguous": True | |
| } | |
| response = await client.post(f"{API_V2}/generate/password", json=payload) | |
| return response.status_code == 200, response.json() | |
| async def test_entropy_status(): | |
| """Test entropy status endpoint""" | |
| async with httpx.AsyncClient() as client: | |
| response = await client.get(f"{API_V2}/quantum/entropy") | |
| return response.status_code == 200, response.json() | |
| async def test_system_stats(): | |
| """Test system statistics endpoint""" | |
| async with httpx.AsyncClient() as client: | |
| response = await client.get(f"{API_V2}/quantum/stats") | |
| return response.status_code == 200, response.json() | |
| async def test_batch_generate(): | |
| """Test batch generation endpoint""" | |
| async with httpx.AsyncClient() as client: | |
| payload = { | |
| "requests": [ | |
| {"length": 16, "format": "hex", "quantum_bits": 8}, | |
| {"length": 32, "format": "base64", "quantum_bits": 12}, | |
| {"length": 8, "format": "array", "quantum_bits": 4} | |
| ], | |
| "parallel": True | |
| } | |
| response = await client.post(f"{API_V2}/generate/batch", json=payload) | |
| return response.status_code == 200, response.json() | |
| async def run_all_tests(): | |
| """Run all API tests""" | |
| console.print(Panel.fit( | |
| "[bold cyan]QCrypt RNG API Test Suite[/bold cyan]\n" | |
| "[yellow]Testing all API endpoints...[/yellow]", | |
| border_style="bold blue" | |
| )) | |
| # Define all tests | |
| tests = [ | |
| ("Root Endpoint", test_root), | |
| ("Health Check", test_health), | |
| ("Generate Bytes", test_generate_bytes), | |
| ("Generate Key", test_generate_key), | |
| ("Generate Token", test_generate_token), | |
| ("Generate UUID", test_generate_uuid), | |
| ("Generate Password", test_generate_password), | |
| ("Entropy Status", test_entropy_status), | |
| ("System Stats", test_system_stats), | |
| ("Batch Generate", test_batch_generate) | |
| ] | |
| # Results table | |
| table = Table(title="API Test Results", show_header=True) | |
| table.add_column("Endpoint", style="cyan", width=20) | |
| table.add_column("Status", style="green", width=10) | |
| table.add_column("Response Time", style="yellow", width=12) | |
| table.add_column("Sample Response", style="white", width=50) | |
| failed_tests = [] | |
| with Progress( | |
| SpinnerColumn(), | |
| TextColumn("[progress.description]{task.description}"), | |
| console=console, | |
| transient=True | |
| ) as progress: | |
| for test_name, test_func in tests: | |
| task = progress.add_task(f"[cyan]Testing {test_name}...", total=None) | |
| try: | |
| import time | |
| start = time.time() | |
| success, response = await test_func() | |
| elapsed = (time.time() - start) * 1000 | |
| if success: | |
| status = "[green]β Pass[/green]" | |
| # Format sample response | |
| if isinstance(response, dict): | |
| if "data" in response: | |
| sample = str(response["data"])[:47] + "..." | |
| else: | |
| sample = str(response)[:47] + "..." | |
| else: | |
| sample = str(response)[:47] + "..." | |
| else: | |
| status = "[red]β Fail[/red]" | |
| sample = f"[red]{response}[/red]" | |
| failed_tests.append(test_name) | |
| table.add_row( | |
| test_name, | |
| status, | |
| f"{elapsed:.0f}ms", | |
| sample | |
| ) | |
| except Exception as e: | |
| table.add_row( | |
| test_name, | |
| "[red]β Error[/red]", | |
| "N/A", | |
| f"[red]{str(e)[:47]}...[/red]" | |
| ) | |
| failed_tests.append(test_name) | |
| progress.update(task, completed=True) | |
| console.print(table) | |
| # Summary | |
| total_tests = len(tests) | |
| passed_tests = total_tests - len(failed_tests) | |
| if failed_tests: | |
| console.print(f"\n[red]β {len(failed_tests)} test(s) failed:[/red]") | |
| for test in failed_tests: | |
| console.print(f" [red]β[/red] {test}") | |
| else: | |
| console.print("\n[bold green]β All tests passed![/bold green]") | |
| console.print(f"\n[cyan]Test Summary:[/cyan] {passed_tests}/{total_tests} passed") | |
| return len(failed_tests) == 0 | |
| async def test_single_endpoint(): | |
| """Interactive endpoint testing""" | |
| console.print("\n[cyan]Available endpoints:[/cyan]") | |
| console.print("1. Generate Bytes") | |
| console.print("2. Generate Key") | |
| console.print("3. Generate Token") | |
| console.print("4. Generate UUID") | |
| console.print("5. Generate Password") | |
| console.print("6. Entropy Status") | |
| console.print("7. System Stats") | |
| console.print("8. Health Check") | |
| choice = input("\nSelect endpoint to test (1-8): ") | |
| async with httpx.AsyncClient() as client: | |
| try: | |
| if choice == "1": | |
| length = int(input("Enter byte length (1-1024): ") or "32") | |
| format_type = input("Enter format (hex/base64/array/raw): ") or "hex" | |
| response = await client.post(f"{API_V2}/generate/bytes", json={ | |
| "length": length, | |
| "format": format_type, | |
| "quantum_bits": 8 | |
| }) | |
| elif choice == "2": | |
| response = await client.post(f"{API_V2}/generate/key", json={ | |
| "algorithm": "AES", | |
| "key_size": 256 | |
| }) | |
| elif choice == "3": | |
| response = await client.post(f"{API_V2}/generate/token", json={ | |
| "length": 32, | |
| "url_safe": True | |
| }) | |
| elif choice == "4": | |
| response = await client.post(f"{API_V2}/generate/uuid", json={ | |
| "version": 4, | |
| "count": 1 | |
| }) | |
| elif choice == "5": | |
| response = await client.post(f"{API_V2}/generate/password", json={ | |
| "length": 16, | |
| "include_uppercase": True, | |
| "include_lowercase": True, | |
| "include_numbers": True, | |
| "include_symbols": True | |
| }) | |
| elif choice == "6": | |
| response = await client.get(f"{API_V2}/quantum/entropy") | |
| elif choice == "7": | |
| response = await client.get(f"{API_V2}/quantum/stats") | |
| elif choice == "8": | |
| response = await client.get(f"{BASE_URL}/health") | |
| else: | |
| console.print("[red]Invalid choice[/red]") | |
| return | |
| # Display response | |
| console.print(f"\n[green]Status Code:[/green] {response.status_code}") | |
| console.print(f"[cyan]Response:[/cyan]") | |
| console.print(json.dumps(response.json(), indent=2)) | |
| except Exception as e: | |
| console.print(f"[red]Error:[/red] {str(e)}") | |
| async def main(): | |
| """Main test function""" | |
| import sys | |
| # Check if API is running | |
| console.print("[yellow]Checking if API is running...[/yellow]") | |
| try: | |
| async with httpx.AsyncClient() as client: | |
| response = await client.get(f"{BASE_URL}/", timeout=2.0) | |
| console.print("[green]β API is running[/green]\n") | |
| except: | |
| console.print("[red]β API is not running![/red]") | |
| console.print("\nPlease start the API server first:") | |
| console.print("[cyan]python run_api.py[/cyan]") | |
| sys.exit(1) | |
| if len(sys.argv) > 1 and sys.argv[1] == "--interactive": | |
| while True: | |
| await test_single_endpoint() | |
| if input("\nTest another endpoint? (y/n): ").lower() != 'y': | |
| break | |
| else: | |
| success = await run_all_tests() | |
| sys.exit(0 if success else 1) | |
| if __name__ == "__main__": | |
| try: | |
| asyncio.run(main()) | |
| except KeyboardInterrupt: | |
| console.print("\n[yellow]Tests interrupted[/yellow]") | |
| except Exception as e: | |
| console.print(f"[red]Error: {str(e)}[/red]") |