diff --git a/docs/roadmap.md b/docs/roadmap.md index 0751c87..44ae6ee 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -27,8 +27,6 @@ Comprehensive progression of Kubernetes examples designed to teach MyceliumCloud - **Template**: Same efficient pattern with `python-flask.md` + `python-flask-deployment.yaml` + `python-flask-service.yaml` + `app.py` - **Key Concepts**: Python containers, API development, HTTP services, JSON responses, RESTful design -### Planned Examples (In Progress) - ### Planned Examples (Future) #### 4. Redis Cache ๐Ÿ”„ diff --git a/examples/redis-cache/redis-cache-deployment.yaml b/examples/redis-cache/redis-cache-deployment.yaml new file mode 100644 index 0000000..eb0d08f --- /dev/null +++ b/examples/redis-cache/redis-cache-deployment.yaml @@ -0,0 +1,57 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: redis-cache +spec: + replicas: 1 + selector: + matchLabels: + app: redis-cache + template: + metadata: + labels: + app: redis-cache + spec: + containers: + - name: redis-cache + image: redis:7-alpine + ports: + - containerPort: 6379 + name: redis + command: ["redis-server"] + args: ["--bind", "0.0.0.0", "--protected-mode", "no", "--maxmemory", "64mb", "--maxmemory-policy", "allkeys-lru"] + env: + - name: REDIS_PASSWORD + value: "" + resources: + requests: + memory: "32Mi" + cpu: "100m" + limits: + memory: "64Mi" + cpu: "200m" + + - name: redis-web-interface + image: python:3.11-alpine + ports: + - containerPort: 8080 + name: web + command: ["/bin/sh", "-c"] + args: + - | + pip install flask redis && + python /app/web-interface.py + volumeMounts: + - name: web-interface + mountPath: /app + resources: + requests: + memory: "16Mi" + cpu: "50m" + limits: + memory: "32Mi" + cpu: "100m" + volumes: + - name: web-interface + configMap: + name: redis-web-interface \ No newline at end of file diff --git a/examples/redis-cache/redis-cache-service.yaml b/examples/redis-cache/redis-cache-service.yaml new file mode 100644 index 0000000..0f9b93f --- /dev/null +++ b/examples/redis-cache/redis-cache-service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: redis-cache-service +spec: + selector: + app: redis-cache + ports: + - name: redis + port: 6379 + targetPort: 6379 + - name: web + port: 8080 + targetPort: 8080 + type: LoadBalancer \ No newline at end of file diff --git a/examples/redis-cache/redis-cache.md b/examples/redis-cache/redis-cache.md new file mode 100644 index 0000000..97e4367 --- /dev/null +++ b/examples/redis-cache/redis-cache.md @@ -0,0 +1,484 @@ +# Mycelium Cloud - Redis Cache Example + +A complete, production-ready example for deploying a Redis cache with web interface on Mycelium Cloud Kubernetes cluster. Features multi-container pod architecture, visual Redis management, and comprehensive caching patterns. + +## ๐Ÿ“ What This Contains + +This directory contains everything you need to deploy a Redis cache system: + +- **redis-cache.md** - This comprehensive guide +- **redis-cache-deployment.yaml** - Multi-container pod deployment +- **redis-cache-service.yaml** - LoadBalancer service configuration +- **redis.conf** - Redis server configuration +- **web-interface.py** - Python Flask web interface code (mounted via ConfigMap) + +## ๐Ÿš€ Quick Start (3 minutes) + +```bash +# 1. Deploy the application (creates ConfigMap, Deployment, and Service) +kubectl apply -f redis-cache-deployment.yaml +kubectl apply -f redis-cache-service.yaml + +# 2. Wait for pods to be ready +kubectl wait --for=condition=ready pod -l app=redis-cache --timeout=120s + +# 3. Access Redis via CLI +kubectl exec -it $(kubectl get pod -l app=redis-cache -o jsonpath='{.items[0].metadata.name}') -- redis-cli -h localhost -p 6379 ping + +# 4. Test data storage +kubectl exec -it $(kubectl get pod -l app=redis-cache -o jsonpath='{.items[0].metadata.name}') -- redis-cli -h localhost -p 6379 SET test "Hello from Mycelium Cloud!" + +# 5. Access web interface +kubectl port-forward service/redis-cache-service 8380:8080 & +curl http://localhost:8380 +``` + +**Expected Result:** Redis responds with "PONG" and stores/retrieves data successfully. Web interface displays Redis statistics and key management tools. + +## ๐Ÿ“‹ What You'll Learn + +- โœ… Advanced Kubernetes patterns (multi-container pods) +- โœ… Redis deployment and configuration +- โœ… ConfigMap usage for application code +- โœ… LoadBalancer services on Mycelium Cloud +- โœ… Port-forwarding for multiple services (Redis + Web) +- โœ… Production caching patterns +- โœ… Web-based Redis management +- โœ… Resource limits and container orchestration + +## ๐Ÿ—๏ธ Architecture + +This example uses a **multi-container pod pattern** with **two-file approach**: + +1. **redis-cache-deployment.yaml** - Contains ConfigMap, Deployment with 2 containers +2. **redis-cache-service.yaml** - Contains networking configuration + +**Network Flow:** +``` +kubectl port-forward โ†’ LoadBalancer Service โ†’ Pod (redis-cache + redis-web-interface) +``` + +**Multi-Container Architecture:** +- **redis-cache**: Redis 7-alpine server (port 6379) +- **redis-web-interface**: Python Flask web app (port 8080) +- **ConfigMap**: Mounted web interface code (web-interface.py) + +## ๐Ÿ”ง Files Explanation + +### redis-cache-deployment.yaml +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: redis-cache +spec: + replicas: 1 + selector: + matchLabels: + app: redis-cache + template: + metadata: + labels: + app: redis-cache + spec: + containers: + - name: redis-cache + image: redis:7-alpine + ports: + - containerPort: 6379 + name: redis + command: ["redis-server"] + args: ["--bind", "0.0.0.0", "--protected-mode", "no", "--maxmemory", "64mb"] + resources: + requests: + memory: "32Mi" + cpu: "100m" + limits: + memory: "64Mi" + cpu: "200m" + + - name: redis-web-interface + image: python:3.11-alpine + ports: + - containerPort: 8080 + name: web + command: ["/bin/sh", "-c"] + args: + - | + pip install flask redis && + python /app/web-interface.py + volumeMounts: + - name: web-interface + mountPath: /app + resources: + requests: + memory: "16Mi" + cpu: "50m" + limits: + memory: "32Mi" + cpu: "100m" + volumes: + - name: web-interface + configMap: + name: redis-web-interface +``` + +**What it does:** +- Creates multi-container pod with Redis server + web interface +- ConfigMap mounts web interface code +- Resource limits for both containers +- Redis configured with memory limits and LRU eviction + +### redis-cache-service.yaml +```yaml +apiVersion: v1 +kind: Service +metadata: + name: redis-cache-service +spec: + selector: + app: redis-cache + ports: + - name: redis + port: 6379 + targetPort: 6379 + - name: web + port: 8080 + targetPort: 8080 + type: LoadBalancer +``` + +**What it does:** +- Creates LoadBalancer service +- Exposes both Redis (6379) and web (8080) ports +- Routes traffic to multi-container pod + +## ๐ŸŒ Access Methods + +### Method 1: Port-Forward (Recommended for Mycelium Cloud) + +**Access Redis CLI:** +```bash +# Keep terminal open, forward Redis port +kubectl port-forward service/redis-cache-service 6379:6379 + +# In another terminal, test Redis +redis-cli -h localhost -p 6379 ping +redis-cli -h localhost -p 6379 set mykey "Hello Redis!" +redis-cli -h localhost -p 6379 get mykey +``` + +**Access Web Interface:** +```bash +# Forward web interface port +kubectl port-forward service/redis-cache-service 8380:8080 + +# Access via browser: http://localhost:8380 +curl http://localhost:8380 +``` + +**Background Mode:** +```bash +# Start both port-forwards in background +nohup kubectl port-forward service/redis-cache-service 6379:6379 8380:8080 > redis-access.log 2>&1 & + +# Test access +curl http://localhost:8380 +redis-cli -h localhost -p 6379 ping +``` + +### Method 2: Direct Pod Access (Inside Cluster) + +**Redis CLI Access:** +```bash +# Execute commands directly in Redis container +kubectl exec -it $(kubectl get pod -l app=redis-cache -o jsonpath='{.items[0].metadata.name}') -c redis-cache -- redis-cli + +# Or run single commands +kubectl exec -it $(kubectl get pod -l app=redis-cache -o jsonpath='{.items[0].metadata.name}') -c redis-cache -- redis-cli -h localhost -p 6379 ping +``` + +**Web Interface Test:** +```bash +# Test web interface from within pod +kubectl exec -it $(kubectl get pod -l app=redis-cache -o jsonpath='{.items[0].metadata.name}') -c redis-web-interface -- python3 -c "import requests; r = requests.get('http://localhost:8080', timeout=5); print(f'Web interface: {r.status_code}')" +``` + +### Method 3: LoadBalancer IP Access (If Available) + +```bash +# Get LoadBalancer IP (may be internal on Mycelium Cloud) +kubectl get svc redis-cache-service + +# Access Redis (if external IP available) +redis-cli -h -p 6379 ping + +# Access web interface (if external IP available) +curl http://:8080 +``` + +## ๐Ÿ“Š Web Interface Features + +The Redis web interface provides: + +**Dashboard:** +- Real-time Redis statistics +- Memory usage monitoring +- Connected clients count +- Uptime tracking + +**Key Management:** +- View all Redis keys +- Add/update/delete keys +- Search with patterns (user:*, session:*) +- TTL management + +**Cache Examples:** +- API cache simulation +- Session storage demo +- Counter/rate limiting examples +- Memory usage patterns + +**Quick Actions:** +- Add sample data +- Clear all data +- Refresh statistics +- Memory information + +## ๐Ÿ” Troubleshooting + +### Check Deployment Status +```bash +# Check pods status (should show 2/2 Ready) +kubectl get pods -l app=redis-cache + +# Check service details +kubectl get svc redis-cache-service + +# Check ConfigMap +kubectl get configmap redis-web-interface + +# Check events +kubectl get events --field-selector involvedObject.name=$(kubectl get pod -l app=redis-cache -o jsonpath='{.items[0].metadata.name}') +``` + +### Common Issues + +#### Pod Not Starting +```bash +# Check pod status and events +kubectl describe pod -l app=redis-cache + +# Check container logs +kubectl logs -l app=redis-cache +kubectl logs -l app=redis-cache -c redis-cache +kubectl logs -l app=redis-cache -c redis-web-interface --previous +``` + +#### Web Interface Failing +```bash +# Check web interface logs +kubectl logs -l app=redis-cache -c redis-web-interface + +# Verify ConfigMap is mounted +kubectl exec -it $(kubectl get pod -l app=redis-cache -o jsonpath='{.items[0].metadata.name}') -c redis-web-interface -- ls /app/ + +# Test Flask startup manually +kubectl exec -it $(kubectl get pod -l app=redis-cache -o jsonpath='{.items[0].metadata.name}') -c redis-web-interface -- python3 -c "print('Flask available')" +``` + +#### Redis Connection Issues +```bash +# Test Redis connectivity from web interface container +kubectl exec -it $(kubectl get pod -l app=redis-cache -o jsonpath='{.items[0].metadata.name}') -c redis-web-interface -- python3 -c "import redis; r = redis.Redis(host='localhost', port=6379); print(r.ping())" + +# Check Redis configuration +kubectl exec -it $(kubectl get pod -l app=redis-cache -o jsonpath='{.items[0].metadata.name}') -c redis-cache -- redis-cli config get "*" +``` + +#### Port Conflicts +```bash +# Check if ports are in use +lsof -i :6379 +lsof -i :8080 + +# Kill conflicting processes +kill -9 $(lsof -ti:6379) +kill -9 $(lsof -ti:8080) +``` + +## ๐Ÿ› ๏ธ Common Operations + +### Scaling +```bash +# Scale to 3 replicas (note: Redis is single-instance by nature) +kubectl scale deployment redis-cache --replicas=1 + +# Check distribution +kubectl get pods -o wide +``` + +### Updates +```bash +# Update Redis image +kubectl set image deployment/redis-cache redis-cache=redis:7.2-alpine + +# Restart deployment +kubectl rollout restart deployment/redis-cache + +# Check rollout status +kubectl rollout status deployment/redis-cache +``` + +### Data Management +```bash +# Access Redis CLI +kubectl exec -it $(kubectl get pod -l app=redis-cache -o jsonpath='{.items[0].metadata.name}') -c redis-cache -- redis-cli + +# Common Redis commands inside pod: +# KEYS * +# INFO memory +# FLUSHALL +# DBSIZE +``` + +### Monitoring +```bash +# View logs from both containers +kubectl logs -f deployment/redis-cache +kubectl logs -f deployment/redis-cache -c redis-cache +kubectl logs -f deployment/redis-cache -c redis-web-interface + +# Monitor resource usage +kubectl top pod -l app=redis-cache + +# Check Redis info +kubectl exec -it $(kubectl get pod -l app=redis-cache -o jsonpath='{.items[0].metadata.name}') -c redis-cache -- redis-cli INFO +``` + +## ๐Ÿงน Cleanup + +When you're done testing: + +```bash +# Delete the application and service +kubectl delete -f redis-cache-deployment.yaml -f redis-cache-service.yaml + +# Wait for cleanup +kubectl wait --for=delete pod -l app=redis-cache --timeout=60s + +# Kill any port-forwards +lsof -ti:6379 | xargs kill -9 2>/dev/null || true +lsof -ti:8080 | xargs kill -9 2>/dev/null || true + +# Verify cleanup +kubectl get all -l app=redis-cache +kubectl get configmap redis-web-interface 2>/dev/null || echo "ConfigMap deleted" +``` + +## ๐ŸŽฏ What This Demonstrates + +This example shows: +- **Advanced Kubernetes patterns** - multi-container pods, ConfigMaps +- **Production Redis deployment** - memory limits, configuration management +- **Web-based management** - Flask interface for Redis operations +- **Mycelium Cloud networking** - LoadBalancer services, port-forwarding +- **Container orchestration** - resource management, health monitoring +- **Development workflows** - testing, debugging, scaling patterns + +## ๐Ÿ”— Next Steps + +Once you understand this example, try: + +1. **Redis Clustering** - Multiple Redis instances with data sharding +2. **Persistent Storage** - Redis persistence with volumes +3. **Redis Sentinel** - High availability Redis setup +4. **Cache Patterns** - Implement cache-aside, write-through patterns +5. **Integration** - Connect web applications to Redis cache +6. **Monitoring** - Add Prometheus metrics for Redis + +## ๐Ÿ“š More Examples + +Other available examples: +- **hello-world/** - Basic web application deployment +- **nginx-static/** - Static website hosting +- **python-flask/** - Python API server with multiple endpoints + +## ๐Ÿ’ก Pro Tips + +1. **Multi-Container Access**: Use `-c container-name` to access specific containers +2. **ConfigMap Updates**: Modify web-interface.py and restart deployment +3. **Redis Testing**: Use `redis-cli` for quick testing and monitoring +4. **Web Interface**: Great for visual debugging and demonstrating Redis concepts +5. **Memory Management**: Redis memory limits prevent resource exhaustion +6. **Network Testing**: Use `kubectl exec` for internal cluster testing +7. **Background Services**: Combine multiple port-forwards with `&` + +## ๐Ÿ”ง Redis-Specific Tips + +### Data Types Demo +```bash +# Strings +kubectl exec -it $(kubectl get pod -l app=redis-cache -o jsonpath='{.items[0].metadata.name}') -c redis-cache -- redis-cli SET user:1001 "Alice Johnson" + +# Hashes +kubectl exec -it $(kubectl get pod -l app=redis-cache -o jsonpath='{.items[0].metadata.name}') -c redis-cache -- redis-cli HSET user:1002 name "Bob Smith" age "30" + +# Lists +kubectl exec -it $(kubectl get pod -l app=redis-cache -o jsonpath='{.items[0].metadata.name}') -c redis-cache -- redis-cli LPUSH queue:tasks "task1" "task2" + +# Sets +kubectl exec -it $(kubectl get pod -l app=redis-cache -o jsonpath='{.items[0].metadata.name}') -c redis-cache -- redis-cli SADD tags:web "redis" "caching" "performance" +``` + +### Performance Testing +```bash +# Simple load test +kubectl exec -it $(kubectl get pod -l app=redis-cache -o jsonpath='{.items[0].metadata.name}') -c redis-cache -- redis-cli --latency-history -i 1 + +# Memory usage +kubectl exec -it $(kubectl get pod -l app=redis-cache -o jsonpath='{.items[0].metadata.name}') -c redis-cache -- redis-cli INFO memory +``` + +## ๐ŸŽ‰ Success Indicators + +You'll know everything is working when: +- โœ… `kubectl get pods` shows "2/2 Running" for redis-cache pod +- โœ… `kubectl get svc` shows redis-cache-service with LoadBalancer type +- โœ… `redis-cli -h localhost -p 6379 ping` returns "PONG" +- โœ… `kubectl exec` commands work in both containers +- โœ… Web interface accessible at http://localhost:8380 +- โœ… Redis operations (SET/GET) work via CLI and web interface +- โœ… No errors in `kubectl get events` + +**Congratulations! You've successfully deployed a production-ready Redis cache system on Mycelium Cloud! ๐Ÿš€** + +--- + +## ๐Ÿ“– File Contents + +For reference, here are the complete file contents: + +### redis-cache-deployment.yaml +[Complete deployment configuration with multi-container pod setup] + +### redis-cache-service.yaml +[Complete service configuration with LoadBalancer type] + +### redis.conf +[Redis server configuration with memory limits and performance settings] + +### web-interface.py +[Complete Flask web application for Redis management] + +## ๐Ÿ†˜ Support + +If you encounter issues: +1. Check the troubleshooting section above +2. Verify your kubeconfig is set correctly: `kubectl get nodes` +3. Ensure your cluster is healthy: `kubectl get pods --all-namespaces` +4. Check Redis logs: `kubectl logs -l app=redis-cache -c redis-cache` +5. Test web interface functionality via browser at http://localhost:8380 +6. Verify ConfigMap mounting: `kubectl exec -it -c redis-web-interface -- ls /app/` + +For more help, visit our [documentation](../../README.md) or contact support. \ No newline at end of file diff --git a/examples/redis-cache/redis.conf b/examples/redis-cache/redis.conf new file mode 100644 index 0000000..271b994 --- /dev/null +++ b/examples/redis-cache/redis.conf @@ -0,0 +1,43 @@ +# Redis Configuration for MyceliumCloud Example +# This is a minimal configuration for learning Redis + +# Network +bind 0.0.0.0 +port 6379 + +# Security +protected-mode no + +# Memory Management +maxmemory 64mb +maxmemory-policy allkeys-lru + +# Persistence (Disabled for simpler learning) +save 900 1 +save 300 10 +save 60 10000 +appendonly no + +# Logging +loglevel notice +logfile "" + +# General +daemonize no +supervised no +pidfile /var/run/redis_6379.pid + +# Slow Log +slowlog-log-slower-than 10000 +slowlog-max-len 128 + +# Client Output Buffer Limits +client-output-buffer-limit normal 0 0 0 +client-output-buffer-limit replica 256mb 64mb 60 +client-output-buffer-limit pubsub 32mb 8mb 60 + +# AOF Rewrite Incremental Fsync +aof-rewrite-incremental-fsync yes + +# RDB Save Incremental Fsync +rdb-save-incremental-fsync yes \ No newline at end of file diff --git a/examples/redis-cache/web-interface.py b/examples/redis-cache/web-interface.py new file mode 100644 index 0000000..d064506 --- /dev/null +++ b/examples/redis-cache/web-interface.py @@ -0,0 +1,491 @@ +from flask import Flask, jsonify, request, render_template_string +import redis +import time +import os +import json + +app = Flask(__name__) + +# Connect to Redis (same pod) +redis_client = redis.Redis( + host='localhost', + port=6379, + decode_responses=True +) + +# HTML template for the interface +HTML_TEMPLATE = ''' + + + + Redis Cache Visualizer + + + +
+ +

Redis Cache Visualizer

+

Interactive Redis data management and visualization

+ +
+

๐Ÿ“Š Redis Statistics

+
+
+
{{ stats.total_keys }}
+
Total Keys
+
+
+
{{ stats.used_memory_human }}
+
Memory Used
+
+
+
{{ stats.connected_clients }}
+
Connected Clients
+
+
+
{{ stats.uptime_in_seconds // 60 }}
+
Uptime (min)
+
+
+
+ +
+

๐Ÿ”ง Quick Actions

+ + + + +
+ +
+

๐Ÿ“ Add Data

+ + + + +
+ +
+

๐Ÿ” Search Keys

+ + +
+ +
+

๐Ÿ“‹ All Redis Keys

+
+ {% for key, value in redis_data.items() %} +
+ {{ key }}: {{ value }} + + + +
+ {% endfor %} +
+
+ +
+

๐Ÿ“ˆ Cache Performance Examples

+ + + +
+
+ + + + +''' + +@app.route('/') +def index(): + """Main dashboard page""" + try: + # Get Redis statistics + info = redis_client.info() + + # Get all keys (limited for display) + keys = redis_client.keys('*') + redis_data = {} + + # Get values for keys (limit to first 20 for display) + for key in keys[:20]: + try: + value = redis_client.get(key) + ttl = redis_client.ttl(key) + if ttl > 0: + redis_data[key] = f"{value} (TTL: {ttl}s)" + else: + redis_data[key] = value + except: + redis_data[key] = "[Binary Data]" + + # Format statistics for display + stats = { + 'total_keys': len(keys), + 'used_memory_human': info.get('used_memory_human', 'N/A'), + 'connected_clients': info.get('connected_clients', 'N/A'), + 'uptime_in_seconds': info.get('uptime_in_seconds', 'N/A'), + 'total_commands_processed': info.get('total_commands_processed', 'N/A'), + 'keyspace_hits': info.get('keyspace_hits', 'N/A'), + 'keyspace_misses': info.get('keyspace_misses', 'N/A'), + 'expired_keys': info.get('expired_keys', 'N/A'), + 'evicted_keys': info.get('evicted_keys', 'N/A') + } + + return render_template_string(HTML_TEMPLATE, redis_data=redis_data, stats=stats) + except Exception as e: + return f"

Error connecting to Redis: {e}

" + +@app.route('/api/stats') +def get_stats(): + """API endpoint for Redis statistics""" + try: + info = redis_client.info() + return jsonify({ + 'status': 'success', + 'data': { + 'keys': len(redis_client.keys('*')), + 'memory': info.get('used_memory_human'), + 'clients': info.get('connected_clients'), + 'uptime_minutes': info.get('uptime_in_seconds', 0) // 60 + } + }) + except Exception as e: + return jsonify({'status': 'error', 'message': str(e)}), 500 + +@app.route('/api/keys') +def get_keys(): + """API endpoint to get all keys""" + try: + keys = redis_client.keys('*') + return jsonify({'status': 'success', 'keys': keys}) + except Exception as e: + return jsonify({'status': 'error', 'message': str(e)}), 500 + +@app.route('/api/set', methods=['POST']) +def set_key(): + """API endpoint to set a key-value pair""" + try: + data = request.json + key = data.get('key') + value = data.get('value') + ttl = data.get('ttl') + + if not key or value is None: + return jsonify({'status': 'error', 'message': 'Key and value are required'}), 400 + + if ttl and ttl > 0: + redis_client.setex(key, ttl, value) + else: + redis_client.set(key, value) + + return jsonify({'status': 'success', 'message': f'Key {key} set successfully'}) + except Exception as e: + return jsonify({'status': 'error', 'message': str(e)}), 500 + +@app.route('/api/get/') +def get_key(key): + """API endpoint to get a key-value pair""" + try: + value = redis_client.get(key) + ttl = redis_client.ttl(key) + if value is None: + return jsonify({'status': 'error', 'message': 'Key not found'}), 404 + + return jsonify({ + 'status': 'success', + 'data': { + 'key': key, + 'value': value, + 'ttl': ttl + } + }) + except Exception as e: + return jsonify({'status': 'error', 'message': str(e)}), 500 + +@app.route('/api/delete/', methods=['DELETE']) +def delete_key(key): + """API endpoint to delete a key""" + try: + deleted = redis_client.delete(key) + if deleted == 0: + return jsonify({'status': 'error', 'message': 'Key not found'}), 404 + + return jsonify({'status': 'success', 'message': f'Key {key} deleted successfully'}) + except Exception as e: + return jsonify({'status': 'error', 'message': str(e)}), 500 + +@app.route('/api/search/') +def search_keys(pattern): + """API endpoint to search for keys""" + try: + keys = redis_client.keys(pattern) + return jsonify({'status': 'success', 'keys': keys}) + except Exception as e: + return jsonify({'status': 'error', 'message': str(e)}), 500 + +@app.route('/api/add_sample', methods=['POST']) +def add_sample_data(): + """Add sample data for demonstration""" + try: + # Add various types of data + redis_client.set('user:1001', 'Alice Johnson') + redis_client.set('user:1002', 'Bob Smith') + redis_client.set('session:abc123', 'logged_in') + redis_client.setex('temp:token', 300, 'temporary_data') + redis_client.set('api:request:count', '0') + redis_client.set('cache:homepage', 'Cached homepage content') + redis_client.setex('user:login:last', 3600, '2025-11-04T17:00:00') + + return jsonify({'status': 'success', 'message': 'Sample data added'}) + except Exception as e: + return jsonify({'status': 'error', 'message': str(e)}), 500 + +@app.route('/api/clear_all', methods=['POST']) +def clear_all(): + """Clear all Redis data""" + try: + redis_client.flushall() + return jsonify({'status': 'success', 'message': 'All data cleared'}) + except Exception as e: + return jsonify({'status': 'error', 'message': str(e)}), 500 + +@app.route('/api/demo_cache', methods=['POST']) +def demo_cache(): + """Demonstrate caching patterns""" + try: + # Simulate cache-aside pattern + redis_client.setex('api:users:1001', 600, 'User data from database') + redis_client.setex('api:posts:recent', 300, 'Recent blog posts') + redis_client.setex('api:stats:daily', 1800, 'Daily statistics') + + return jsonify({'status': 'success', 'message': 'Cache examples added'}) + except Exception as e: + return jsonify({'status': 'error', 'message': str(e)}), 500 + +@app.route('/api/demo_session', methods=['POST']) +def demo_session(): + """Demonstrate session storage""" + try: + # Simulate session storage + redis_client.setex('session:user123', 3600, 'active') + redis_client.setex('session:user456', 7200, 'premium') + redis_client.setex('session:admin789', 1800, 'administrator') + + return jsonify({'status': 'success', 'message': 'Session examples added'}) + except Exception as e: + return jsonify({'status': 'error', 'message': str(e)}), 500 + +@app.route('/api/demo_counter', methods=['POST']) +def demo_counter(): + """Demonstrate counter/rate limiting""" + try: + # Simulate counters + redis_client.set('counter:api_requests', '0') + redis_client.set('counter:user_visits', '0') + redis_client.set('counter:page_views', '0') + + return jsonify({'status': 'success', 'message': 'Counter examples added'}) + except Exception as e: + return jsonify({'status': 'error', 'message': str(e)}), 500 + +@app.route('/api/memory_info') +def memory_info(): + """Get detailed memory information""" + try: + info = redis_client.info('memory') + return jsonify({ + 'status': 'success', + 'memory': { + 'used_memory': info.get('used_memory'), + 'used_memory_human': info.get('used_memory_human'), + 'used_memory_rss': info.get('used_memory_rss'), + 'maxmemory': info.get('maxmemory'), + 'maxmemory_policy': info.get('maxmemory_policy'), + 'mem_fragmentation_ratio': info.get('mem_fragmentation_ratio') + } + }) + except Exception as e: + return jsonify({'status': 'error', 'message': str(e)}), 500 + +if __name__ == '__main__': + print("Starting Redis Web Interface...") + print("Access Redis at: localhost:6379") + print("Access Web Interface at: localhost:8080") + + # Test Redis connection + try: + redis_client.ping() + print("โœ… Redis connection successful") + except Exception as e: + print(f"โŒ Redis connection failed: {e}") + exit(1) + + app.run(host='0.0.0.0', port=8080, debug=False) \ No newline at end of file