|
Download API_GUIDE.md from CatPtain/page_shot: direct link, hf CLI and curl.
- Browser
- Download file 6.26 kB
-
https://huggingface.co/spaces/CatPtain/page_shot/resolve/main/API_GUIDE.md
- Command line
-
hf download hf://spaces/CatPtain/page_shot/API_GUIDE.md
-
curl -L -o API_GUIDE.md https://huggingface.co/spaces/CatPtain/page_shot/resolve/main/API_GUIDE.md
6.26 kB
| # API Authentication & Usage Guide | |
| ## ๐ Setting Up API Key in Hugging Face Spaces | |
| ### Step 1: Generate Secure API Key | |
| ```bash | |
| # Generate random API key (example methods) | |
| node -e "console.log('sk-' + require('crypto').randomBytes(32).toString('hex'))" | |
| # Or use Python | |
| python -c "import secrets; print('sk-' + secrets.token_hex(32))" | |
| ``` | |
| ### Step 2: Configure in HF Spaces | |
| 1. Navigate to your Space: `https://huggingface.co/spaces/your-username/space-name` | |
| 2. Click **"Settings"** tab | |
| 3. Click **"Variables"** section | |
| 4. Add this environment variable: | |
| | Variable | Value | Description | | |
| |----------|-------|-------------| | |
| | `API_KEY` | `sk-your-secure-key-here` | Single API key for authentication | | |
| ### Step 3: Test Authentication | |
| ```bash | |
| # Test without API key (should fail if authentication enabled) | |
| curl -X POST https://your-space.hf.space/screenshot \ | |
| -H "Content-Type: application/json" \ | |
| -d '{"url": "https://example.com"}' | |
| # Test with API key (should work) | |
| curl -X POST https://your-space.hf.space/screenshot \ | |
| -H "Authorization: Bearer your-api-key-here" \ | |
| -H "Content-Type: application/json" \ | |
| -d '{"url": "https://example.com"}' | |
| ``` | |
| ## ๐ Understanding Server Status Responses | |
| ### Normal Operation | |
| ```json | |
| { | |
| "status": "running", | |
| "system": { "cpuUsage": "25%" }, | |
| "queue": { "activeRequests": 1, "queuedRequests": 0 } | |
| } | |
| ``` | |
| ### Server Busy (CPU > 95%) | |
| ```json | |
| { | |
| "status": "busy", | |
| "error": "Server is currently overloaded", | |
| "cpuUsage": "96%", | |
| "queueLength": 3 | |
| } | |
| ``` | |
| ### Queue Full Response | |
| ```json | |
| { | |
| "status": "busy", | |
| "error": "Request queue timeout", | |
| "queueLength": 10 | |
| } | |
| ``` | |
| ## ๐ Implementing Retry Logic | |
| ### JavaScript Retry Pattern | |
| ```javascript | |
| async function screenshotWithRetry(url, options = {}, maxRetries = 3) { | |
| for (let attempt = 1; attempt <= maxRetries; attempt++) { | |
| try { | |
| const response = await fetch('/screenshot', { | |
| method: 'POST', | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| 'Authorization': 'Bearer your-api-key' | |
| }, | |
| body: JSON.stringify({ url, ...options }) | |
| }); | |
| if (response.ok) { | |
| return await response.blob(); | |
| } | |
| if (response.status === 503) { | |
| const error = await response.json(); | |
| if (error.status === 'busy') { | |
| console.log(`Attempt ${attempt}: Server busy, retrying...`); | |
| await new Promise(resolve => setTimeout(resolve, 2000 * attempt)); | |
| continue; | |
| } | |
| } | |
| // Other errors, don't retry | |
| throw new Error(`API Error: ${response.status}`); | |
| } catch (error) { | |
| if (attempt === maxRetries) throw error; | |
| await new Promise(resolve => setTimeout(resolve, 1000 * attempt)); | |
| } | |
| } | |
| } | |
| ``` | |
| ### Python Retry Pattern | |
| ```python | |
| import time | |
| import requests | |
| from typing import Optional | |
| def screenshot_with_retry(url: str, api_key: str, max_retries: int = 3) -> Optional[bytes]: | |
| for attempt in range(1, max_retries + 1): | |
| try: | |
| response = requests.post( | |
| 'https://your-space.hf.space/screenshot', | |
| headers={'Authorization': f'Bearer {api_key}', 'Content-Type': 'application/json'}, | |
| json={'url': url}, | |
| timeout=30 | |
| ) | |
| if response.status_code == 200: | |
| return response.content | |
| if response.status_code == 503: | |
| error_data = response.json() | |
| if error_data.get('status') == 'busy': | |
| print(f"Attempt {attempt}: Server busy (CPU: {error_data.get('cpuUsage', 'N/A')})") | |
| time.sleep(2 * attempt) | |
| continue | |
| response.raise_for_status() | |
| except requests.RequestException as e: | |
| if attempt == max_retries: | |
| raise e | |
| time.sleep(attempt) | |
| return None | |
| ``` | |
| ## ๐จ Rate Limiting & Best Practices | |
| ### Rate Limit Headers | |
| The API returns rate limiting information: | |
| ``` | |
| X-RateLimit-Limit: 100 | |
| X-RateLimit-Remaining: 95 | |
| X-RateLimit-Reset: 1640995200 | |
| ``` | |
| ### Best Practices | |
| 1. **Implement exponential backoff** for retries | |
| 2. **Cache results** when possible | |
| 3. **Use appropriate image quality** (70-80% usually sufficient) | |
| 4. **Monitor your usage** via `/status` endpoint | |
| 5. **Handle queue timeouts** gracefully | |
| ### Production Usage Example | |
| ```javascript | |
| class ScreenshotAPI { | |
| constructor(apiKey, baseUrl) { | |
| this.apiKey = apiKey; | |
| this.baseUrl = baseUrl; | |
| this.requestCount = 0; | |
| this.resetTime = 0; | |
| } | |
| async screenshot(url, options = {}) { | |
| // Check rate limit | |
| if (this.requestCount >= 95 && Date.now() < this.resetTime) { | |
| throw new Error('Rate limit approached, waiting...'); | |
| } | |
| const response = await this.makeRequest('/screenshot', { | |
| method: 'POST', | |
| body: JSON.stringify({ url, ...options }) | |
| }); | |
| // Update rate limit tracking | |
| this.requestCount = parseInt(response.headers.get('X-RateLimit-Remaining') || '0'); | |
| this.resetTime = parseInt(response.headers.get('X-RateLimit-Reset') || '0') * 1000; | |
| return response; | |
| } | |
| async makeRequest(endpoint, options = {}) { | |
| return fetch(this.baseUrl + endpoint, { | |
| ...options, | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| 'Authorization': `Bearer ${this.apiKey}`, | |
| ...options.headers | |
| } | |
| }); | |
| } | |
| } | |
| ``` | |
| ## ๐ง Troubleshooting | |
| ### Common Issues | |
| | Error | Cause | Solution | | |
| |-------|-------|----------| | |
| | `401 Unauthorized` | Missing API key | Add `Authorization: Bearer` header | | |
| | `403 Forbidden` | Invalid API key | Check key spelling/validity | | |
| | `503 Service Unavailable` | Server overloaded | Implement retry with delay | | |
| | `429 Too Many Requests` | Rate limit exceeded | Wait for reset time | | |
| ### Performance Optimization | |
| - Use smaller dimensions for faster processing | |
| - Lower quality settings for non-critical uses | |
| - Batch requests with appropriate delays | |
| - Monitor CPU usage via `/status` |