flaskdockernew / chapp.py
MySafeCode's picture
Rename app.py to chapp.py
063377d verified
Raw
History Blame Contribute Delete
10.7 kB
#!/usr/bin/env python3
# checker_pattern.py - Simple raw data checker pattern
import numpy as np
import time
import os
from flask import Flask, Response
# ===== 1. SETUP =====
PORT = int(os.getenv('PORT', 7860))
WIDTH, HEIGHT = 400, 300
TILE_SIZE = 40 # Size of each checker tile
print(f"πŸš€ Starting checker pattern server on port {PORT}")
# ===== 2. CREATE FLASK APP =====
app = Flask(__name__)
# ===== 3. SIMPLE HTML WITH CANVAS =====
HTML = '''<!DOCTYPE html>
<html>
<head>
<title>Checker Pattern Test</title>
<style>
body {
margin: 0;
padding: 20px;
background: #222;
color: white;
font-family: Arial, sans-serif;
text-align: center;
}
h1 { color: #4CAF50; }
#testCanvas {
border: 5px solid #4CAF50;
background: black;
display: block;
margin: 20px auto;
image-rendering: pixelated;
}
.info {
background: #333;
padding: 15px;
border-radius: 8px;
display: inline-block;
margin: 10px;
text-align: left;
}
.success { color: #4CAF50; font-weight: bold; }
.error { color: #f44336; font-weight: bold; }
</style>
</head>
<body>
<h1>βœ… CHECKER PATTERN TEST - MUST SHOW BELOW</h1>
<div>
<h3>If you see a black/white checker pattern below, it's WORKING!</h3>
<canvas id="testCanvas" width="400" height="300"></canvas>
</div>
<div class="info">
<h3>Debug Info:</h3>
<div>Server Time: <span id="serverTime">-</span></div>
<div>Data Size: <span id="dataSize">0</span> bytes</div>
<div>Status: <span id="status" class="success">Loading...</span></div>
<div>Last Update: <span id="lastUpdate">Never</span></div>
</div>
<div style="margin-top: 20px;">
<button onclick="loadChecker()">Load Checker Pattern</button>
<button onclick="testRaw()">Test Raw Data</button>
<button onclick="testImage()">Test Image Format</button>
</div>
<script>
const canvas = document.getElementById('testCanvas');
const ctx = canvas.getContext('2d');
// Create a simple checker pattern directly in JavaScript
function drawLocalChecker() {
console.log('🎨 Drawing local checker pattern...');
const tileSize = 40;
const imageData = new ImageData(400, 300);
const data = imageData.data;
for (let y = 0; y < 300; y++) {
for (let x = 0; x < 400; x++) {
const i = (y * 400 + x) * 4;
// Checker pattern logic
const tileX = Math.floor(x / tileSize);
const tileY = Math.floor(y / tileSize);
if ((tileX + tileY) % 2 === 0) {
// White tile
data[i] = 255; // R
data[i + 1] = 255; // G
data[i + 2] = 255; // B
} else {
// Black tile
data[i] = 0; // R
data[i + 1] = 0; // G
data[i + 2] = 0; // B
}
data[i + 3] = 255; // Alpha
}
}
ctx.putImageData(imageData, 0, 0);
console.log('βœ… Local checker drawn');
}
// Load checker pattern from Flask
function loadChecker() {
console.log('πŸ“₯ Loading checker from server...');
fetch('/checker')
.then(response => {
console.log('Response:', response.status, response.statusText);
return response.arrayBuffer();
})
.then(buffer => {
console.log(`πŸ“¦ Received ${buffer.byteLength} bytes`);
if (buffer.byteLength === 0) {
console.error('❌ Empty buffer!');
return;
}
// Create ImageData
const imageData = new ImageData(400, 300);
const rgba = imageData.data;
const rgb = new Uint8Array(buffer);
// Check size
const expectedSize = 400 * 300 * 3;
if (rgb.length !== expectedSize) {
console.error(`❌ Wrong size! Got ${rgb.length}, expected ${expectedSize}`);
return;
}
// Convert RGB to RGBA
for (let i = 0, j = 0; i < rgba.length; i += 4, j += 3) {
rgba[i] = rgb[j];
rgba[i + 1] = rgb[j + 1];
rgba[i + 2] = rgb[j + 2];
rgba[i + 3] = 255;
}
// Draw to canvas
ctx.putImageData(imageData, 0, 0);
// Update UI
document.getElementById('dataSize').textContent = buffer.byteLength;
document.getElementById('lastUpdate').textContent = new Date().toLocaleTimeString();
document.getElementById('status').textContent = 'Loaded βœ“';
console.log('βœ… Server checker drawn');
})
.catch(error => {
console.error('❌ Load error:', error);
document.getElementById('status').textContent = 'Error: ' + error.message;
document.getElementById('status').className = 'error';
});
}
function testRaw() {
console.log('πŸ§ͺ Testing raw data endpoint...');
fetch('/raw')
.then(r => r.arrayBuffer())
.then(buffer => {
console.log('Raw test:', buffer.byteLength, 'bytes');
alert(`Raw data test: ${buffer.byteLength} bytes received`);
});
}
function testImage() {
console.log('πŸ–ΌοΈ Testing image endpoint...');
const img = new Image();
img.onload = () => {
console.log('Image loaded');
ctx.drawImage(img, 0, 0);
alert('Image loaded successfully');
};
img.onerror = (e) => {
console.error('Image failed:', e);
alert('Image failed to load');
};
img.src = '/image?t=' + Date.now();
}
// Initialize
drawLocalChecker();
console.log('🟒 Page ready');
</script>
</body>
</html>'''
@app.route('/')
def index():
return HTML
@app.route('/checker')
def get_checker():
"""Return raw RGB bytes of a checker pattern"""
print("🎲 Generating checker pattern...")
# Create checker pattern using numpy
pattern = np.zeros((HEIGHT, WIDTH, 3), dtype=np.uint8)
# Create grid of tile indices
y_indices, x_indices = np.mgrid[:HEIGHT, :WIDTH]
tile_x = x_indices // TILE_SIZE
tile_y = y_indices // TILE_SIZE
# Checker pattern: (tile_x + tile_y) % 2 == 0 -> white, else black
checker_mask = ((tile_x + tile_y) % 2 == 0)
# White tiles: RGB = [255, 255, 255]
pattern[checker_mask] = [255, 255, 255]
# Black tiles: already [0, 0, 0] from zeros initialization
# Convert to raw bytes
raw_bytes = pattern.tobytes()
print(f"πŸ“€ Serving checker pattern: {len(raw_bytes)} bytes")
return Response(
raw_bytes,
mimetype='application/octet-stream',
headers={
'Cache-Control': 'no-cache, no-store, must-revalidate',
'Content-Type': 'application/octet-stream',
'X-Pattern': 'checker'
}
)
@app.route('/image')
def get_image():
"""Return the same checker pattern as a JPEG image"""
print("πŸ–ΌοΈ Generating checker image...")
# Create checker pattern
pattern = np.zeros((HEIGHT, WIDTH, 3), dtype=np.uint8)
y_indices, x_indices = np.mgrid[:HEIGHT, :WIDTH]
tile_x = x_indices // TILE_SIZE
tile_y = y_indices // TILE_SIZE
checker_mask = ((tile_x + tile_y) % 2 == 0)
pattern[checker_mask] = [255, 255, 255]
# Convert to JPEG using PIL
from PIL import Image
import io
img = Image.fromarray(pattern, 'RGB')
buffer = io.BytesIO()
img.save(buffer, format='JPEG', quality=90)
buffer.seek(0)
print(f"πŸ“€ Serving JPEG image: {buffer.getbuffer().nbytes} bytes")
return Response(
buffer.getvalue(),
mimetype='image/jpeg',
headers={'Cache-Control': 'no-cache'}
)
@app.route('/raw')
def get_raw():
"""Simple raw data test - returns colored stripes"""
print("🌈 Generating colored stripes...")
# Create colored stripes pattern
pattern = np.zeros((HEIGHT, WIDTH, 3), dtype=np.uint8)
# Red stripe
pattern[:, :WIDTH//3, 0] = 255
# Green stripe
pattern[:, WIDTH//3:2*WIDTH//3, 1] = 255
# Blue stripe
pattern[:, 2*WIDTH//3:, 2] = 255
raw_bytes = pattern.tobytes()
return Response(
raw_bytes,
mimetype='application/octet-stream',
headers={'Cache-Control': 'no-cache'}
)
@app.route('/test')
def test():
"""Simple test endpoint"""
return {
'status': 'ok',
'time': time.time(),
'width': WIDTH,
'height': HEIGHT,
'tile_size': TILE_SIZE,
'data_size': WIDTH * HEIGHT * 3
}
# ===== 4. MAIN =====
def main():
print("="*60)
print("🎯 CHECKER PATTERN SERVER")
print("="*60)
print(f"πŸ“‘ Port: {PORT}")
print(f"🎨 Resolution: {WIDTH}x{HEIGHT}")
print(f"🧱 Tile size: {TILE_SIZE}")
print(f"πŸ“Š Data size per frame: {WIDTH * HEIGHT * 3} bytes")
print("="*60)
print("βœ… Server ready! Open in browser:")
print(f" http://localhost:{PORT}")
print("="*60)
try:
app.run(
host='0.0.0.0',
port=PORT,
debug=False,
threaded=True,
use_reloader=False
)
except Exception as e:
print(f"❌ Server error: {e}")
if __name__ == "__main__":
main()