feat(topology): add Flask app skeleton with db connection (psycopg 3)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -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"
|
||||||
@@ -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
|
||||||
Reference in New Issue
Block a user