Spaces:
Paused
Paused
| """ | |
| Documentation Page - Developer docs | |
| """ | |
| from fastapi import Request | |
| def render_docs(): | |
| return """ | |
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>M5 Documentation</title> | |
| <style> | |
| :root { | |
| --bg: #0a0a0f; | |
| --surface: #12121a; | |
| --surface-2: #1a1a24; | |
| --border: rgba(255,255,255,.08); | |
| --text: #f0f0f5; | |
| --muted: #6b6b78; | |
| --primary: #00f0ff; | |
| --primary-dim: rgba(0,240,255,.1); | |
| } | |
| * { margin: 0; padding: 0; box-sizing: border-box; } | |
| body { | |
| font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Display', sans-serif; | |
| background: var(--bg); | |
| color: var(--text); | |
| min-height: 100vh; | |
| } | |
| .container { max-width: 1200px; margin: 0 auto; padding: 0 20px; } | |
| .header { | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| padding: 20px 0; | |
| border-bottom: 1px solid var(--border); | |
| margin-bottom: 40px; | |
| } | |
| .logo { font-size: 24px; font-weight: 700; } | |
| .logo span { color: var(--primary); } | |
| .nav a { color: var(--muted); text-decoration: none; margin-left: 20px; font-size: 14px; } | |
| .nav a:hover { color: var(--text); } | |
| .docs-layout { display: grid; grid-template-columns: 250px 1fr; gap: 40px; } | |
| .sidebar { position: sticky; top: 20px; height: fit-content; } | |
| .sidebar h3 { font-size: 12px; text-transform: uppercase; letter-spacing: 1px; color: var(--muted); margin-bottom: 16px; } | |
| .sidebar a { display: block; color: var(--muted); text-decoration: none; padding: 8px 0; font-size: 14px; } | |
| .sidebar a:hover { color: var(--primary); } | |
| .sidebar a.active { color: var(--primary); } | |
| .content h1 { font-size: 36px; margin-bottom: 24px; } | |
| .content h2 { font-size: 24px; margin: 32px 0 16px; } | |
| .content h3 { font-size: 18px; margin: 24px 0 12px; } | |
| .content p { line-height: 1.7; color: var(--muted); margin-bottom: 16px; } | |
| .content code { background: var(--surface-2); padding: 2px 6px; border-radius: 4px; font-family: 'SF Mono', monospace; font-size: 13px; } | |
| .content pre { background: var(--surface-2); padding: 16px; border-radius: 8px; overflow-x: auto; margin: 16px 0; } | |
| .content pre code { background: none; padding: 0; } | |
| .content ul { margin: 16px 0; padding-left: 20px; color: var(--muted); } | |
| .content li { margin-bottom: 8px; } | |
| .btn { | |
| display: inline-block; | |
| padding: 10px 20px; | |
| background: var(--primary); | |
| color: #000; | |
| text-decoration: none; | |
| border-radius: 8px; | |
| font-weight: 600; | |
| font-size: 14px; | |
| margin: 16px 0; | |
| } | |
| @media (max-width: 768px) { | |
| .docs-layout { grid-template-columns: 1fr; } | |
| .sidebar { display: none; } | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="container"> | |
| <header class="header"> | |
| <div class="logo"><span>M5</span> Documentation</div> | |
| <nav class="nav"> | |
| <a href="/m5-landing">Home</a> | |
| <a href="/api">API Reference</a> | |
| <a href="/sdk">SDK</a> | |
| <a href="/m5">Dashboard</a> | |
| </nav> | |
| </header> | |
| <div class="docs-layout"> | |
| <aside class="sidebar"> | |
| <h3>Getting Started</h3> | |
| <a href="#introduction" class="active">Introduction</a> | |
| <a href="#authentication">Authentication</a> | |
| <a href="#quickstart">Quick Start</a> | |
| <h3 style="margin-top: 24px;">API Reference</h3> | |
| <a href="#chat-api">Chat Completions</a> | |
| <a href="#models-api">Models</a> | |
| <a href="#accounts-api">Accounts</a> | |
| <h3 style="margin-top: 24px;">SDKs</h3> | |
| <a href="#python-sdk">Python SDK</a> | |
| <a href="#js-sdk">JavaScript SDK</a> | |
| <h3 style="margin-top: 24px;">Advanced</h3> | |
| <a href="#tunneling">Tunneling</a> | |
| <a href="#rate-limits">Rate Limits</a> | |
| </aside> | |
| <main class="content"> | |
| <h1 id="introduction">Introduction</h1> | |
| <p>M5 is a local compute gateway that turns your Ollama instance into a public API. It provides OpenAI-compatible endpoints, chat storage, and API key management.</p> | |
| <h2 id="authentication">Authentication</h2> | |
| <p>M5 uses Google OAuth for authentication. Sign in with your Google account to get started. After signing in, you'll receive an API key for programmatic access.</p> | |
| <h2 id="quickstart">Quick Start</h2> | |
| <p>1. Install Ollama locally:</p> | |
| <pre><code>curl https://ollama.com/install.sh | sh</code></pre> | |
| <p>2. Pull a model:</p> | |
| <pre><code>ollama pull llama3.2</code></pre> | |
| <p>3. Sign in to M5 and get your API key</p> | |
| <p>4. Make a request:</p> | |
| <pre><code>curl -X POST https://m5.hf.space/v1/chat/completions \\ | |
| -H "Authorization: Bearer YOUR_API_KEY" \\ | |
| -H "Content-Type: application/json" \\ | |
| -d '{"model":"llama3.2","messages":[{"role":"user","content":"Hello"}]}'</code></pre> | |
| <h1 id="chat-api">Chat Completions API</h1> | |
| <p>OpenAI-compatible chat completions endpoint.</p> | |
| <h3>Endpoint</h3> | |
| <code>POST /v1/chat/completions</code> | |
| <h3>Request Body</h3> | |
| <pre><code>{ | |
| "model": "llama3.2", | |
| "messages": [ | |
| {"role": "user", "content": "Hello"} | |
| ], | |
| "temperature": 0.7, | |
| "max_tokens": 1000, | |
| "stream": false, | |
| "ollama_url": "http://localhost:11434" // Optional | |
| }</code></pre> | |
| <h3>Response</h3> | |
| <pre><code>{ | |
| "id": "chatcmpl-xxx", | |
| "object": "chat.completion", | |
| "created": 1234567890, | |
| "model": "llama3.2", | |
| "choices": [ | |
| { | |
| "index": 0, | |
| "message": { | |
| "role": "assistant", | |
| "content": "Hello! How can I help you?" | |
| }, | |
| "finish_reason": "stop" | |
| } | |
| ], | |
| "usage": { | |
| "prompt_tokens": 10, | |
| "completion_tokens": 20, | |
| "total_tokens": 30 | |
| } | |
| }</code></pre> | |
| <h1 id="models-api">Models API</h1> | |
| <p>List available Ollama models.</p> | |
| <h3>Endpoint</h3> | |
| <code>GET /v1/models</code> | |
| <h3>Response</h3> | |
| <pre><code>{ | |
| "object": "list", | |
| "data": [ | |
| { | |
| "id": "llama3.2", | |
| "object": "model", | |
| "created": 1234567890, | |
| "owned_by": "ollama" | |
| } | |
| ] | |
| }</code></pre> | |
| <h1 id="accounts-api">Accounts API</h1> | |
| <p>Manage your account and API keys.</p> | |
| <h3>Get Account Info</h3> | |
| <code>GET /api/accounts/me</code> | |
| <h3>Create API Key</h3> | |
| <code>POST /api/accounts/api-keys</code> | |
| <h1 id="python-sdk">Python SDK</h1> | |
| <pre><code>from m5 import M5Client | |
| client = M5Client(api_key="your-api-key") | |
| response = client.chat.completions.create( | |
| model="llama3.2", | |
| messages=[{"role": "user", "content": "Hello"}] | |
| ) | |
| print(response.choices[0].message.content)</code></pre> | |
| <h1 id="tunneling">Tunneling</h1> | |
| <p>Expose your local Ollama to the cloud using ngrok:</p> | |
| <pre><code># Start ngrok | |
| ngrok http 11434 | |
| # Register tunnel in M5 UI or API | |
| POST /api/accounts/ollama-tunnel | |
| { | |
| "ollama_public_url": "https://xxx.ngrok-free.app" | |
| }</code></pre> | |
| <h1 id="rate-limits">Rate Limits</h1> | |
| <ul> | |
| <li>60 requests per minute</li> | |
| <li>1000 requests per day</li> | |
| <li>Custom limits available for enterprise</li> | |
| </ul> | |
| </main> | |
| </div> | |
| </div> | |
| </body> | |
| </html> | |
| """ | |