API Authentication & Usage Guide
π Setting Up API Key in Hugging Face Spaces
Step 1: Generate Secure API Key
node -e "console.log('sk-' + require('crypto').randomBytes(32).toString('hex'))"
python -c "import secrets; print('sk-' + secrets.token_hex(32))"
Step 2: Configure in HF Spaces
- Navigate to your Space:
https://huggingface.co/spaces/your-username/space-name
- Click "Settings" tab
- Click "Variables" section
- Add this environment variable:
Variable |
Value |
Description |
API_KEY |
sk-your-secure-key-here |
Single API key for authentication |
Step 3: Test Authentication
curl -X POST https://your-space.hf.space/screenshot \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com"}'
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
{
"status": "running",
"system": { "cpuUsage": "25%" },
"queue": { "activeRequests": 1, "queuedRequests": 0 }
}
Server Busy (CPU > 95%)
{
"status": "busy",
"error": "Server is currently overloaded",
"cpuUsage": "96%",
"queueLength": 3
}
Queue Full Response
{
"status": "busy",
"error": "Request queue timeout",
"queueLength": 10
}
π Implementing Retry Logic
JavaScript Retry Pattern
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;
}
}
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
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
- Implement exponential backoff for retries
- Cache results when possible
- Use appropriate image quality (70-80% usually sufficient)
- Monitor your usage via
/status
endpoint
- Handle queue timeouts gracefully
Production Usage Example
class ScreenshotAPI {
constructor(apiKey, baseUrl) {
this.apiKey = apiKey;
this.baseUrl = baseUrl;
this.requestCount = 0;
this.resetTime = 0;
}
async screenshot(url, options = {}) {
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 })
});
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