Skip to content

chore(api): Add true read-only sessions#38625

Open
cqjjjzr wants to merge 2 commits into
langgenius:mainfrom
cqjjjzr:db-session-3
Open

chore(api): Add true read-only sessions#38625
cqjjjzr wants to merge 2 commits into
langgenius:mainfrom
cqjjjzr:db-session-3

Conversation

@cqjjjzr

@cqjjjzr cqjjjzr commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Important

  1. Make sure you have read our contribution guidelines
  2. Ensure there is an associated issue and you have been assigned to it
  3. Use the correct syntax to link this PR: Fixes #<issue number>.

Summary

No issue.

Add infrastrucrture to prevent mislabelling writing session as readonly like those in #38559 .

Typing using ReadonlySession is not applied yet. We will do this gradually.

Checklist

  • This change requires a documentation update, included: Dify Document
  • I understand that this PR may be closed in case there was no previous discussion or issues. (This doesn't apply to typos!)
  • I've added a test for each change that was introduced, and I tried as much as possible to make a single atomic change.
  • I've updated the documentation accordingly.
  • I ran make lint && make type-check (backend) and cd web && pnpm exec vp staged (frontend) to appease the lint gods

@cqjjjzr cqjjjzr requested a review from Copilot July 9, 2026 20:49
@dosubot dosubot Bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Jul 9, 2026
@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Pyrefly Type Coverage

Metric Base PR Delta
Type coverage 52.64% 52.68% +0.04%
Strict coverage 52.16% 52.18% +0.02%
Typed symbols 32,618 32,656 +38
Untyped symbols 29,619 29,619 0
Modules 2986 2987 +1

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a “true” read-only SQLAlchemy session path in the backend API to prevent accidentally treating a write-capable session as read-only, and updates controller/session behavior and tests to validate read-only enforcement.

Changes:

  • Implemented GuardedSession + create_readonly_session() with runtime write guards and DB-native read-only transaction/connection protections.
  • Switched controllers.common.session.with_session(write=False) to use the guarded read-only session context.
  • Added unit tests covering representative ORM/Core/raw-SQL write attempts being blocked in read-only mode.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
api/core/db/session_factory.py Adds guarded read-only session implementation and enforcement hooks.
api/controllers/common/session.py Uses the new read-only session for write=False controller handlers.
api/tests/unit_tests/core/db/test_session_factory.py Unit tests validating read-only session behavior at the session factory layer.
api/tests/unit_tests/controllers/common/test_session.py Unit tests validating with_session(write=False) uses read-only behavior and blocks writes.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +140 to +152
def _start_native_readonly_transaction(session: Session) -> Connection:
connection = session.connection()
connection.info[READONLY_CONNECTION_FLAG] = True
dialect_name = connection.dialect.name

if dialect_name == "sqlite":
connection.exec_driver_sql("PRAGMA query_only = ON")
elif dialect_name == "postgresql":
connection.exec_driver_sql("BEGIN READ ONLY")
elif dialect_name in {"mysql", "mariadb"}:
connection.exec_driver_sql("START TRANSACTION READ ONLY")

return connection
Comment thread api/core/db/session_factory.py Outdated


@contextmanager
def create_readonly_session() -> Generator[GuardedSession]:
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants