sk1/backend/app.py
2026-05-11 20:59:41 +02:00

126 lines
3.5 KiB
Python

import os
import time
from datetime import datetime
import psycopg2
from flask import Flask, jsonify, request
app = Flask(__name__)
DB_CONFIG = {
"host": os.getenv("DB_HOST", "db"),
"port": int(os.getenv("DB_PORT", "5432")),
"dbname": os.getenv("DB_NAME", "guestbook"),
"user": os.getenv("DB_USER", "guestbook_user"),
"password": os.getenv("DB_PASSWORD", ""),
"sslmode": os.getenv("DB_SSLMODE", "prefer"),
}
APP_PORT = int(os.getenv("APP_PORT", "5000"))
def get_connection():
return psycopg2.connect(**DB_CONFIG)
def init_db(retries: int = 20, delay: int = 2) -> None:
for attempt in range(1, retries + 1):
try:
with get_connection() as conn:
with conn.cursor() as cur:
cur.execute(
"""
CREATE TABLE IF NOT EXISTS messages (
id SERIAL PRIMARY KEY,
author VARCHAR(100) NOT NULL,
content TEXT NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
)
"""
)
conn.commit()
print("Database initialized.")
return
except Exception as exc:
print(f"Database not ready yet (attempt {attempt}/{retries}): {exc}")
time.sleep(delay)
raise RuntimeError("Could not initialize the database.")
@app.route("/api/health", methods=["GET"])
def health():
try:
with get_connection() as conn:
with conn.cursor() as cur:
cur.execute("SELECT 1")
cur.fetchone()
return jsonify({"status": "ok", "database": "connected"}), 200
except Exception as exc:
return jsonify({"status": "error", "database": str(exc)}), 500
@app.route("/api/messages", methods=["GET"])
def get_messages():
with get_connection() as conn:
with conn.cursor() as cur:
cur.execute(
"""
SELECT id, author, content, created_at
FROM messages
ORDER BY created_at DESC, id DESC
"""
)
rows = cur.fetchall()
data = [
{
"id": row[0],
"author": row[1],
"content": row[2],
"created_at": row[3].isoformat(),
}
for row in rows
]
return jsonify(data), 200
@app.route("/api/messages", methods=["POST"])
def add_message():
payload = request.get_json(silent=True) or {}
author = (payload.get("author") or "").strip()
content = (payload.get("content") or "").strip()
if not author or not content:
return jsonify({"error": "Fields 'author' and 'content' are required."}), 400
with get_connection() as conn:
with conn.cursor() as cur:
cur.execute(
"""
INSERT INTO messages (author, content, created_at)
VALUES (%s, %s, %s)
RETURNING id, author, content, created_at
""",
(author, content, datetime.utcnow()),
)
row = cur.fetchone()
conn.commit()
return (
jsonify(
{
"id": row[0],
"author": row[1],
"content": row[2],
"created_at": row[3].isoformat(),
}
),
201,
)
if __name__ == "__main__":
init_db()
app.run(host="0.0.0.0", port=APP_PORT)