last_edit / server /api_docs.py
Moharek
Deploy Moharek GEO Platform
a74b879
"""
API Documentation System
- OpenAPI/Swagger documentation
- Endpoint discovery
- Schema validation
"""
from fastapi.openapi.utils import get_openapi
from fastapi import FastAPI
import json
from typing import Dict, List, Any, Optional
from pathlib import Path
import os
class APIDocumentation:
"""API documentation generator"""
@staticmethod
def generate_openapi_schema(app: FastAPI) -> Dict[str, Any]:
"""Generate OpenAPI schema"""
return get_openapi(
title="Moharek GEO Platform API",
version="1.0.0",
description="AI-powered Generative Engine Optimization platform",
routes=app.routes,
)
@staticmethod
def get_endpoint_docs() -> List[Dict[str, Any]]:
"""Get documentation for all endpoints"""
return [
{
"path": "/api/crawl",
"method": "POST",
"description": "Crawl website and analyze content",
"parameters": {
"url": "Website URL to crawl",
"org_name": "Organization name",
"org_url": "Organization URL",
"max_pages": "Maximum pages to crawl (default: 3)",
"runs": "Number of runs to average (default: 1)"
},
"response": {
"ok": "Success status",
"message": "Response message",
"mean_score": "Average GEO score",
"median_score": "Median GEO score",
"variance": "Score variance"
},
"rate_limit": "10 requests/hour",
"authentication": "Optional (Bearer token)"
},
{
"path": "/api/jobs",
"method": "POST",
"description": "Enqueue a crawl job",
"parameters": {
"url": "Website URL",
"org_name": "Organization name",
"org_url": "Organization URL",
"max_pages": "Maximum pages (default: 3)",
"runs": "Number of runs (default: 1)"
},
"response": {
"ok": "Success status",
"job_id": "Job ID for tracking"
},
"rate_limit": "30 requests/minute",
"authentication": "Optional"
},
{
"path": "/api/jobs/{job_id}",
"method": "GET",
"description": "Get job status",
"parameters": {
"job_id": "Job ID"
},
"response": {
"ok": "Success status",
"job": "Job details including status and progress"
},
"rate_limit": "100 requests/minute",
"authentication": "Optional"
},
{
"path": "/ws/jobs/{job_id}",
"method": "WebSocket",
"description": "Real-time job progress updates",
"parameters": {
"job_id": "Job ID"
},
"response": "Job status updates in real-time",
"rate_limit": "Unlimited",
"authentication": "Optional"
},
{
"path": "/api/analyze",
"method": "POST",
"description": "Analyze crawled content",
"parameters": {
"job_id": "Job ID (optional)",
"api_keys": "API keys for external services"
},
"response": {
"ok": "Success status",
"analysis": "Content analysis results",
"geo_score": "GEO visibility score",
"competitor_insight": "Competitor analysis"
},
"rate_limit": "20 requests/hour",
"authentication": "Optional"
},
{
"path": "/api/recommendations",
"method": "POST",
"description": "Generate SEO recommendations",
"parameters": {
"job_id": "Job ID (optional)",
"api_keys": "API keys for external services"
},
"response": {
"ok": "Success status",
"recommendations": "List of recommendations",
"audit": "Audit data",
"geo_score": "GEO score"
},
"rate_limit": "20 requests/hour",
"authentication": "Optional"
},
{
"path": "/api/keywords",
"method": "POST",
"description": "Extract and analyze keywords",
"parameters": {
"url": "Website URL",
"max_pages": "Maximum pages (default: 1)",
"enrich": "Enrich with search volume data",
"analytics": "Return analytics data"
},
"response": {
"ok": "Success status",
"keywords": "List of keywords",
"analytics": "Keyword analytics (if requested)"
},
"rate_limit": "15 requests/hour",
"authentication": "Optional"
},
{
"path": "/api/content/generate",
"method": "POST",
"description": "Generate AI content",
"parameters": {
"keyword": "Target keyword",
"lang": "Language (default: en)",
"target_site": "Target website",
"prefer_backend": "AI backend (groq/openai)"
},
"response": {
"ok": "Success status",
"result": "Generated content"
},
"rate_limit": "5 requests/hour",
"authentication": "Optional"
},
{
"path": "/api/content/optimize",
"method": "POST",
"description": "Optimize existing content",
"parameters": {
"content": "Content to optimize",
"keyword": "Target keyword",
"lang": "Language (default: en)"
},
"response": {
"ok": "Success status",
"result": "Optimized content"
},
"rate_limit": "10 requests/hour",
"authentication": "Optional"
},
{
"path": "/api/users/register",
"method": "POST",
"description": "Register new user",
"parameters": {
"email": "User email",
"password": "User password",
"company_id": "Company ID (optional)"
},
"response": {
"ok": "Success status",
"user_id": "New user ID",
"token": "Authentication token"
},
"rate_limit": "5 requests/minute",
"authentication": "None"
},
{
"path": "/api/users/login",
"method": "POST",
"description": "Login user",
"parameters": {
"email": "User email",
"password": "User password"
},
"response": {
"ok": "Success status",
"token": "Authentication token",
"user": "User details"
},
"rate_limit": "10 requests/minute",
"authentication": "None"
},
{
"path": "/api/users/me",
"method": "GET",
"description": "Get current user",
"parameters": {},
"response": {
"ok": "Success status",
"user": "User details"
},
"rate_limit": "100 requests/minute",
"authentication": "Required (Bearer token)"
},
{
"path": "/api/notifications",
"method": "GET",
"description": "Get user notifications",
"parameters": {
"unread_only": "Only unread notifications"
},
"response": {
"ok": "Success status",
"notifications": "List of notifications",
"count": "Total count"
},
"rate_limit": "50 requests/minute",
"authentication": "Required"
},
{
"path": "/api/2fa/setup",
"method": "POST",
"description": "Setup two-factor authentication",
"parameters": {},
"response": {
"ok": "Success status",
"secret": "2FA secret",
"qr_code": "QR code for authenticator app"
},
"rate_limit": "5 requests/minute",
"authentication": "Required"
},
{
"path": "/api/support/tickets",
"method": "POST",
"description": "Create support ticket",
"parameters": {
"subject": "Ticket subject",
"description": "Ticket description",
"category": "Ticket category",
"priority": "Priority level"
},
"response": {
"ok": "Success status",
"ticket_id": "New ticket ID"
},
"rate_limit": "10 requests/hour",
"authentication": "Required"
},
{
"path": "/api/ads/dashboard",
"method": "GET",
"description": "Get ads dashboard data",
"parameters": {
"demo": "Use demo data",
"days": "Number of days (default: 30)"
},
"response": {
"ok": "Success status",
"summary": "KPI summary",
"campaigns": "Campaign data"
},
"rate_limit": "20 requests/hour",
"authentication": "Optional"
},
{
"path": "/api/geo/visibility",
"method": "POST",
"description": "Check AI visibility score",
"parameters": {
"brand": "Brand name",
"queries": "Search queries",
"api_keys": "API keys"
},
"response": {
"ok": "Success status",
"result": "Visibility score and details"
},
"rate_limit": "20 requests/hour",
"authentication": "Optional"
},
{
"path": "/health",
"method": "GET",
"description": "Health check endpoint",
"parameters": {},
"response": {
"status": "Service status",
"service": "Service name"
},
"rate_limit": "Unlimited",
"authentication": "None"
}
]
@staticmethod
def get_error_codes() -> Dict[str, str]:
"""Get error code documentation"""
return {
"200": "OK - Request successful",
"201": "Created - Resource created successfully",
"400": "Bad Request - Invalid parameters",
"401": "Unauthorized - Authentication required",
"403": "Forbidden - Insufficient permissions",
"404": "Not Found - Resource not found",
"429": "Too Many Requests - Rate limit exceeded",
"500": "Internal Server Error - Server error",
"503": "Service Unavailable - Service temporarily unavailable"
}
@staticmethod
def get_authentication_docs() -> Dict[str, Any]:
"""Get authentication documentation"""
return {
"methods": [
{
"type": "Bearer Token",
"description": "JWT token in Authorization header",
"example": "Authorization: Bearer <token>",
"endpoints": "Most endpoints"
},
{
"type": "API Key",
"description": "API key for external services",
"example": "api_keys: {openai: <key>, groq: <key>}",
"endpoints": "Content generation, analysis"
}
],
"token_expiry": "24 hours",
"refresh": "Login again to get new token"
}
@staticmethod
def get_rate_limit_docs() -> Dict[str, Any]:
"""Get rate limit documentation"""
return {
"default": "100 requests/minute",
"endpoints": {
"/api/crawl": "10 requests/hour",
"/api/analyze": "20 requests/hour",
"/api/keywords": "15 requests/hour",
"/api/content/generate": "5 requests/hour",
"/api/search": "30 requests/hour"
},
"headers": {
"X-RateLimit-Limit": "Maximum requests allowed",
"X-RateLimit-Remaining": "Remaining requests",
"Retry-After": "Seconds to wait before retry"
},
"exceeded": "Returns 429 status code"
}
@staticmethod
def save_documentation(output_path: str = None):
"""Save documentation to file"""
if not output_path:
output_path = Path(os.environ.get('OUTPUT_DIR', './output')) / 'api_docs.json'
docs = {
"title": "Moharek GEO Platform API",
"version": "1.0.0",
"description": "AI-powered Generative Engine Optimization platform",
"endpoints": APIDocumentation.get_endpoint_docs(),
"error_codes": APIDocumentation.get_error_codes(),
"authentication": APIDocumentation.get_authentication_docs(),
"rate_limits": APIDocumentation.get_rate_limit_docs()
}
Path(output_path).write_text(json.dumps(docs, indent=2))
return output_path
# Generate documentation on import
try:
APIDocumentation.save_documentation()
except Exception as e:
print(f"Warning: Could not save API documentation: {e}")