mirror of
https://github.com/arc53/DocsGPT.git
synced 2026-05-22 13:25:08 +00:00
* feat: postgres tests * feat: mongo cutoff * feat: mongo cutoff * feat: adjust docs and compose files * fix: mini code mongo removals * fix: tests and k8s mongo stuff * feat: test fixes * fix: ruff * fix: vale * Potential fix for pull request finding 'CodeQL / Clear-text logging of sensitive information' Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> * fix: mini suggestions * vale lint fix 2 * fix: codeql columns thing * fix: test mongo * fix: tests coverage * feat: better tests 4 * feat: more tests * feat: decent coverage * fix: ruff fixes * fix: remove mongo mock * feat: enhance workflow engine and API routes; add document retrieval and source handling * feat: e2e tests * fix: mcp, mongo and more * fix: mini codeql warning * fix: agent chunk view * fix: mini issues * fix: more pg fixes * feat: postgres prep on start * feat: qa tests * fix: mini improvements * fix: tests --------- Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> Co-authored-by: Siddhant Rai <siddhant.rai.5686@gmail.com>
68 lines
2.3 KiB
Python
68 lines
2.3 KiB
Python
"""Per-request connection helpers for route handlers.
|
|
|
|
Every route-handler that talks to Postgres opens a short-lived, explicit
|
|
transaction via the context managers in this module. The pattern is::
|
|
|
|
from application.storage.db.session import db_session
|
|
|
|
with db_session() as conn:
|
|
repo = PromptsRepository(conn)
|
|
prompt = repo.get(prompt_id, user_id)
|
|
|
|
Why explicit, not ``flask.g``: the lifecycle stays local to each handler,
|
|
which mirrors how the repository test fixtures already work and keeps
|
|
error handling obvious. Celery tasks and the seeder use the same helper
|
|
so there's one pattern to learn.
|
|
|
|
Two flavors:
|
|
|
|
* ``db_session()`` — opens a transaction (``engine.begin()``). Commits on
|
|
clean exit, rolls back on exception. Use for any handler that may
|
|
write.
|
|
* ``db_readonly()`` — opens a plain connection (``engine.connect()``) for
|
|
read-only paths. Avoids the commit round-trip on pure reads.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from contextlib import contextmanager
|
|
from typing import Iterator
|
|
|
|
from sqlalchemy import Connection, text
|
|
|
|
from application.storage.db.engine import get_engine
|
|
|
|
|
|
@contextmanager
|
|
def db_session() -> Iterator[Connection]:
|
|
"""Transactional connection. Commits on success, rolls back on error."""
|
|
with get_engine().begin() as conn:
|
|
yield conn
|
|
|
|
|
|
@contextmanager
|
|
def db_readonly() -> Iterator[Connection]:
|
|
"""Read-only connection for handlers that never write.
|
|
|
|
The connection is placed into a Postgres ``READ ONLY`` transaction
|
|
before any caller statement runs, so an accidental ``INSERT`` /
|
|
``UPDATE`` / ``DELETE`` from inside the block raises
|
|
``InternalError: cannot execute ... in a read-only transaction``
|
|
instead of silently mutating data.
|
|
|
|
The transaction itself is rolled back on exit — a read-only
|
|
transaction has nothing meaningful to commit, and rolling back avoids
|
|
leaving the connection in an open-transaction state when it returns
|
|
to the pool.
|
|
"""
|
|
with get_engine().connect() as conn:
|
|
trans = conn.begin()
|
|
try:
|
|
# Must be the first statement in the txn; psycopg3 + SA both
|
|
# honor this and Postgres rejects writes for the rest of the
|
|
# transaction's lifetime.
|
|
conn.execute(text("SET TRANSACTION READ ONLY"))
|
|
yield conn
|
|
finally:
|
|
trans.rollback()
|