From 29fc482bb0ea3bc288d32e2501380a3992990bf7 Mon Sep 17 00:00:00 2001 From: Armor00 <2654988228@qq.com> Date: Thu, 9 Jul 2026 20:49:23 +0800 Subject: [PATCH] feat(topology): add Flask app skeleton with db connection (psycopg 3) Co-Authored-By: Claude --- topology_api/__init__.py | 0 topology_api/config.py | 30 ++++++++++++++++++++++++++++ topology_api/db.py | 34 ++++++++++++++++++++++++++++++++ topology_api/queries/__init__.py | 0 topology_api/routes/__init__.py | 0 topology_api/seed/__init__.py | 0 6 files changed, 64 insertions(+) create mode 100644 topology_api/__init__.py create mode 100644 topology_api/config.py create mode 100644 topology_api/db.py create mode 100644 topology_api/queries/__init__.py create mode 100644 topology_api/routes/__init__.py create mode 100644 topology_api/seed/__init__.py diff --git a/topology_api/__init__.py b/topology_api/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/topology_api/config.py b/topology_api/config.py new file mode 100644 index 0000000..7b43c0f --- /dev/null +++ b/topology_api/config.py @@ -0,0 +1,30 @@ +# topology_api/config.py +import os + +# PostgreSQL connection (from .env) +PGHOST = os.environ.get("PGHOST", "192.168.195.241") +PGPORT = os.environ.get("PGPORT", "35432") +PGUSER = os.environ.get("PGUSER", "user_armor") +PGPASSWORD = os.environ.get("PGPASSWORD", "user_armor_1790990971") +TOPO_DATABASE = os.environ.get("TOPO_DATABASE", "ksp_wiki_topology") + +_BASE_DSN = f"postgresql://{PGUSER}:{PGPASSWORD}@{PGHOST}:{PGPORT}" + +DATABASE_URL = os.environ.get( + "TOPOLOGY_DATABASE_URL", + f"{_BASE_DSN}/{TOPO_DATABASE}", +) + +READER_DATABASE_URL = os.environ.get( + "TOPOLOGY_READER_DATABASE_URL", + DATABASE_URL, +) + +WRITER_DATABASE_URL = os.environ.get( + "TOPOLOGY_WRITER_DATABASE_URL", + DATABASE_URL, +) + +API_HOST = os.environ.get("TOPOLOGY_API_HOST", "0.0.0.0") +API_PORT = int(os.environ.get("TOPOLOGY_API_PORT", "5000")) +API_DEBUG = os.environ.get("TOPOLOGY_API_DEBUG", "false").lower() == "true" diff --git a/topology_api/db.py b/topology_api/db.py new file mode 100644 index 0000000..689d7be --- /dev/null +++ b/topology_api/db.py @@ -0,0 +1,34 @@ +# topology_api/db.py +import psycopg +from psycopg.rows import dict_row +from contextlib import contextmanager +from topology_api.config import READER_DATABASE_URL, WRITER_DATABASE_URL + + +def get_reader_connection(): + """Return a new read-only connection with dict_row rows.""" + return psycopg.connect(READER_DATABASE_URL, row_factory=dict_row) + + +def get_writer_connection(): + """Return a new write-capable connection with dict_row rows.""" + return psycopg.connect(WRITER_DATABASE_URL, row_factory=dict_row) + + +@contextmanager +def read_cursor(): + """Context manager for read queries. Returns a cursor.""" + with get_reader_connection() as conn: + conn.execute("SET search_path TO topology, public") + with conn.cursor() as cur: + yield cur + + +@contextmanager +def write_cursor(): + """Context manager for write queries. Auto-commits on success, rollback on error.""" + with get_writer_connection() as conn: + conn.execute("SET search_path TO topology, public") + with conn.transaction(): + with conn.cursor() as cur: + yield cur diff --git a/topology_api/queries/__init__.py b/topology_api/queries/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/topology_api/routes/__init__.py b/topology_api/routes/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/topology_api/seed/__init__.py b/topology_api/seed/__init__.py new file mode 100644 index 0000000..e69de29