{"stack": "python-flask", "files": {"requirements.txt": "flask\ngunicorn\n", "app.py": "\"\"\"\nExample Flask app for Niblit.ai.\nThis is a minimal todo list app with SQLite persistence.\n\"\"\"\n\nimport os\nimport sqlite3\nfrom flask import Flask, request, jsonify, render_template_string\n\napp = Flask(__name__)\n\n# Database path - MUST use /data/ for persistence\nDATABASE_PATH = os.environ.get('DATABASE_PATH', '/data/app.db')\n\n\ndef get_db():\n    \"\"\"Get database connection.\"\"\"\n    conn = sqlite3.connect(DATABASE_PATH)\n    conn.row_factory = sqlite3.Row\n    return conn\n\n\ndef init_db():\n    \"\"\"Initialize the database schema.\"\"\"\n    db = get_db()\n    db.execute('''\n        CREATE TABLE IF NOT EXISTS todos (\n            id INTEGER PRIMARY KEY AUTOINCREMENT,\n            title TEXT NOT NULL,\n            completed BOOLEAN DEFAULT FALSE,\n            created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n        )\n    ''')\n    db.commit()\n    db.close()\n\n\n# HTML template (inline for simplicity)\nHTML_TEMPLATE = '''\n<!DOCTYPE html>\n<html>\n<head>\n    <title>Todo App - Niblit.ai</title>\n    <style>\n        body { font-family: -apple-system, sans-serif; max-width: 600px; margin: 50px auto; padding: 20px; }\n        h1 { color: #4F46E5; }\n        .todo { padding: 10px; border-bottom: 1px solid #eee; display: flex; align-items: center; }\n        .todo.completed span { text-decoration: line-through; color: #999; }\n        .todo input { margin-right: 10px; }\n        form { display: flex; gap: 10px; margin-bottom: 20px; }\n        input[type=\"text\"] { flex: 1; padding: 10px; border: 1px solid #ddd; border-radius: 4px; }\n        button { padding: 10px 20px; background: #4F46E5; color: white; border: none; border-radius: 4px; cursor: pointer; }\n        button:hover { background: #4338CA; }\n        .footer { margin-top: 40px; color: #999; font-size: 14px; }\n    </style>\n</head>\n<body>\n    <h1>Todo List</h1>\n    <form action=\"/todos\" method=\"POST\">\n        <input type=\"text\" name=\"title\" placeholder=\"What needs to be done?\" required>\n        <button type=\"submit\">Add</button>\n    </form>\n    <div id=\"todos\">\n        {% for todo in todos %}\n        <div class=\"todo {% if todo.completed %}completed{% endif %}\">\n            <input type=\"checkbox\" {% if todo.completed %}checked{% endif %}\n                   onchange=\"location.href='/todos/{{ todo.id }}/toggle'\">\n            <span>{{ todo.title }}</span>\n        </div>\n        {% endfor %}\n    </div>\n    <div class=\"footer\">\n        Powered by <a href=\"https://niblit.ai\">Niblit.ai</a>\n    </div>\n</body>\n</html>\n'''\n\n\n@app.route('/')\ndef home():\n    \"\"\"Show all todos.\"\"\"\n    db = get_db()\n    todos = db.execute('SELECT * FROM todos ORDER BY created_at DESC').fetchall()\n    db.close()\n    return render_template_string(HTML_TEMPLATE, todos=todos)\n\n\n@app.route('/todos', methods=['POST'])\ndef create_todo():\n    \"\"\"Create a new todo.\"\"\"\n    title = request.form.get('title')\n    if title:\n        db = get_db()\n        db.execute('INSERT INTO todos (title) VALUES (?)', (title,))\n        db.commit()\n        db.close()\n    return home()\n\n\n@app.route('/todos/<int:todo_id>/toggle')\ndef toggle_todo(todo_id):\n    \"\"\"Toggle todo completion status.\"\"\"\n    db = get_db()\n    db.execute('UPDATE todos SET completed = NOT completed WHERE id = ?', (todo_id,))\n    db.commit()\n    db.close()\n    return home()\n\n\n@app.route('/api/todos')\ndef api_todos():\n    \"\"\"API endpoint returning todos as JSON.\"\"\"\n    db = get_db()\n    todos = db.execute('SELECT * FROM todos ORDER BY created_at DESC').fetchall()\n    db.close()\n    return jsonify([dict(todo) for todo in todos])\n\n\n@app.route('/health')\ndef health():\n    \"\"\"Health check endpoint.\"\"\"\n    return jsonify({'status': 'ok'})\n\n\n# Initialize database on startup\nwith app.app_context():\n    init_db()\n\n\nif __name__ == '__main__':\n    app.run(host='0.0.0.0', port=int(os.environ.get('PORT', 8080)))\n", "Dockerfile": "FROM python:3.12-slim\n\nWORKDIR /app\n\n# Install dependencies first (better caching)\nCOPY requirements.txt .\nRUN pip install --no-cache-dir -r requirements.txt\n\n# Copy application code\nCOPY . .\n\n# Create data directory for persistent storage\nRUN mkdir -p /data\n\n# Environment variables\nENV PORT=5000\nENV FLASK_ENV=production\nENV DATABASE_PATH=/data/app.db\n\nEXPOSE 5000\n\n# Run with gunicorn for production\nCMD [\"gunicorn\", \"--bind\", \"0.0.0.0:5000\", \"--workers\", \"2\", \"app:app\"]\n"}}