mirror of
https://github.com/Skyvern-AI/skyvern.git
synced 2026-04-28 03:30:10 +00:00
refactor(SKY-62): consolidate repository pattern follow-up PRs (#5283)
This commit is contained in:
parent
22d05d5091
commit
d3bba42792
13 changed files with 65 additions and 18 deletions
4
skyvern/forge/sdk/db/_sentinels.py
Normal file
4
skyvern/forge/sdk/db/_sentinels.py
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
"""Sentinel values for the database layer."""
|
||||
|
||||
# Sentinel for distinguishing "not passed" from "passed as None" in update methods.
|
||||
_UNSET = object()
|
||||
|
|
@ -36,7 +36,16 @@ LOG = structlog.get_logger()
|
|||
|
||||
|
||||
class BrowserSessionsMixin:
|
||||
"""Database operations for browser profiles and persistent browser sessions."""
|
||||
"""Database operations for browser profiles and persistent browser sessions.
|
||||
|
||||
.. deprecated::
|
||||
This mixin is part of the legacy database layer. New code should use the
|
||||
repository classes in ``skyvern.forge.sdk.db.repositories`` instead.
|
||||
|
||||
Cross-mixin migrations already completed:
|
||||
- ``get_last_workflow_run_for_browser_session`` → ``WorkflowRunsRepository``
|
||||
(queries workflow runs as the primary entity, browser session is just a filter).
|
||||
"""
|
||||
|
||||
Session: _SessionFactory
|
||||
|
||||
|
|
@ -46,6 +55,9 @@ class BrowserSessionsMixin:
|
|||
browser_session_id: str,
|
||||
organization_id: str | None = None,
|
||||
) -> WorkflowRun | None:
|
||||
# Deprecated: moved to WorkflowRunsRepository.get_last_workflow_run_for_browser_session
|
||||
# (skyvern/forge/sdk/db/repositories/workflow_runs.py). The primary entity is the
|
||||
# workflow run, not the browser session. This copy remains for legacy mixin compatibility.
|
||||
async with self.Session() as session:
|
||||
# check if there's a queued run
|
||||
query = select(WorkflowRunModel).filter_by(browser_session_id=browser_session_id)
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ from skyvern.forge.sdk.schemas.organization_bitwarden_collections import Organiz
|
|||
if TYPE_CHECKING:
|
||||
from skyvern.forge.sdk.db.base_alchemy_db import _SessionFactory
|
||||
|
||||
_UNSET = object()
|
||||
from skyvern.forge.sdk.db._sentinels import _UNSET
|
||||
|
||||
|
||||
class CredentialsMixin:
|
||||
|
|
|
|||
|
|
@ -23,12 +23,22 @@ if TYPE_CHECKING:
|
|||
|
||||
from skyvern.forge.sdk.db.base_alchemy_db import _SessionFactory
|
||||
|
||||
from skyvern.forge.sdk.db._sentinels import _UNSET
|
||||
|
||||
LOG = structlog.get_logger()
|
||||
_UNSET = object()
|
||||
|
||||
|
||||
class SchedulesMixin:
|
||||
"""Database operations for workflow schedules."""
|
||||
"""Database operations for workflow schedules.
|
||||
|
||||
.. deprecated::
|
||||
This mixin is part of the legacy database layer. New code should use the
|
||||
repository classes in ``skyvern.forge.sdk.db.repositories`` instead.
|
||||
|
||||
Cross-mixin migrations already completed:
|
||||
- ``soft_delete_workflow_and_schedules_by_permanent_id`` → ``WorkflowsRepository``
|
||||
(operates on workflows as the primary entity, schedules are a side-effect).
|
||||
"""
|
||||
|
||||
Session: _SessionFactory
|
||||
engine: AsyncEngine
|
||||
|
|
@ -563,7 +573,14 @@ class SchedulesMixin:
|
|||
workflow_permanent_id: str,
|
||||
organization_id: str | None = None,
|
||||
) -> list[str]:
|
||||
"""Soft-delete a workflow and its active schedules in a single DB transaction."""
|
||||
"""Soft-delete a workflow and its active schedules in a single DB transaction.
|
||||
|
||||
.. deprecated::
|
||||
Moved to ``WorkflowsRepository.soft_delete_workflow_and_schedules_by_permanent_id``
|
||||
(skyvern/forge/sdk/db/repositories/workflows.py). The primary entity is the
|
||||
workflow, not the schedule, so it belongs in the workflows repository.
|
||||
This copy remains for backward compatibility with the legacy mixin layer.
|
||||
"""
|
||||
async with self.Session() as session:
|
||||
select_query = (
|
||||
select(WorkflowScheduleModel.workflow_schedule_id)
|
||||
|
|
|
|||
|
|
@ -65,8 +65,9 @@ from skyvern.webeye.actions.actions import Action
|
|||
if TYPE_CHECKING:
|
||||
from skyvern.forge.sdk.db.base_alchemy_db import _SessionFactory
|
||||
|
||||
from skyvern.forge.sdk.db._sentinels import _UNSET
|
||||
|
||||
LOG = structlog.get_logger()
|
||||
_UNSET = object()
|
||||
|
||||
|
||||
class WorkflowParametersMixin:
|
||||
|
|
|
|||
|
|
@ -44,8 +44,9 @@ if TYPE_CHECKING:
|
|||
|
||||
from skyvern.forge.sdk.db.base_alchemy_db import _SessionFactory
|
||||
|
||||
from skyvern.forge.sdk.db._sentinels import _UNSET
|
||||
|
||||
LOG = structlog.get_logger()
|
||||
_UNSET = object()
|
||||
|
||||
|
||||
class WorkflowRunsMixin:
|
||||
|
|
|
|||
|
|
@ -1,4 +1 @@
|
|||
"""Domain-specific repository classes extracted from AgentDB mixins."""
|
||||
|
||||
# Sentinel for distinguishing "not passed" from "passed as None" in update methods.
|
||||
_UNSET = object()
|
||||
|
|
|
|||
|
|
@ -5,14 +5,13 @@ from datetime import datetime, timezone
|
|||
from sqlalchemy import select
|
||||
|
||||
from skyvern.forge.sdk.db._error_handling import db_operation
|
||||
from skyvern.forge.sdk.db._sentinels import _UNSET
|
||||
from skyvern.forge.sdk.db.base_repository import BaseRepository
|
||||
from skyvern.forge.sdk.db.exceptions import NotFoundError
|
||||
from skyvern.forge.sdk.db.models import CredentialModel, OrganizationBitwardenCollectionModel
|
||||
from skyvern.forge.sdk.schemas.credentials import Credential, CredentialType, CredentialVaultType
|
||||
from skyvern.forge.sdk.schemas.organization_bitwarden_collections import OrganizationBitwardenCollection
|
||||
|
||||
from . import _UNSET
|
||||
|
||||
|
||||
class CredentialRepository(BaseRepository):
|
||||
"""Database operations for credential and Bitwarden collection management."""
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ from skyvern.forge.sdk.workflow.schedules import compute_next_run
|
|||
if TYPE_CHECKING:
|
||||
from skyvern.forge.sdk.db.base_alchemy_db import _SessionFactory
|
||||
|
||||
from . import _UNSET
|
||||
from skyvern.forge.sdk.db._sentinels import _UNSET
|
||||
|
||||
LOG = structlog.get_logger()
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ from sqlalchemy import select
|
|||
|
||||
from skyvern.config import settings
|
||||
from skyvern.forge.sdk.db._error_handling import db_operation
|
||||
from skyvern.forge.sdk.db._sentinels import _UNSET
|
||||
from skyvern.forge.sdk.db.base_repository import BaseRepository
|
||||
from skyvern.forge.sdk.db.exceptions import NotFoundError
|
||||
from skyvern.forge.sdk.db.models import (
|
||||
|
|
@ -63,8 +64,6 @@ from skyvern.forge.sdk.workflow.models.parameter import (
|
|||
from skyvern.schemas.runs import RunType
|
||||
from skyvern.webeye.actions.actions import Action
|
||||
|
||||
from . import _UNSET
|
||||
|
||||
LOG = structlog.get_logger()
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ from skyvern.forge.sdk.db.exceptions import NotFoundError
|
|||
if TYPE_CHECKING:
|
||||
from skyvern.forge.sdk.db.base_alchemy_db import _SessionFactory
|
||||
|
||||
from skyvern.forge.sdk.db._sentinels import _UNSET
|
||||
from skyvern.forge.sdk.db.models import (
|
||||
TaskModel,
|
||||
WorkflowModel,
|
||||
|
|
@ -46,8 +47,6 @@ from skyvern.forge.sdk.workflow.models.workflow import (
|
|||
)
|
||||
from skyvern.schemas.runs import ProxyLocationInput
|
||||
|
||||
from . import _UNSET
|
||||
|
||||
LOG = structlog.get_logger()
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1633,7 +1633,7 @@ async def update_bitwarden_credential(
|
|||
"""
|
||||
try:
|
||||
# Atomically invalidate old + create new in a single transaction
|
||||
auth_token = await app.DATABASE.replace_org_auth_token(
|
||||
auth_token = await app.DATABASE.organizations.replace_org_auth_token(
|
||||
organization_id=current_org.organization_id,
|
||||
token_type=OrganizationAuthTokenType.bitwarden_credential,
|
||||
token=request.credential,
|
||||
|
|
|
|||
18
tests/unit/forge/sdk/db/test_sentinels.py
Normal file
18
tests/unit/forge/sdk/db/test_sentinels.py
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
"""Tests for the _UNSET sentinel value."""
|
||||
|
||||
from skyvern.forge.sdk.db._sentinels import _UNSET
|
||||
|
||||
|
||||
def test_unset_is_unique_sentinel() -> None:
|
||||
"""_UNSET should be distinguishable from None and other values."""
|
||||
assert _UNSET is not None
|
||||
assert _UNSET is not False
|
||||
assert _UNSET != 0
|
||||
assert _UNSET != ""
|
||||
|
||||
|
||||
def test_unset_identity() -> None:
|
||||
"""_UNSET should be the same object across imports."""
|
||||
from skyvern.forge.sdk.db._sentinels import _UNSET as second_import
|
||||
|
||||
assert _UNSET is second_import
|
||||
Loading…
Add table
Add a link
Reference in a new issue