- Created docs_server.py with HTTP basic authentication - Added start-docs-server.sh for easy startup - Updated README.md with documentation access instructions - Provides working authentication when .htaccess isn't supported Usage: ./start-docs-server.sh [port] Credentials: langmem / langmem2025 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
105 lines
3.4 KiB
Python
Executable File
105 lines
3.4 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""
|
|
Simple authenticated web server for LangMem documentation
|
|
"""
|
|
|
|
import http.server
|
|
import socketserver
|
|
import base64
|
|
import os
|
|
from urllib.parse import parse_qs
|
|
|
|
# Authentication credentials
|
|
USERNAME = "langmem"
|
|
PASSWORD = "langmem2025"
|
|
|
|
class AuthHTTPRequestHandler(http.server.SimpleHTTPRequestHandler):
|
|
"""HTTP handler with basic authentication"""
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, directory="docs", **kwargs)
|
|
|
|
def do_GET(self):
|
|
"""Handle GET requests with authentication"""
|
|
if self.authenticate():
|
|
super().do_GET()
|
|
else:
|
|
self.send_auth_request()
|
|
|
|
def authenticate(self):
|
|
"""Check if request has valid authentication"""
|
|
auth_header = self.headers.get('Authorization')
|
|
|
|
if not auth_header:
|
|
return False
|
|
|
|
try:
|
|
auth_type, credentials = auth_header.split(' ', 1)
|
|
if auth_type.lower() != 'basic':
|
|
return False
|
|
|
|
decoded = base64.b64decode(credentials).decode('utf-8')
|
|
username, password = decoded.split(':', 1)
|
|
|
|
return username == USERNAME and password == PASSWORD
|
|
|
|
except Exception:
|
|
return False
|
|
|
|
def send_auth_request(self):
|
|
"""Send authentication request to client"""
|
|
self.send_response(401)
|
|
self.send_header('WWW-Authenticate', 'Basic realm="LangMem Documentation"')
|
|
self.send_header('Content-type', 'text/html')
|
|
self.end_headers()
|
|
|
|
html = """
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>Authentication Required</title>
|
|
<style>
|
|
body { font-family: Arial, sans-serif; text-align: center; margin-top: 100px; }
|
|
.container { max-width: 400px; margin: 0 auto; padding: 20px; border: 1px solid #ccc; border-radius: 10px; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="container">
|
|
<h2>🔐 LangMem Documentation</h2>
|
|
<p>Authentication required to access documentation.</p>
|
|
<p><strong>Username:</strong> langmem<br>
|
|
<strong>Password:</strong> langmem2025</p>
|
|
<p>Please refresh the page and enter your credentials when prompted.</p>
|
|
</div>
|
|
</body>
|
|
</html>
|
|
"""
|
|
self.wfile.write(html.encode())
|
|
|
|
def start_server(port=8080):
|
|
"""Start the authenticated documentation server"""
|
|
try:
|
|
with socketserver.TCPServer(("", port), AuthHTTPRequestHandler) as httpd:
|
|
print(f"🌐 LangMem Documentation Server started!")
|
|
print(f"📍 URL: http://localhost:{port}")
|
|
print(f"🔑 Username: {USERNAME}")
|
|
print(f"🔑 Password: {PASSWORD}")
|
|
print(f"🛑 Press Ctrl+C to stop the server")
|
|
print("=" * 50)
|
|
httpd.serve_forever()
|
|
except KeyboardInterrupt:
|
|
print("\n🛑 Server stopped by user")
|
|
except Exception as e:
|
|
print(f"❌ Error starting server: {e}")
|
|
|
|
if __name__ == "__main__":
|
|
import sys
|
|
|
|
port = 8080
|
|
if len(sys.argv) > 1:
|
|
try:
|
|
port = int(sys.argv[1])
|
|
except ValueError:
|
|
print("Invalid port number. Using default port 8080.")
|
|
|
|
start_server(port) |