mirror of
https://github.com/langgenius/dify.git
synced 2026-07-21 02:28:30 +08:00
chore: clean Db session from service (#38227)
Co-authored-by: chariri <w@chariri.moe> Co-authored-by: WH-2099 <wh2099@pm.me>
This commit is contained in:
parent
ee0068eed4
commit
68d8328b9c
@ -25,7 +25,7 @@ def reset_password(email, new_password, password_confirm):
|
||||
return
|
||||
normalized_email = email.strip().lower()
|
||||
|
||||
account = AccountService.get_account_by_email_with_case_fallback(db.session, email.strip())
|
||||
account = AccountService.get_account_by_email_with_case_fallback(email.strip(), session=db.session())
|
||||
|
||||
if not account:
|
||||
click.echo(click.style(f"Account not found for email: {email}", fg="red"))
|
||||
@ -67,7 +67,7 @@ def reset_email(email, new_email, email_confirm):
|
||||
return
|
||||
normalized_new_email = new_email.strip().lower()
|
||||
|
||||
account = AccountService.get_account_by_email_with_case_fallback(db.session, email.strip())
|
||||
account = AccountService.get_account_by_email_with_case_fallback(email.strip(), session=db.session())
|
||||
|
||||
if not account:
|
||||
click.echo(click.style(f"Account not found for email: {email}", fg="red"))
|
||||
@ -133,9 +133,9 @@ def create_tenant(email: str, language: str | None = None, name: str | None = No
|
||||
password=new_password,
|
||||
language=language,
|
||||
create_workspace_required=False,
|
||||
session=db.session,
|
||||
session=db.session(),
|
||||
)
|
||||
TenantService.create_owner_tenant_if_not_exist(account, name, session=db.session)
|
||||
TenantService.create_owner_tenant_if_not_exist(account, name, session=db.session())
|
||||
|
||||
click.echo(
|
||||
click.style(
|
||||
|
||||
@ -9,6 +9,7 @@ from uuid import UUID
|
||||
import click
|
||||
import sqlalchemy as sa
|
||||
import yaml
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from core.db.session_factory import session_factory
|
||||
from extensions.ext_database import db
|
||||
@ -108,7 +109,7 @@ def export_migration_data(input_file: str | None, output_file: str | None, overw
|
||||
raw_config = _load_json_object(input_file, "Export config")
|
||||
selection = ExportConfigParser().parse(raw_config)
|
||||
with session_factory.create_session() as session:
|
||||
result = MigrationExportService().export(session, selection)
|
||||
result = MigrationExportService().export(selection, session=session)
|
||||
MigrationPackageService().save_package(result.package, output_file, overwrite=overwrite)
|
||||
click.echo(click.style(f"Output written to {output_file}", fg="green"))
|
||||
_render_report(result.report_items, context=_with_output_path(result.report_context, output_file))
|
||||
@ -157,7 +158,6 @@ def import_migration_data(
|
||||
package = MigrationPackageService().load_package(input_file)
|
||||
with session_factory.create_session() as session:
|
||||
result = MigrationImportService().import_package(
|
||||
session,
|
||||
ImportRequest(
|
||||
package=package,
|
||||
cli_target_tenant=target_tenant,
|
||||
@ -169,6 +169,7 @@ def import_migration_data(
|
||||
create_app_api_token_on_import=create_app_api_token_on_import,
|
||||
),
|
||||
),
|
||||
session=session,
|
||||
)
|
||||
_render_report(result.report_items, context=result.report_context)
|
||||
except MigrationDataError as exc:
|
||||
@ -217,7 +218,9 @@ def migration_data_wizard() -> None:
|
||||
default=True,
|
||||
show_default=False,
|
||||
)
|
||||
auto_tools = _discover_auto_tools([app for app in apps if app.id in set(app_ids)], include_referenced_tools)
|
||||
auto_tools = _discover_auto_tools(
|
||||
[app for app in apps if app.id in set(app_ids)], include_referenced_tools, session=db.session()
|
||||
)
|
||||
auto_tools = _resolve_auto_tool_names(tenant.id, auto_tools)
|
||||
_print_auto_tools(auto_tools)
|
||||
additional_tools = _prompt_additional_tools(tenant.id, auto_tools)
|
||||
@ -253,7 +256,7 @@ def migration_data_wizard() -> None:
|
||||
output_file=output_file,
|
||||
)
|
||||
with session_factory.create_session() as session:
|
||||
result = MigrationExportService().export(session, selection)
|
||||
result = MigrationExportService().export(selection, session=session)
|
||||
MigrationPackageService().save_package(result.package, output_file, overwrite=overwrite)
|
||||
click.echo(click.style(f"Output written to {output_file}", fg="green"))
|
||||
_print_wizard_step("Report")
|
||||
@ -394,13 +397,13 @@ def _prompt_import_options() -> tuple[bool, bool, str, str]:
|
||||
return include_secrets, create_tokens, id_strategy, conflict_strategy
|
||||
|
||||
|
||||
def _discover_auto_tools(apps: list[App], include_referenced_tools: bool) -> WizardToolMap:
|
||||
def _discover_auto_tools(apps: list[App], include_referenced_tools: bool, *, session: Session) -> WizardToolMap:
|
||||
auto_tools: WizardToolMap = {"api_tools": {}, "workflow_tools": {}, "mcp_tools": {}}
|
||||
if not include_referenced_tools:
|
||||
return auto_tools
|
||||
discovery_service = DependencyDiscoveryService()
|
||||
for app in apps:
|
||||
dsl_content = AppDslService.export_dsl(app_model=app, include_secret=False)
|
||||
dsl_content = AppDslService.export_dsl(app_model=app, session=session, include_secret=False)
|
||||
raw_dsl = yaml.safe_load(dsl_content) if dsl_content else {}
|
||||
dsl = raw_dsl if isinstance(raw_dsl, dict) else {}
|
||||
for dependency in discovery_service.discover_from_dsl(dsl):
|
||||
|
||||
@ -472,6 +472,7 @@ def backfill_plugin_auto_upgrade(
|
||||
try:
|
||||
result = PluginAutoUpgradeService.backfill_strategy_categories(
|
||||
current_tenant_id,
|
||||
session=db.session(),
|
||||
)
|
||||
except Exception as e:
|
||||
failed_count += 1
|
||||
|
||||
@ -6,6 +6,7 @@ from concurrent.futures import ThreadPoolExecutor, as_completed
|
||||
|
||||
import click
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from configs import dify_config
|
||||
from core.db.session_factory import session_factory
|
||||
@ -131,16 +132,35 @@ def _replace_member_role(
|
||||
operator_account_id: str,
|
||||
member_account_id: str,
|
||||
role_id: str,
|
||||
*,
|
||||
session: Session,
|
||||
) -> str:
|
||||
RBACService.MemberRoles.replace(
|
||||
tenant_id=tenant_id,
|
||||
account_id=operator_account_id,
|
||||
member_account_id=member_account_id,
|
||||
role_ids=[role_id],
|
||||
session=session,
|
||||
)
|
||||
return member_account_id
|
||||
|
||||
|
||||
def _replace_member_role_with_new_session(
|
||||
tenant_id: str,
|
||||
operator_account_id: str,
|
||||
member_account_id: str,
|
||||
role_id: str,
|
||||
) -> str:
|
||||
with session_factory.create_session() as session:
|
||||
return _replace_member_role(
|
||||
tenant_id=tenant_id,
|
||||
operator_account_id=operator_account_id,
|
||||
member_account_id=member_account_id,
|
||||
role_id=role_id,
|
||||
session=session,
|
||||
)
|
||||
|
||||
|
||||
@click.command(
|
||||
"rbac-migrate-member-roles", help="Migrate legacy workspace member roles into RBAC member-role bindings."
|
||||
)
|
||||
@ -217,14 +237,21 @@ def migrate_member_roles_to_rbac(
|
||||
|
||||
if replace_jobs:
|
||||
if workers == 1:
|
||||
for member_account_id, resolved_role_id in replace_jobs:
|
||||
_replace_member_role(workspace_id, owner_account_id, member_account_id, resolved_role_id)
|
||||
migrated_count += 1
|
||||
with session_factory.create_session() as session:
|
||||
for member_account_id, resolved_role_id in replace_jobs:
|
||||
_replace_member_role(
|
||||
workspace_id,
|
||||
owner_account_id,
|
||||
member_account_id,
|
||||
resolved_role_id,
|
||||
session=session,
|
||||
)
|
||||
migrated_count += 1
|
||||
else:
|
||||
with ThreadPoolExecutor(max_workers=workers) as executor:
|
||||
futures = [
|
||||
executor.submit(
|
||||
_replace_member_role,
|
||||
_replace_member_role_with_new_session,
|
||||
workspace_id,
|
||||
owner_account_id,
|
||||
member_account_id,
|
||||
|
||||
@ -4,6 +4,7 @@ from collections.abc import Sequence
|
||||
from dataclasses import dataclass
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from extensions.ext_database import db
|
||||
from services.enterprise import rbac_service as enterprise_rbac_service
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@ -76,7 +77,7 @@ def resolve_app_access_filter(
|
||||
inner-API round trip; otherwise it is fetched here.
|
||||
"""
|
||||
if permissions is None:
|
||||
permissions = enterprise_rbac_service.RBACService.MyPermissions.get(tenant_id, account_id)
|
||||
permissions = enterprise_rbac_service.RBACService.MyPermissions.get(tenant_id, account_id, session=db.session())
|
||||
whitelist_scope = enterprise_rbac_service.RBACService.AppAccess.whitelist_resources(tenant_id, account_id)
|
||||
|
||||
can_manage_own_apps = _MANAGE_OWN_APPS_PERMISSION_KEY in permissions.workspace.permission_keys
|
||||
|
||||
@ -16,6 +16,7 @@ from controllers.console.wraps import (
|
||||
with_current_tenant_id,
|
||||
with_current_user_id,
|
||||
)
|
||||
from extensions.ext_database import db
|
||||
from fields.agent_fields import (
|
||||
AgentAppComposerResponse,
|
||||
AgentComposerCandidatesResponse,
|
||||
@ -69,6 +70,7 @@ class WorkflowAgentComposerApi(Resource):
|
||||
node_id=node_id,
|
||||
account_id=account_id,
|
||||
snapshot_id=query.snapshot_id,
|
||||
session=db.session(),
|
||||
),
|
||||
)
|
||||
|
||||
@ -94,6 +96,7 @@ class WorkflowAgentComposerApi(Resource):
|
||||
node_id=node_id,
|
||||
account_id=account_id,
|
||||
payload=payload,
|
||||
session=db.session(),
|
||||
),
|
||||
)
|
||||
|
||||
@ -126,6 +129,7 @@ class WorkflowAgentComposerCopyFromRosterApi(Resource):
|
||||
source_agent_id=payload.source_agent_id,
|
||||
source_snapshot_id=payload.source_snapshot_id,
|
||||
idempotency_key=payload.idempotency_key,
|
||||
session=db.session(),
|
||||
),
|
||||
)
|
||||
|
||||
@ -149,8 +153,9 @@ class WorkflowAgentComposerValidateApi(Resource):
|
||||
tenant_id=tenant_id,
|
||||
payload=payload,
|
||||
agent_id=AgentComposerService.resolve_workflow_node_agent_id(
|
||||
tenant_id=tenant_id, app_id=app_model.id, node_id=node_id
|
||||
tenant_id=tenant_id, app_id=app_model.id, node_id=node_id, session=db.session()
|
||||
),
|
||||
session=db.session(),
|
||||
)
|
||||
return dump_response(AgentComposerValidateResponse, {"result": "success", "errors": [], **findings})
|
||||
|
||||
@ -174,6 +179,7 @@ class WorkflowAgentComposerCandidatesApi(Resource):
|
||||
app_id=app_model.id,
|
||||
node_id=node_id,
|
||||
user_id=current_user_id,
|
||||
session=db.session(),
|
||||
),
|
||||
)
|
||||
|
||||
@ -196,7 +202,9 @@ class WorkflowAgentComposerImpactApi(Resource):
|
||||
)
|
||||
return dump_response(
|
||||
AgentComposerImpactResponse,
|
||||
AgentComposerService.calculate_impact(tenant_id=tenant_id, current_snapshot_id=current_snapshot_id),
|
||||
AgentComposerService.calculate_impact(
|
||||
tenant_id=tenant_id, current_snapshot_id=current_snapshot_id, session=db.session()
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@ -224,6 +232,7 @@ class WorkflowAgentComposerSaveToRosterApi(Resource):
|
||||
node_id=node_id,
|
||||
account_id=account_id,
|
||||
payload=payload,
|
||||
session=db.session(),
|
||||
),
|
||||
)
|
||||
|
||||
@ -238,7 +247,7 @@ class AgentComposerApi(Resource):
|
||||
def get(self, tenant_id: str, agent_id: UUID):
|
||||
return dump_response(
|
||||
AgentAppComposerResponse,
|
||||
AgentComposerService.load_agent_composer(tenant_id=tenant_id, agent_id=str(agent_id)),
|
||||
AgentComposerService.load_agent_composer(tenant_id=tenant_id, agent_id=str(agent_id), session=db.session()),
|
||||
)
|
||||
|
||||
@console_ns.expect(console_ns.models[ComposerSavePayload.__name__])
|
||||
@ -259,6 +268,7 @@ class AgentComposerApi(Resource):
|
||||
agent_id=str(agent_id),
|
||||
account_id=account_id,
|
||||
payload=payload,
|
||||
session=db.session(),
|
||||
),
|
||||
)
|
||||
|
||||
@ -274,7 +284,7 @@ class AgentComposerValidateApi(Resource):
|
||||
@account_initialization_required
|
||||
@with_current_tenant_id
|
||||
def post(self, tenant_id: str, agent_id: UUID):
|
||||
AgentComposerService.load_agent_composer(tenant_id=tenant_id, agent_id=str(agent_id))
|
||||
AgentComposerService.load_agent_composer(tenant_id=tenant_id, agent_id=str(agent_id), session=db.session())
|
||||
payload = ComposerSavePayload.model_validate(console_ns.payload or {})
|
||||
ComposerConfigValidator.validate_publish_payload(payload)
|
||||
AgentComposerService.validate_knowledge_datasets(tenant_id=tenant_id, agent_soul=payload.agent_soul)
|
||||
@ -282,6 +292,7 @@ class AgentComposerValidateApi(Resource):
|
||||
tenant_id=tenant_id,
|
||||
payload=payload,
|
||||
agent_id=str(agent_id),
|
||||
session=db.session(),
|
||||
)
|
||||
return dump_response(AgentComposerValidateResponse, {"result": "success", "errors": [], **findings})
|
||||
|
||||
@ -303,5 +314,6 @@ class AgentComposerCandidatesApi(Resource):
|
||||
tenant_id=tenant_id,
|
||||
agent_id=str(agent_id),
|
||||
user_id=current_user_id,
|
||||
session=db.session(),
|
||||
),
|
||||
)
|
||||
|
||||
@ -534,7 +534,7 @@ class AgentAppListApi(Resource):
|
||||
status="normal",
|
||||
)
|
||||
|
||||
app_pagination = AppService().get_paginate_apps(current_user.id, current_tenant_id, params, db.session)
|
||||
app_pagination = AppService().get_paginate_apps(current_user.id, current_tenant_id, params, db.session())
|
||||
if app_pagination is None:
|
||||
empty = AgentAppPagination(page=args.page, limit=args.limit, total=0, has_more=False, data=[])
|
||||
return empty.model_dump(mode="json")
|
||||
@ -567,7 +567,7 @@ class AgentAppListApi(Resource):
|
||||
icon_background=args.icon_background,
|
||||
)
|
||||
|
||||
app = AppService().create_app(current_tenant_id, params, current_user)
|
||||
app = AppService().create_app(current_tenant_id, params, current_user, session=db.session())
|
||||
return _serialize_agent_app_detail(app, current_user=current_user), 201
|
||||
|
||||
|
||||
@ -607,7 +607,7 @@ class AgentAppApi(Resource):
|
||||
"max_active_requests": args.max_active_requests or 0,
|
||||
"role": args.role,
|
||||
}
|
||||
updated = AppService().update_app(app_model, args_dict)
|
||||
updated = AppService().update_app(app_model, args_dict, session=db.session())
|
||||
return _serialize_agent_app_detail(updated, current_user=current_user)
|
||||
|
||||
@console_ns.response(204, "Agent app deleted successfully")
|
||||
@ -619,7 +619,7 @@ class AgentAppApi(Resource):
|
||||
@with_current_tenant_id
|
||||
def delete(self, tenant_id: str, agent_id: UUID):
|
||||
app_model = _resolve_agent_app_model(tenant_id=tenant_id, agent_id=agent_id)
|
||||
AppService().delete_app(app_model)
|
||||
AppService().delete_app(app_model, session=db.session())
|
||||
return "", 204
|
||||
|
||||
|
||||
@ -668,6 +668,7 @@ class AgentPublishApi(Resource):
|
||||
agent_id=str(agent_id),
|
||||
account_id=current_user.id,
|
||||
version_note=args.version_note,
|
||||
session=db.session(),
|
||||
)
|
||||
|
||||
|
||||
@ -688,6 +689,7 @@ class AgentBuildDraftCheckoutApi(Resource):
|
||||
agent_id=str(agent_id),
|
||||
account_id=current_user.id,
|
||||
force=args.force,
|
||||
session=db.session(),
|
||||
)
|
||||
|
||||
|
||||
@ -705,6 +707,7 @@ class AgentBuildDraftApi(Resource):
|
||||
tenant_id=tenant_id,
|
||||
agent_id=str(agent_id),
|
||||
account_id=current_user.id,
|
||||
session=db.session(),
|
||||
)
|
||||
|
||||
@console_ns.expect(console_ns.models[ComposerSavePayload.__name__])
|
||||
@ -722,6 +725,7 @@ class AgentBuildDraftApi(Resource):
|
||||
agent_id=str(agent_id),
|
||||
account_id=current_user.id,
|
||||
payload=payload,
|
||||
session=db.session(),
|
||||
)
|
||||
|
||||
@console_ns.response(200, "Agent build draft discarded", console_ns.models[AgentSimpleResultResponse.__name__])
|
||||
@ -736,6 +740,7 @@ class AgentBuildDraftApi(Resource):
|
||||
tenant_id=tenant_id,
|
||||
agent_id=str(agent_id),
|
||||
account_id=current_user.id,
|
||||
session=db.session(),
|
||||
)
|
||||
|
||||
|
||||
@ -753,6 +758,7 @@ class AgentBuildDraftApplyApi(Resource):
|
||||
tenant_id=tenant_id,
|
||||
agent_id=str(agent_id),
|
||||
account_id=current_user.id,
|
||||
session=db.session(),
|
||||
)
|
||||
|
||||
|
||||
@ -810,7 +816,7 @@ class AgentApiStatusApi(Resource):
|
||||
def post(self, tenant_id: str, agent_id: UUID):
|
||||
app_model = _resolve_agent_app_model(tenant_id=tenant_id, agent_id=agent_id)
|
||||
args = AgentApiStatusPayload.model_validate(console_ns.payload)
|
||||
app_model = AppService().update_app_api_status(app_model, args.enable_api)
|
||||
app_model = AppService().update_app_api_status(app_model, args.enable_api, session=db.session())
|
||||
return _serialize_agent_api_access(app_model)
|
||||
|
||||
|
||||
|
||||
@ -172,7 +172,7 @@ register_response_schema_models(
|
||||
def _resolve_agent_id(app_model: App, node_id: str | None) -> str | None:
|
||||
if node_id and app_model.mode != AppMode.AGENT:
|
||||
return AgentComposerService.resolve_workflow_node_agent_id(
|
||||
tenant_id=app_model.tenant_id, app_id=app_model.id, node_id=node_id
|
||||
tenant_id=app_model.tenant_id, app_id=app_model.id, node_id=node_id, session=db.session()
|
||||
)
|
||||
return app_model.bound_agent_id
|
||||
|
||||
@ -202,6 +202,7 @@ def _upload_skill_for_app(*, current_user: Account, app_model: App):
|
||||
tenant_id=app_model.tenant_id,
|
||||
user_id=current_user.id,
|
||||
agent_id=agent_id,
|
||||
session=db.session(),
|
||||
)
|
||||
except (SkillPackageError, AgentDriveError) as exc:
|
||||
return {"code": exc.code, "message": exc.message}, exc.status_code
|
||||
@ -240,6 +241,7 @@ def _commit_drive_file_for_app(*, current_user: Account, app_model: App, allow_n
|
||||
value_owned_by_drive=True,
|
||||
)
|
||||
],
|
||||
session=db.session(),
|
||||
)
|
||||
except AgentDriveError as exc:
|
||||
return {"code": exc.code, "message": exc.message}, exc.status_code
|
||||
@ -273,6 +275,7 @@ def _delete_drive_file_for_app(*, current_user: Account, app_model: App, allow_n
|
||||
user_id=current_user.id,
|
||||
agent_id=agent_id,
|
||||
items=[DriveCommitItem(key=key, file_ref=None)],
|
||||
session=db.session(),
|
||||
)
|
||||
except AgentDriveError as exc:
|
||||
return {"code": exc.code, "message": exc.message}, exc.status_code
|
||||
@ -298,6 +301,7 @@ def _delete_skill_for_app(*, current_user: Account, app_model: App, slug: str, a
|
||||
DriveCommitItem(key=f"{slug}/SKILL.md", file_ref=None),
|
||||
DriveCommitItem(key=f"{slug}/.DIFY-SKILL-FULL.zip", file_ref=None),
|
||||
],
|
||||
session=db.session(),
|
||||
)
|
||||
except AgentDriveError as exc:
|
||||
return {"code": exc.code, "message": exc.message}, exc.status_code
|
||||
@ -313,7 +317,9 @@ def _infer_skill_tools_for_app(*, app_model: App, slug: str):
|
||||
if "/" in slug or not slug.strip():
|
||||
return {"code": "drive_key_invalid", "message": "skill slug must be a single path segment"}, 400
|
||||
try:
|
||||
return SkillToolInferenceService().infer(tenant_id=app_model.tenant_id, agent_id=agent_id, slug=slug)
|
||||
return SkillToolInferenceService().infer(
|
||||
tenant_id=app_model.tenant_id, agent_id=agent_id, slug=slug, session=db.session()
|
||||
)
|
||||
except SkillToolInferenceError as exc:
|
||||
return {"code": exc.code, "message": exc.message}, exc.status_code
|
||||
|
||||
@ -335,7 +341,7 @@ class AgentLogApi(Resource):
|
||||
"""Get agent logs"""
|
||||
args = AgentLogQuery.model_validate(request.args.to_dict(flat=True))
|
||||
|
||||
return AgentService.get_agent_logs(app_model, args.conversation_id, args.message_id)
|
||||
return AgentService.get_agent_logs(app_model, args.conversation_id, args.message_id, db.session())
|
||||
|
||||
|
||||
@console_ns.route("/agent/<uuid:agent_id>/skills/upload")
|
||||
|
||||
@ -93,7 +93,7 @@ class AgentAppFeatureConfigResource(Resource):
|
||||
app_model=app_model,
|
||||
account=current_user,
|
||||
config=args.model_dump(exclude_none=True),
|
||||
session=db.session,
|
||||
session=db.session(),
|
||||
)
|
||||
|
||||
app_model_config_was_updated.send(app_model, app_model_config=new_app_model_config)
|
||||
|
||||
@ -25,6 +25,7 @@ from controllers.console import console_ns
|
||||
from controllers.console.agent.app_helpers import resolve_agent_runtime_app_model
|
||||
from controllers.console.app.wraps import get_app_model
|
||||
from controllers.console.wraps import account_initialization_required, setup_required, with_current_tenant_id
|
||||
from extensions.ext_database import db
|
||||
from fields.base import ResponseModel
|
||||
from libs.login import login_required
|
||||
from models.model import App, AppMode
|
||||
@ -269,6 +270,7 @@ class WorkflowAgentSandboxListResource(Resource):
|
||||
node_id=node_id,
|
||||
node_execution_id=query.node_execution_id,
|
||||
path=query.path,
|
||||
session=db.session(),
|
||||
)
|
||||
except Exception as exc:
|
||||
return _handle(exc)
|
||||
@ -305,6 +307,7 @@ class WorkflowAgentSandboxReadResource(Resource):
|
||||
node_id=node_id,
|
||||
node_execution_id=query.node_execution_id,
|
||||
path=query.path,
|
||||
session=db.session(),
|
||||
)
|
||||
except Exception as exc:
|
||||
return _handle(exc)
|
||||
@ -334,6 +337,7 @@ class WorkflowAgentSandboxUploadResource(Resource):
|
||||
node_id=node_id,
|
||||
node_execution_id=payload.node_execution_id,
|
||||
path=payload.path,
|
||||
session=db.session(),
|
||||
)
|
||||
except Exception as exc:
|
||||
return _handle(exc)
|
||||
|
||||
@ -253,6 +253,7 @@ def _resolve_agent_id(app_model: App, node_id: str | None) -> str | None:
|
||||
tenant_id=app_model.tenant_id,
|
||||
app_id=app_model.id,
|
||||
node_id=node_id,
|
||||
session=db.session(),
|
||||
)
|
||||
return app_model.bound_agent_id
|
||||
|
||||
@ -288,13 +289,16 @@ def _resolve_console_version(
|
||||
tenant_id=tenant_id,
|
||||
agent_id=agent_id,
|
||||
account_id=account_id,
|
||||
session=db.session(),
|
||||
)
|
||||
draft = state.get("draft") or {}
|
||||
draft_id = draft.get("id")
|
||||
if isinstance(draft_id, str) and draft_id:
|
||||
return draft_id, AgentConfigVersionKind.BUILD_DRAFT
|
||||
else:
|
||||
state = AgentComposerService.load_agent_composer(tenant_id=tenant_id, agent_id=agent_id)
|
||||
state = AgentComposerService.load_agent_composer(
|
||||
tenant_id=tenant_id, agent_id=agent_id, session=db.session()
|
||||
)
|
||||
draft = state.get("draft") or {}
|
||||
draft_id = draft.get("id")
|
||||
if isinstance(draft_id, str) and draft_id:
|
||||
|
||||
@ -28,6 +28,7 @@ from controllers.console import console_ns
|
||||
from controllers.console.agent.app_helpers import resolve_agent_runtime_app_model
|
||||
from controllers.console.app.wraps import get_app_model
|
||||
from controllers.console.wraps import account_initialization_required, setup_required, with_current_tenant_id
|
||||
from extensions.ext_database import db
|
||||
from fields.base import ResponseModel
|
||||
from libs.login import login_required
|
||||
from models.model import App, AppMode
|
||||
@ -147,7 +148,7 @@ def _resolve_agent_id(app_model: App, node_id: str | None) -> str | None:
|
||||
"""Agent identity for the drive: app-bound agent, or the workflow node binding."""
|
||||
if node_id:
|
||||
return AgentComposerService.resolve_workflow_node_agent_id(
|
||||
tenant_id=app_model.tenant_id, app_id=app_model.id, node_id=node_id
|
||||
tenant_id=app_model.tenant_id, app_id=app_model.id, node_id=node_id, session=db.session()
|
||||
)
|
||||
return app_model.bound_agent_id
|
||||
|
||||
@ -184,7 +185,9 @@ class AgentDriveListByAgentApi(Resource):
|
||||
query = query_params_from_request(AgentDriveListByAgentQuery)
|
||||
resolve_agent_runtime_app_model(tenant_id=tenant_id, agent_id=agent_id)
|
||||
try:
|
||||
items = AgentDriveService().manifest(tenant_id=tenant_id, agent_id=str(agent_id), prefix=query.prefix)
|
||||
items = AgentDriveService().manifest(
|
||||
tenant_id=tenant_id, agent_id=str(agent_id), prefix=query.prefix, session=db.session()
|
||||
)
|
||||
except AgentDriveError as exc:
|
||||
return _handle(exc)
|
||||
return {"items": [{k: v for k, v in item.items() if k != "file_id"} for item in items]}
|
||||
@ -203,7 +206,7 @@ class AgentDriveSkillListByAgentApi(Resource):
|
||||
def get(self, tenant_id: str, agent_id: UUID):
|
||||
resolve_agent_runtime_app_model(tenant_id=tenant_id, agent_id=agent_id)
|
||||
try:
|
||||
items = AgentDriveService().list_skills(tenant_id=tenant_id, agent_id=str(agent_id))
|
||||
items = AgentDriveService().list_skills(tenant_id=tenant_id, agent_id=str(agent_id), session=db.session())
|
||||
except AgentDriveError as exc:
|
||||
return _handle(exc)
|
||||
return {"items": items}
|
||||
@ -227,6 +230,7 @@ class AgentDriveSkillInspectByAgentApi(Resource):
|
||||
tenant_id=tenant_id,
|
||||
agent_id=str(agent_id),
|
||||
skill_path=skill_path,
|
||||
session=db.session(),
|
||||
)
|
||||
)
|
||||
except AgentDriveError as exc:
|
||||
@ -247,7 +251,9 @@ class AgentDrivePreviewByAgentApi(Resource):
|
||||
query = query_params_from_request(AgentDriveFileByAgentQuery)
|
||||
resolve_agent_runtime_app_model(tenant_id=tenant_id, agent_id=agent_id)
|
||||
try:
|
||||
return AgentDriveService().preview(tenant_id=tenant_id, agent_id=str(agent_id), key=query.key)
|
||||
return AgentDriveService().preview(
|
||||
tenant_id=tenant_id, agent_id=str(agent_id), key=query.key, session=db.session()
|
||||
)
|
||||
except AgentDriveError as exc:
|
||||
return _handle(exc)
|
||||
|
||||
@ -266,7 +272,9 @@ class AgentDriveDownloadByAgentApi(Resource):
|
||||
query = query_params_from_request(AgentDriveFileByAgentQuery)
|
||||
resolve_agent_runtime_app_model(tenant_id=tenant_id, agent_id=agent_id)
|
||||
try:
|
||||
url = AgentDriveService().download_url(tenant_id=tenant_id, agent_id=str(agent_id), key=query.key)
|
||||
url = AgentDriveService().download_url(
|
||||
tenant_id=tenant_id, agent_id=str(agent_id), key=query.key, session=db.session()
|
||||
)
|
||||
except AgentDriveError as exc:
|
||||
return _handle(exc)
|
||||
return {"url": url}
|
||||
@ -288,7 +296,9 @@ class AgentDriveListApi(Resource):
|
||||
if not agent_id:
|
||||
return _agent_not_bound()
|
||||
try:
|
||||
items = AgentDriveService().manifest(tenant_id=app_model.tenant_id, agent_id=agent_id, prefix=query.prefix)
|
||||
items = AgentDriveService().manifest(
|
||||
tenant_id=app_model.tenant_id, agent_id=agent_id, prefix=query.prefix, session=db.session()
|
||||
)
|
||||
except AgentDriveError as exc:
|
||||
return _handle(exc)
|
||||
# the inner manifest exposes file_id for agent-side pulls; the console
|
||||
@ -312,7 +322,9 @@ class AgentDriveSkillListApi(Resource):
|
||||
if not agent_id:
|
||||
return _agent_not_bound()
|
||||
try:
|
||||
items = AgentDriveService().list_skills(tenant_id=app_model.tenant_id, agent_id=agent_id)
|
||||
items = AgentDriveService().list_skills(
|
||||
tenant_id=app_model.tenant_id, agent_id=agent_id, session=db.session()
|
||||
)
|
||||
except AgentDriveError as exc:
|
||||
return _handle(exc)
|
||||
return {"items": items}
|
||||
@ -345,6 +357,7 @@ class AgentDriveSkillInspectApi(Resource):
|
||||
tenant_id=app_model.tenant_id,
|
||||
agent_id=agent_id,
|
||||
skill_path=skill_path,
|
||||
session=db.session(),
|
||||
)
|
||||
)
|
||||
except AgentDriveError as exc:
|
||||
@ -367,7 +380,9 @@ class AgentDrivePreviewApi(Resource):
|
||||
if not agent_id:
|
||||
return _agent_not_bound()
|
||||
try:
|
||||
return AgentDriveService().preview(tenant_id=app_model.tenant_id, agent_id=agent_id, key=query.key)
|
||||
return AgentDriveService().preview(
|
||||
tenant_id=app_model.tenant_id, agent_id=agent_id, key=query.key, session=db.session()
|
||||
)
|
||||
except AgentDriveError as exc:
|
||||
return _handle(exc)
|
||||
|
||||
@ -388,7 +403,9 @@ class AgentDriveDownloadApi(Resource):
|
||||
if not agent_id:
|
||||
return _agent_not_bound()
|
||||
try:
|
||||
url = AgentDriveService().download_url(tenant_id=app_model.tenant_id, agent_id=agent_id, key=query.key)
|
||||
url = AgentDriveService().download_url(
|
||||
tenant_id=app_model.tenant_id, agent_id=agent_id, key=query.key, session=db.session()
|
||||
)
|
||||
except AgentDriveError as exc:
|
||||
return _handle(exc)
|
||||
return {"url": url}
|
||||
|
||||
@ -211,7 +211,7 @@ class AppAnnotationSettingDetailApi(Resource):
|
||||
@edit_permission_required
|
||||
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
|
||||
def get(self, app_id: UUID):
|
||||
result = AppAnnotationService.get_app_annotation_setting_by_app_id(str(app_id))
|
||||
result = AppAnnotationService.get_app_annotation_setting_by_app_id(str(app_id), session=db.session())
|
||||
return dump_response(AnnotationSettingResponse, result), 200
|
||||
|
||||
|
||||
@ -235,7 +235,7 @@ class AppAnnotationSettingUpdateApi(Resource):
|
||||
|
||||
setting_args: UpdateAnnotationSettingArgs = {"score_threshold": args.score_threshold}
|
||||
result = AppAnnotationService.update_app_annotation_setting(
|
||||
str(app_id), annotation_setting_id_str, setting_args
|
||||
str(app_id), annotation_setting_id_str, setting_args, session=db.session()
|
||||
)
|
||||
return dump_response(AnnotationSettingResponse, result), 200
|
||||
|
||||
@ -292,7 +292,9 @@ class AnnotationApi(Resource):
|
||||
limit = args.limit
|
||||
keyword = args.keyword
|
||||
|
||||
annotation_list, total = AppAnnotationService.get_annotation_list_by_app_id(str(app_id), page, limit, keyword)
|
||||
annotation_list, total = AppAnnotationService.get_annotation_list_by_app_id(
|
||||
str(app_id), page, limit, keyword, session=db.session()
|
||||
)
|
||||
annotation_models = TypeAdapter(list[Annotation]).validate_python(annotation_list, from_attributes=True)
|
||||
return AnnotationList(
|
||||
data=annotation_models, has_more=len(annotation_list) == limit, limit=limit, total=total, page=page
|
||||
@ -321,7 +323,9 @@ class AnnotationApi(Resource):
|
||||
upsert_args["message_id"] = args.message_id
|
||||
if args.question is not None:
|
||||
upsert_args["question"] = args.question
|
||||
annotation = AppAnnotationService.up_insert_app_annotation_from_message(upsert_args, str(app_id))
|
||||
annotation = AppAnnotationService.up_insert_app_annotation_from_message(
|
||||
upsert_args, str(app_id), session=db.session()
|
||||
)
|
||||
return dump_response(Annotation, annotation), 201
|
||||
|
||||
@setup_required
|
||||
@ -345,11 +349,11 @@ class AnnotationApi(Resource):
|
||||
}, 400
|
||||
|
||||
app_ref = _get_app_ref(str(app_id))
|
||||
AppAnnotationService.delete_app_annotations_in_batch(app_ref, annotation_ids)
|
||||
AppAnnotationService.delete_app_annotations_in_batch(app_ref, annotation_ids, session=db.session())
|
||||
return "", 204
|
||||
# If no annotation_ids are provided, handle clearing all annotations
|
||||
else:
|
||||
AppAnnotationService.clear_all_annotations(str(app_id))
|
||||
AppAnnotationService.clear_all_annotations(str(app_id), session=db.session())
|
||||
return "", 204
|
||||
|
||||
|
||||
@ -370,7 +374,7 @@ class AnnotationExportApi(Resource):
|
||||
@edit_permission_required
|
||||
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_VIEW_LAYOUT)
|
||||
def get(self, app_id: UUID):
|
||||
annotation_list = AppAnnotationService.export_annotation_list_by_app_id(str(app_id))
|
||||
annotation_list = AppAnnotationService.export_annotation_list_by_app_id(str(app_id), session=db.session())
|
||||
annotation_models = TypeAdapter(list[Annotation]).validate_python(annotation_list, from_attributes=True)
|
||||
return (
|
||||
AnnotationExportList(data=annotation_models).model_dump(mode="json"),
|
||||
@ -406,7 +410,7 @@ class AnnotationUpdateDeleteApi(Resource):
|
||||
update_args["question"] = args.question
|
||||
app_ref = _get_app_ref(str(app_id))
|
||||
annotation_ref = AppRefService.create_annotation_ref(app_ref, str(annotation_id))
|
||||
annotation = AppAnnotationService.update_app_annotation_directly(update_args, annotation_ref, db.session)
|
||||
annotation = AppAnnotationService.update_app_annotation_directly(update_args, annotation_ref, db.session())
|
||||
return Annotation.model_validate(annotation, from_attributes=True).model_dump(mode="json")
|
||||
|
||||
@setup_required
|
||||
@ -418,7 +422,7 @@ class AnnotationUpdateDeleteApi(Resource):
|
||||
def delete(self, app_id: UUID, annotation_id: UUID):
|
||||
app_ref = _get_app_ref(str(app_id))
|
||||
annotation_ref = AppRefService.create_annotation_ref(app_ref, str(annotation_id))
|
||||
AppAnnotationService.delete_app_annotation(annotation_ref, db.session)
|
||||
AppAnnotationService.delete_app_annotation(annotation_ref, db.session())
|
||||
return "", 204
|
||||
|
||||
|
||||
@ -477,7 +481,7 @@ class AnnotationBatchImportApi(Resource):
|
||||
|
||||
return dump_response(
|
||||
AnnotationBatchImportResponse,
|
||||
AppAnnotationService.batch_import_app_annotations(str(app_id), file),
|
||||
AppAnnotationService.batch_import_app_annotations(str(app_id), file, session=db.session()),
|
||||
)
|
||||
|
||||
|
||||
@ -538,6 +542,7 @@ class AnnotationHitHistoryListApi(Resource):
|
||||
annotation_ref,
|
||||
page,
|
||||
limit,
|
||||
session=db.session(),
|
||||
)
|
||||
history_models = TypeAdapter(list[AnnotationHitHistory]).validate_python(
|
||||
annotation_hit_history_list, from_attributes=True
|
||||
|
||||
@ -584,6 +584,7 @@ class AppListApi(Resource):
|
||||
permissions = enterprise_rbac_service.RBACService.MyPermissions.get(
|
||||
str(current_tenant_id),
|
||||
current_user_id,
|
||||
session=db.session(),
|
||||
)
|
||||
if dify_config.RBAC_ENABLED:
|
||||
access_filter = resolve_app_access_filter(
|
||||
@ -595,7 +596,7 @@ class AppListApi(Resource):
|
||||
|
||||
# get app list
|
||||
app_service = AppService()
|
||||
app_pagination = app_service.get_paginate_apps(current_user_id, current_tenant_id, params, db.session)
|
||||
app_pagination = app_service.get_paginate_apps(current_user_id, current_tenant_id, params, session)
|
||||
if not app_pagination:
|
||||
response = AppPagination(page=args.page, limit=args.limit, total=0, has_more=False, data=[])
|
||||
return response.model_dump(mode="json"), 200
|
||||
@ -643,11 +644,12 @@ class AppListApi(Resource):
|
||||
)
|
||||
|
||||
app_service = AppService()
|
||||
app = app_service.create_app(current_tenant_id, params, current_user)
|
||||
app = app_service.create_app(current_tenant_id, params, current_user, session=db.session())
|
||||
permission_keys_map = enterprise_rbac_service.RBACService.AppPermissions.batch_get(
|
||||
str(current_tenant_id),
|
||||
current_user.id,
|
||||
[str(app.id)],
|
||||
session=db.session(),
|
||||
)
|
||||
app_detail = AppDetailWithSite.model_validate(app, from_attributes=True).model_copy(
|
||||
update={"permission_keys": permission_keys_map.get(str(app.id), [])}
|
||||
@ -681,7 +683,7 @@ class StarredAppListApi(Resource):
|
||||
is_created_by_me=args.is_created_by_me,
|
||||
)
|
||||
|
||||
app_pagination = AppService().get_paginate_starred_apps(current_user_id, current_tenant_id, params, db.session)
|
||||
app_pagination = AppService().get_paginate_starred_apps(current_user_id, current_tenant_id, params, session)
|
||||
if not app_pagination:
|
||||
empty = AppPagination(page=args.page, limit=args.limit, total=0, has_more=False, data=[])
|
||||
return empty.model_dump(mode="json"), 200
|
||||
@ -705,7 +707,7 @@ class AppStarApi(Resource):
|
||||
@with_session
|
||||
@get_app_model(mode=None)
|
||||
def post(self, session: Session, current_user_id: str, app_model: App):
|
||||
AppService.star_app(session, app=app_model, account_id=current_user_id)
|
||||
AppService.star_app(app=app_model, account_id=current_user_id, session=session)
|
||||
return SimpleResultResponse(result="success").model_dump(mode="json")
|
||||
|
||||
@console_ns.doc("unstar_app")
|
||||
@ -721,7 +723,7 @@ class AppStarApi(Resource):
|
||||
@with_session
|
||||
@get_app_model(mode=None)
|
||||
def delete(self, session: Session, current_user_id: str, app_model: App):
|
||||
AppService.unstar_app(session, app=app_model, account_id=current_user_id)
|
||||
AppService.unstar_app(app=app_model, account_id=current_user_id, session=session)
|
||||
return SimpleResultResponse(result="success").model_dump(mode="json")
|
||||
|
||||
|
||||
@ -753,6 +755,7 @@ class AppApi(Resource):
|
||||
str(current_tenant_id),
|
||||
current_user.id,
|
||||
app_id=str(app_model.id),
|
||||
session=db.session(),
|
||||
)
|
||||
permission_keys_map = permissions.app.permission_keys_by_resource_ids([str(app_model.id)])
|
||||
|
||||
@ -789,7 +792,7 @@ class AppApi(Resource):
|
||||
"use_icon_as_answer_icon": args.use_icon_as_answer_icon or False,
|
||||
"max_active_requests": args.max_active_requests or 0,
|
||||
}
|
||||
app_model = app_service.update_app(app_model, args_dict)
|
||||
app_model = app_service.update_app(app_model, args_dict, session=db.session())
|
||||
return dump_response(AppDetailWithSite, app_model)
|
||||
|
||||
@console_ns.doc("delete_app")
|
||||
@ -806,7 +809,7 @@ class AppApi(Resource):
|
||||
def delete(self, app_model: App):
|
||||
"""Delete app"""
|
||||
app_service = AppService()
|
||||
app_service.delete_app(app_model)
|
||||
app_service.delete_app(app_model, session=db.session())
|
||||
|
||||
return "", 204
|
||||
|
||||
@ -835,7 +838,7 @@ class AppCopyApi(Resource):
|
||||
|
||||
with Session(db.engine, expire_on_commit=False) as session:
|
||||
import_service = AppDslService(session)
|
||||
yaml_content = import_service.export_dsl(app_model=app_model, include_secret=True)
|
||||
yaml_content = import_service.export_dsl(app_model=app_model, session=session, include_secret=True)
|
||||
result = import_service.import_app(
|
||||
account=current_user,
|
||||
import_mode=ImportMode.YAML_CONTENT,
|
||||
@ -877,6 +880,7 @@ class AppCopyApi(Resource):
|
||||
str(current_tenant_id),
|
||||
current_user.id,
|
||||
[str(app.id)],
|
||||
session=db.session(),
|
||||
)
|
||||
response_model = AppDetailWithSite.model_validate(app, from_attributes=True).model_copy(
|
||||
update={"permission_keys": permission_keys_map.get(str(app.id), [])}
|
||||
@ -905,6 +909,7 @@ class AppExportApi(Resource):
|
||||
response = AppExportResponse(
|
||||
data=AppDslService.export_dsl(
|
||||
app_model=app_model,
|
||||
session=db.session(),
|
||||
include_secret=args.include_secret,
|
||||
workflow_id=args.workflow_id,
|
||||
)
|
||||
@ -929,7 +934,7 @@ class AppPublishToCreatorsPlatformApi(Resource):
|
||||
if not dify_config.CREATORS_PLATFORM_FEATURES_ENABLED:
|
||||
return {"error": "Creators Platform features are not enabled"}, 403
|
||||
|
||||
dsl_content = AppDslService.export_dsl(app_model=app_model, include_secret=False)
|
||||
dsl_content = AppDslService.export_dsl(app_model=app_model, session=db.session(), include_secret=False)
|
||||
dsl_bytes = dsl_content.encode("utf-8")
|
||||
|
||||
claim_code = upload_dsl(dsl_bytes)
|
||||
@ -955,7 +960,7 @@ class AppNameApi(Resource):
|
||||
args = AppNamePayload.model_validate(console_ns.payload)
|
||||
|
||||
app_service = AppService()
|
||||
app_model = app_service.update_app_name(app_model, args.name)
|
||||
app_model = app_service.update_app_name(app_model, args.name, session=db.session())
|
||||
return dump_response(AppDetail, app_model)
|
||||
|
||||
|
||||
@ -982,6 +987,7 @@ class AppIconApi(Resource):
|
||||
args.icon or "",
|
||||
args.icon_background or "",
|
||||
args.icon_type,
|
||||
session=db.session(),
|
||||
)
|
||||
return dump_response(AppDetail, app_model)
|
||||
|
||||
@ -1004,7 +1010,7 @@ class AppSiteStatus(Resource):
|
||||
args = AppSiteStatusPayload.model_validate(console_ns.payload)
|
||||
|
||||
app_service = AppService()
|
||||
app_model = app_service.update_app_site_status(app_model, args.enable_site)
|
||||
app_model = app_service.update_app_site_status(app_model, args.enable_site, session=db.session())
|
||||
return dump_response(AppDetail, app_model)
|
||||
|
||||
|
||||
@ -1026,7 +1032,7 @@ class AppApiStatus(Resource):
|
||||
args = AppApiStatusPayload.model_validate(console_ns.payload)
|
||||
|
||||
app_service = AppService()
|
||||
app_model = app_service.update_app_api_status(app_model, args.enable_api)
|
||||
app_model = app_service.update_app_api_status(app_model, args.enable_api, session=db.session())
|
||||
return dump_response(AppDetail, app_model)
|
||||
|
||||
|
||||
|
||||
@ -161,7 +161,7 @@ class ChatMessageTextApi(Resource):
|
||||
# response-contract:ignore
|
||||
return AudioService.transcript_tts(
|
||||
app_model=app_model,
|
||||
session=db.session,
|
||||
session=db.session(),
|
||||
text=payload.text,
|
||||
voice=payload.voice,
|
||||
message_ref=message_ref,
|
||||
|
||||
@ -200,7 +200,7 @@ class CompletionConversationDetailApi(Resource):
|
||||
conversation_id_str = str(conversation_id)
|
||||
|
||||
try:
|
||||
ConversationService.delete(app_model, conversation_id_str, current_user)
|
||||
ConversationService.delete(app_model, conversation_id_str, current_user, session=db.session())
|
||||
except ConversationNotExistsError:
|
||||
raise NotFound("Conversation Not Exists.")
|
||||
|
||||
@ -354,7 +354,7 @@ class ChatConversationDetailApi(Resource):
|
||||
conversation_id_str = str(conversation_id)
|
||||
|
||||
try:
|
||||
ConversationService.delete(app_model, conversation_id_str, current_user)
|
||||
ConversationService.delete(app_model, conversation_id_str, current_user, session=db.session())
|
||||
except ConversationNotExistsError:
|
||||
raise NotFound("Conversation Not Exists.")
|
||||
|
||||
|
||||
@ -363,6 +363,7 @@ def _list_chat_messages(*, app_model: App, current_user: Account | None = None):
|
||||
app_model=app_model,
|
||||
conversation_id=args.conversation_id,
|
||||
user=current_user,
|
||||
session=db.session(),
|
||||
)
|
||||
except ConversationNotExistsError:
|
||||
raise NotFound("Conversation Not Exists.")
|
||||
@ -474,7 +475,11 @@ def _get_message_suggested_questions(*, current_user: Account, app_model: App, m
|
||||
|
||||
try:
|
||||
questions = MessageService.get_suggested_questions_after_answer(
|
||||
app_model=app_model, message_id=message_id_str, user=current_user, invoke_from=InvokeFrom.DEBUGGER
|
||||
app_model=app_model,
|
||||
message_id=message_id_str,
|
||||
user=current_user,
|
||||
invoke_from=InvokeFrom.DEBUGGER,
|
||||
session=db.session(),
|
||||
)
|
||||
except MessageNotExistsError:
|
||||
raise NotFound("Message not found")
|
||||
|
||||
@ -17,6 +17,7 @@ from controllers.console.wraps import (
|
||||
rbac_permission_required,
|
||||
setup_required,
|
||||
)
|
||||
from extensions.ext_database import db
|
||||
from fields.base import ResponseModel
|
||||
from libs.login import login_required
|
||||
from models import App
|
||||
@ -78,7 +79,7 @@ class TraceAppConfigApi(Resource):
|
||||
|
||||
try:
|
||||
trace_config = OpsService.get_tracing_app_config(
|
||||
app_id=app_model.id, tracing_provider=args.tracing_provider
|
||||
app_id=app_model.id, tracing_provider=args.tracing_provider, session=db.session()
|
||||
)
|
||||
if not trace_config:
|
||||
return {"has_not_configured": True}
|
||||
@ -109,7 +110,10 @@ class TraceAppConfigApi(Resource):
|
||||
|
||||
try:
|
||||
result = OpsService.create_tracing_app_config(
|
||||
app_id=app_model.id, tracing_provider=args.tracing_provider, tracing_config=args.tracing_config
|
||||
app_id=app_model.id,
|
||||
tracing_provider=args.tracing_provider,
|
||||
tracing_config=args.tracing_config,
|
||||
session=db.session(),
|
||||
)
|
||||
if not result:
|
||||
raise TracingConfigIsExist()
|
||||
@ -142,7 +146,10 @@ class TraceAppConfigApi(Resource):
|
||||
|
||||
try:
|
||||
result = OpsService.update_tracing_app_config(
|
||||
app_id=app_model.id, tracing_provider=args.tracing_provider, tracing_config=args.tracing_config
|
||||
app_id=app_model.id,
|
||||
tracing_provider=args.tracing_provider,
|
||||
tracing_config=args.tracing_config,
|
||||
session=db.session(),
|
||||
)
|
||||
if not result:
|
||||
raise TracingConfigNotExist()
|
||||
@ -168,7 +175,9 @@ class TraceAppConfigApi(Resource):
|
||||
args = TraceProviderQuery.model_validate(request.args.to_dict(flat=True))
|
||||
|
||||
try:
|
||||
result = OpsService.delete_tracing_app_config(app_id=app_model.id, tracing_provider=args.tracing_provider)
|
||||
result = OpsService.delete_tracing_app_config(
|
||||
app_id=app_model.id, tracing_provider=args.tracing_provider, session=db.session()
|
||||
)
|
||||
if not result:
|
||||
raise TracingConfigNotExist()
|
||||
return "", 204
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
from extensions.ext_database import db
|
||||
from services.enterprise import rbac_service as enterprise_rbac_service
|
||||
|
||||
|
||||
def get_app_permission_keys(tenant_id: str, account_id: str | None, app_id: str) -> list[str]:
|
||||
permission_keys_map = enterprise_rbac_service.RBACService.AppPermissions.batch_get(tenant_id, account_id, [app_id])
|
||||
permission_keys_map = enterprise_rbac_service.RBACService.AppPermissions.batch_get(
|
||||
tenant_id, account_id, [app_id], session=db.session()
|
||||
)
|
||||
return permission_keys_map.get(app_id, [])
|
||||
|
||||
@ -2,7 +2,7 @@ import json
|
||||
import logging
|
||||
from collections.abc import Sequence
|
||||
from datetime import datetime
|
||||
from typing import Any, NotRequired, TypedDict, cast
|
||||
from typing import Any, NotRequired, TypedDict
|
||||
|
||||
from flask import abort, request
|
||||
from flask_restx import Resource, fields
|
||||
@ -522,7 +522,7 @@ class DraftWorkflowApi(Resource):
|
||||
"""
|
||||
# fetch draft workflow by app_model
|
||||
workflow_service = WorkflowService()
|
||||
workflow = workflow_service.get_draft_workflow(app_model=app_model)
|
||||
workflow = workflow_service.get_draft_workflow(app_model=app_model, session=db.session())
|
||||
|
||||
if not workflow:
|
||||
raise DraftWorkflowNotExist()
|
||||
@ -533,7 +533,7 @@ class DraftWorkflowApi(Resource):
|
||||
# front-end can treat draft graph node data as the editing source.
|
||||
response = WorkflowResponse.model_validate(workflow, from_attributes=True).model_dump(mode="json")
|
||||
response["graph"] = WorkflowAgentPublishService.project_draft_bindings_to_graph(
|
||||
session=cast(Session, db.session),
|
||||
session=db.session(),
|
||||
draft_workflow=workflow,
|
||||
)
|
||||
return response
|
||||
@ -602,6 +602,7 @@ class DraftWorkflowApi(Resource):
|
||||
account=current_user,
|
||||
environment_variables=environment_variables,
|
||||
conversation_variables=conversation_variables,
|
||||
session=db.session(),
|
||||
)
|
||||
except WorkflowHashNotEqualError:
|
||||
raise DraftWorkflowNotSync()
|
||||
@ -695,7 +696,12 @@ class AdvancedChatDraftRunIterationNodeApi(Resource):
|
||||
|
||||
try:
|
||||
response = AppGenerateService.generate_single_iteration(
|
||||
app_model=app_model, user=current_user, node_id=node_id, args=args, streaming=True
|
||||
app_model=app_model,
|
||||
user=current_user,
|
||||
node_id=node_id,
|
||||
args=args,
|
||||
session=db.session(),
|
||||
streaming=True,
|
||||
)
|
||||
|
||||
return helper.compact_generate_response(response)
|
||||
@ -738,7 +744,12 @@ class WorkflowDraftRunIterationNodeApi(Resource):
|
||||
|
||||
try:
|
||||
response = AppGenerateService.generate_single_iteration(
|
||||
app_model=app_model, user=current_user, node_id=node_id, args=args, streaming=True
|
||||
app_model=app_model,
|
||||
user=current_user,
|
||||
node_id=node_id,
|
||||
args=args,
|
||||
session=db.session(),
|
||||
streaming=True,
|
||||
)
|
||||
|
||||
return helper.compact_generate_response(response)
|
||||
@ -777,7 +788,12 @@ class AdvancedChatDraftRunLoopNodeApi(Resource):
|
||||
|
||||
try:
|
||||
response = AppGenerateService.generate_single_loop(
|
||||
app_model=app_model, user=current_user, node_id=node_id, args=args, streaming=True
|
||||
app_model=app_model,
|
||||
user=current_user,
|
||||
node_id=node_id,
|
||||
args=args,
|
||||
session=db.session(),
|
||||
streaming=True,
|
||||
)
|
||||
|
||||
return helper.compact_generate_response(response)
|
||||
@ -820,7 +836,12 @@ class WorkflowDraftRunLoopNodeApi(Resource):
|
||||
|
||||
try:
|
||||
response = AppGenerateService.generate_single_loop(
|
||||
app_model=app_model, user=current_user, node_id=node_id, args=args, streaming=True
|
||||
app_model=app_model,
|
||||
user=current_user,
|
||||
node_id=node_id,
|
||||
args=args,
|
||||
session=db.session(),
|
||||
streaming=True,
|
||||
)
|
||||
|
||||
return helper.compact_generate_response(response)
|
||||
@ -897,6 +918,7 @@ class AdvancedChatDraftHumanInputFormPreviewApi(Resource):
|
||||
account=current_user,
|
||||
node_id=node_id,
|
||||
inputs=inputs,
|
||||
session=db.session(),
|
||||
)
|
||||
return jsonable_encoder(preview)
|
||||
|
||||
@ -932,6 +954,7 @@ class AdvancedChatDraftHumanInputFormRunApi(Resource):
|
||||
form_inputs=args.form_inputs,
|
||||
inputs=args.inputs,
|
||||
action=args.action,
|
||||
session=db.session(),
|
||||
)
|
||||
return jsonable_encoder(result)
|
||||
|
||||
@ -963,6 +986,7 @@ class WorkflowDraftHumanInputFormPreviewApi(Resource):
|
||||
account=current_user,
|
||||
node_id=node_id,
|
||||
inputs=inputs,
|
||||
session=db.session(),
|
||||
)
|
||||
return jsonable_encoder(preview)
|
||||
|
||||
@ -998,6 +1022,7 @@ class WorkflowDraftHumanInputFormRunApi(Resource):
|
||||
form_inputs=args.form_inputs,
|
||||
inputs=args.inputs,
|
||||
action=args.action,
|
||||
session=db.session(),
|
||||
)
|
||||
return jsonable_encoder(result)
|
||||
|
||||
@ -1028,6 +1053,7 @@ class WorkflowDraftHumanInputDeliveryTestApi(Resource):
|
||||
node_id=node_id,
|
||||
delivery_method_id=args.delivery_method_id,
|
||||
inputs=args.inputs,
|
||||
session=db.session(),
|
||||
)
|
||||
return jsonable_encoder({})
|
||||
|
||||
@ -1138,7 +1164,7 @@ class DraftWorkflowNodeRunApi(Resource):
|
||||
|
||||
workflow_srv = WorkflowService()
|
||||
# fetch draft workflow by app_model
|
||||
draft_workflow = workflow_srv.get_draft_workflow(app_model=app_model)
|
||||
draft_workflow = workflow_srv.get_draft_workflow(app_model=app_model, session=db.session())
|
||||
if not draft_workflow:
|
||||
raise ValueError("Workflow not initialized")
|
||||
files = _parse_file(draft_workflow, args.get("files"))
|
||||
@ -1181,7 +1207,7 @@ class PublishedWorkflowApi(Resource):
|
||||
"""
|
||||
# fetch published workflow by app_model
|
||||
workflow_service = WorkflowService()
|
||||
workflow = workflow_service.get_published_workflow(app_model=app_model)
|
||||
workflow = workflow_service.get_published_workflow(app_model=app_model, session=db.session())
|
||||
|
||||
# return workflow, if not found, return None
|
||||
if workflow is None:
|
||||
@ -1323,7 +1349,9 @@ class ConvertToWorkflowApi(Resource):
|
||||
|
||||
# convert to workflow mode
|
||||
workflow_service = WorkflowService()
|
||||
new_app_model = workflow_service.convert_to_workflow(app_model=app_model, account=current_user, args=args)
|
||||
new_app_model = workflow_service.convert_to_workflow(
|
||||
app_model=app_model, account=current_user, args=args, session=db.session()
|
||||
)
|
||||
|
||||
# return app id
|
||||
return {
|
||||
@ -1358,7 +1386,9 @@ class WorkflowFeaturesApi(Resource):
|
||||
features = args.features.model_dump(mode="json", exclude_unset=True)
|
||||
|
||||
workflow_service = WorkflowService()
|
||||
workflow_service.update_draft_workflow_features(app_model=app_model, features=features, account=current_user)
|
||||
workflow_service.update_draft_workflow_features(
|
||||
app_model=app_model, features=features, account=current_user, session=db.session()
|
||||
)
|
||||
|
||||
return {"result": "success"}
|
||||
|
||||
@ -1439,6 +1469,7 @@ class DraftWorkflowRestoreApi(Resource):
|
||||
app_model=app_model,
|
||||
workflow_id=workflow_id,
|
||||
account=current_user,
|
||||
session=db.session(),
|
||||
)
|
||||
except IsDraftWorkflowError as exc:
|
||||
raise BadRequest(RESTORE_SOURCE_WORKFLOW_MUST_BE_PUBLISHED_MESSAGE) from exc
|
||||
@ -1553,7 +1584,7 @@ class DraftWorkflowNodeLastRunApi(Resource):
|
||||
@get_app_model(mode=[AppMode.ADVANCED_CHAT, AppMode.WORKFLOW])
|
||||
def get(self, app_model: App, node_id: str):
|
||||
srv = WorkflowService()
|
||||
workflow = srv.get_draft_workflow(app_model)
|
||||
workflow = srv.get_draft_workflow(app_model, session=db.session())
|
||||
if not workflow:
|
||||
raise NotFound("Workflow not found")
|
||||
node_exec = srv.get_node_last_run(
|
||||
@ -1606,7 +1637,7 @@ class DraftWorkflowTriggerRunApi(Resource):
|
||||
args = DraftWorkflowTriggerRunPayload.model_validate(console_ns.payload or {})
|
||||
node_id = args.node_id
|
||||
workflow_service = WorkflowService()
|
||||
draft_workflow = workflow_service.get_draft_workflow(app_model)
|
||||
draft_workflow = workflow_service.get_draft_workflow(app_model, session=db.session())
|
||||
if not draft_workflow:
|
||||
raise ValueError("Workflow not found")
|
||||
|
||||
@ -1675,7 +1706,7 @@ class DraftWorkflowTriggerNodeApi(Resource):
|
||||
"""
|
||||
|
||||
workflow_service = WorkflowService()
|
||||
draft_workflow = workflow_service.get_draft_workflow(app_model)
|
||||
draft_workflow = workflow_service.get_draft_workflow(app_model, session=db.session())
|
||||
if not draft_workflow:
|
||||
raise ValueError("Workflow not found")
|
||||
|
||||
@ -1759,7 +1790,7 @@ class DraftWorkflowTriggerRunAllApi(Resource):
|
||||
args = DraftWorkflowTriggerRunAllPayload.model_validate(console_ns.payload or {})
|
||||
node_ids = args.node_ids
|
||||
workflow_service = WorkflowService()
|
||||
draft_workflow = workflow_service.get_draft_workflow(app_model)
|
||||
draft_workflow = workflow_service.get_draft_workflow(app_model, session=db.session())
|
||||
if not draft_workflow:
|
||||
raise ValueError("Workflow not found")
|
||||
|
||||
@ -1828,7 +1859,7 @@ class WorkflowOnlineUsersApi(Resource):
|
||||
return {"data": []}
|
||||
|
||||
workflow_service = WorkflowService()
|
||||
accessible_app_ids = workflow_service.get_accessible_app_ids(app_ids, current_tenant_id)
|
||||
accessible_app_ids = workflow_service.get_accessible_app_ids(app_ids, current_tenant_id, session=db.session())
|
||||
ordered_accessible_app_ids = [app_id for app_id in app_ids if app_id in accessible_app_ids]
|
||||
|
||||
users_json_by_app_id: dict[str, Any] = {}
|
||||
|
||||
@ -490,7 +490,7 @@ class WorkflowCommentMentionUsersApi(Resource):
|
||||
current_tenant = current_user.current_tenant # need the tenant object here
|
||||
if current_tenant is None:
|
||||
raise ValueError("current tenant is required")
|
||||
members = TenantService.get_tenant_members(current_tenant, session=db.session)
|
||||
members = TenantService.get_tenant_members(current_tenant, session=db.session())
|
||||
users = TypeAdapter(list[AccountWithRole]).validate_python(members, from_attributes=True)
|
||||
response = WorkflowCommentMentionUsersPayload(users=users)
|
||||
return response.model_dump(mode="json"), 200
|
||||
|
||||
@ -337,7 +337,7 @@ class WorkflowVariableCollectionApi(Resource):
|
||||
|
||||
# fetch draft workflow by app_model
|
||||
workflow_service = WorkflowService()
|
||||
workflow_exist = workflow_service.is_workflow_exist(app_model=app_model)
|
||||
workflow_exist = workflow_service.is_workflow_exist(app_model=app_model, session=db.session())
|
||||
if not workflow_exist:
|
||||
raise DraftWorkflowNotExist()
|
||||
|
||||
@ -553,7 +553,7 @@ class VariableResetApi(Resource):
|
||||
)
|
||||
|
||||
workflow_srv = WorkflowService()
|
||||
draft_workflow = workflow_srv.get_draft_workflow(app_model)
|
||||
draft_workflow = workflow_srv.get_draft_workflow(app_model, session=db.session())
|
||||
if draft_workflow is None:
|
||||
raise NotFoundError(
|
||||
f"Draft workflow not found, app_id={app_model.id}",
|
||||
@ -606,7 +606,7 @@ class ConversationVariableCollectionApi(Resource):
|
||||
# NOTE(QuantumGhost): Prefill conversation variables into the draft variables table
|
||||
# so their IDs can be returned to the caller.
|
||||
workflow_srv = WorkflowService()
|
||||
draft_workflow = workflow_srv.get_draft_workflow(app_model)
|
||||
draft_workflow = workflow_srv.get_draft_workflow(app_model, session=db.session())
|
||||
if draft_workflow is None:
|
||||
raise NotFoundError(description=f"draft workflow not found, id={app_model.id}")
|
||||
draft_var_srv = WorkflowDraftVariableService(db.session())
|
||||
@ -646,6 +646,7 @@ class ConversationVariableCollectionApi(Resource):
|
||||
app_model=app_model,
|
||||
account=current_user,
|
||||
conversation_variables=conversation_variables,
|
||||
session=db.session(),
|
||||
)
|
||||
|
||||
return {"result": "success"}
|
||||
@ -683,7 +684,7 @@ class EnvironmentVariableCollectionApi(Resource):
|
||||
"""
|
||||
# fetch draft workflow by app_model
|
||||
workflow_service = WorkflowService()
|
||||
workflow = workflow_service.get_draft_workflow(app_model=app_model)
|
||||
workflow = workflow_service.get_draft_workflow(app_model=app_model, session=db.session())
|
||||
if workflow is None:
|
||||
raise DraftWorkflowNotExist()
|
||||
|
||||
@ -740,6 +741,7 @@ class EnvironmentVariableCollectionApi(Resource):
|
||||
app_model=app_model,
|
||||
account=current_user,
|
||||
environment_variables=environment_variables,
|
||||
session=db.session(),
|
||||
)
|
||||
|
||||
return {"result": "success"}
|
||||
|
||||
@ -41,6 +41,7 @@ from controllers.console.wraps import (
|
||||
rbac_permission_required,
|
||||
setup_required,
|
||||
)
|
||||
from extensions.ext_database import db
|
||||
from libs.exception import BaseHTTPException
|
||||
from libs.login import login_required
|
||||
from models import App, AppMode
|
||||
@ -92,7 +93,9 @@ def _serve_snapshot(app_model: App, run_id: UUID) -> dict:
|
||||
Flask request context.
|
||||
"""
|
||||
try:
|
||||
snapshot = _service().snapshot_workflow_run(app_model=app_model, workflow_run_id=str(run_id))
|
||||
snapshot = _service().snapshot_workflow_run(
|
||||
app_model=app_model, workflow_run_id=str(run_id), session=db.session()
|
||||
)
|
||||
except NodeOutputInspectorError as error:
|
||||
raise _InspectorNotFound(error) from error
|
||||
return snapshot.model_dump(mode="json")
|
||||
@ -105,6 +108,7 @@ def _serve_node_detail(app_model: App, run_id: UUID, node_id: str) -> dict:
|
||||
app_model=app_model,
|
||||
workflow_run_id=str(run_id),
|
||||
node_id=node_id,
|
||||
session=db.session(),
|
||||
)
|
||||
except NodeOutputInspectorError as error:
|
||||
raise _InspectorNotFound(error) from error
|
||||
@ -119,6 +123,7 @@ def _serve_output_preview(app_model: App, run_id: UUID, node_id: str, output_nam
|
||||
workflow_run_id=str(run_id),
|
||||
node_id=node_id,
|
||||
output_name=output_name,
|
||||
session=db.session(),
|
||||
)
|
||||
except NodeOutputInspectorError as error:
|
||||
raise _InspectorNotFound(error) from error
|
||||
@ -245,7 +250,7 @@ def _stream_inspector_events(app_model: App, run_id: UUID) -> Iterator[str]:
|
||||
# if the run is gone (raised before yielding any bytes, so Flask turns it
|
||||
# into the normal HTTP 404 path).
|
||||
try:
|
||||
snapshot = service.snapshot_workflow_run(app_model=app_model, workflow_run_id=run_id_str)
|
||||
snapshot = service.snapshot_workflow_run(app_model=app_model, workflow_run_id=run_id_str, session=db.session())
|
||||
except NodeOutputInspectorError as error:
|
||||
raise _InspectorNotFound(error) from error
|
||||
|
||||
@ -308,6 +313,7 @@ def _stream_inspector_events(app_model: App, run_id: UUID) -> Iterator[str]:
|
||||
app_model=app_model,
|
||||
workflow_run_id=run_id_str,
|
||||
node_id=message.node_id,
|
||||
session=db.session(),
|
||||
)
|
||||
except NodeOutputInspectorError:
|
||||
# Node may not appear in the graph yet (race with persistence); skip.
|
||||
|
||||
@ -90,7 +90,7 @@ class ActivateCheckApi(Resource):
|
||||
token = args.token
|
||||
|
||||
invitation = RegisterService.get_invitation_with_case_fallback(
|
||||
workspaceId, args.email, token, session=db.session
|
||||
workspaceId, args.email, token, session=db.session()
|
||||
)
|
||||
if invitation:
|
||||
data = invitation.get("data", {})
|
||||
@ -140,7 +140,7 @@ class ActivateApi(Resource):
|
||||
|
||||
normalized_request_email = args.email.lower() if args.email else None
|
||||
invitation = RegisterService.get_invitation_with_case_fallback(
|
||||
args.workspace_id, args.email, args.token, session=db.session
|
||||
args.workspace_id, args.email, args.token, session=db.session()
|
||||
)
|
||||
if invitation is None:
|
||||
raise AlreadyActivateError()
|
||||
@ -178,7 +178,7 @@ class ActivateApi(Resource):
|
||||
RegisterService.revoke_token(args.workspace_id, normalized_request_email, args.token)
|
||||
|
||||
if membership_id is None:
|
||||
TenantService.create_tenant_member(tenant, account, db.session, role=role)
|
||||
TenantService.create_tenant_member(tenant, account, db.session(), role=role)
|
||||
|
||||
if setup_fields:
|
||||
account.name = setup_fields[0]
|
||||
@ -188,6 +188,6 @@ class ActivateApi(Resource):
|
||||
account.status = AccountStatus.ACTIVE
|
||||
account.initialized_at = naive_utc_now()
|
||||
|
||||
TenantService.switch_tenant(account, tenant.id, session=db.session)
|
||||
TenantService.switch_tenant(account, tenant.id, session=db.session())
|
||||
|
||||
return {"result": "success"}
|
||||
|
||||
@ -59,7 +59,7 @@ class ApiKeyAuthDataSource(Resource):
|
||||
@account_initialization_required
|
||||
@with_current_tenant_id
|
||||
def get(self, current_tenant_id: str):
|
||||
data_source_api_key_bindings = ApiKeyAuthService.get_provider_auth_list(db.session(), current_tenant_id)
|
||||
data_source_api_key_bindings = ApiKeyAuthService.get_provider_auth_list(current_tenant_id, session=db.session())
|
||||
if data_source_api_key_bindings:
|
||||
return {
|
||||
"sources": [
|
||||
@ -93,7 +93,7 @@ class ApiKeyAuthDataSourceBinding(Resource):
|
||||
data = payload.model_dump()
|
||||
ApiKeyAuthService.validate_api_key_auth_args(data)
|
||||
try:
|
||||
ApiKeyAuthService.create_provider_auth(db.session(), current_tenant_id, data)
|
||||
ApiKeyAuthService.create_provider_auth(current_tenant_id, data, session=db.session())
|
||||
except Exception as e:
|
||||
raise ApiKeyAuthFailedError(str(e))
|
||||
return {"result": "success"}, 200
|
||||
@ -110,6 +110,6 @@ class ApiKeyAuthDataSourceBindingDelete(Resource):
|
||||
@with_current_tenant_id
|
||||
def delete(self, current_tenant_id: str, binding_id: UUID):
|
||||
# The role of the current user in the table must be admin or owner
|
||||
ApiKeyAuthService.delete_provider_auth(db.session(), current_tenant_id, str(binding_id))
|
||||
ApiKeyAuthService.delete_provider_auth(current_tenant_id, str(binding_id), session=db.session())
|
||||
|
||||
return "", 204
|
||||
|
||||
@ -101,7 +101,7 @@ class EmailRegisterSendEmailApi(Resource):
|
||||
if dify_config.BILLING_ENABLED and BillingService.is_email_in_freeze(normalized_email):
|
||||
raise AccountInFreezeError()
|
||||
|
||||
account = AccountService.get_account_by_email_with_case_fallback(db.session, args.email)
|
||||
account = AccountService.get_account_by_email_with_case_fallback(args.email, session=db.session())
|
||||
token = AccountService.send_email_register_email(email=normalized_email, account=account, language=language)
|
||||
return {"result": "success", "data": token}
|
||||
|
||||
@ -176,7 +176,7 @@ class EmailRegisterResetApi(Resource):
|
||||
email = register_data.get("email", "")
|
||||
normalized_email = email.lower()
|
||||
|
||||
account = AccountService.get_account_by_email_with_case_fallback(db.session, email)
|
||||
account = AccountService.get_account_by_email_with_case_fallback(email, session=db.session())
|
||||
|
||||
if account:
|
||||
raise EmailAlreadyInUseError()
|
||||
@ -187,7 +187,7 @@ class EmailRegisterResetApi(Resource):
|
||||
timezone=args.timezone,
|
||||
language=args.language,
|
||||
)
|
||||
token_pair = AccountService.login(account=account, session=db.session, ip_address=extract_remote_ip(request))
|
||||
token_pair = AccountService.login(account=account, session=db.session(), ip_address=extract_remote_ip(request))
|
||||
AccountService.reset_login_error_rate_limit(normalized_email)
|
||||
|
||||
return {"result": "success", "data": token_pair.model_dump()}
|
||||
@ -206,7 +206,7 @@ class EmailRegisterResetApi(Resource):
|
||||
password=password,
|
||||
interface_language=get_valid_language(language),
|
||||
timezone=timezone,
|
||||
session=db.session,
|
||||
session=db.session(),
|
||||
)
|
||||
except AccountRegisterError:
|
||||
raise AccountInFreezeError()
|
||||
|
||||
@ -82,7 +82,7 @@ class ForgotPasswordSendEmailApi(Resource):
|
||||
else:
|
||||
language = "en-US"
|
||||
|
||||
account = AccountService.get_account_by_email_with_case_fallback(db.session, args.email)
|
||||
account = AccountService.get_account_by_email_with_case_fallback(args.email, session=db.session())
|
||||
|
||||
token = AccountService.send_reset_password_email(
|
||||
account=account,
|
||||
@ -180,7 +180,7 @@ class ForgotPasswordResetApi(Resource):
|
||||
password_hashed = hash_password(args.new_password, salt)
|
||||
|
||||
email = reset_data.get("email", "")
|
||||
account = AccountService.get_account_by_email_with_case_fallback(db.session, email)
|
||||
account = AccountService.get_account_by_email_with_case_fallback(email, session=db.session())
|
||||
|
||||
if account:
|
||||
account = db.session.merge(account)
|
||||
@ -198,10 +198,10 @@ class ForgotPasswordResetApi(Resource):
|
||||
|
||||
# Create workspace if needed
|
||||
if (
|
||||
not TenantService.get_join_tenants(account, session=db.session)
|
||||
not TenantService.get_join_tenants(account, session=db.session())
|
||||
and FeatureService.get_system_features().is_allow_create_workspace
|
||||
):
|
||||
tenant = TenantService.create_tenant(f"{account.name}'s Workspace", session=db.session)
|
||||
TenantService.create_tenant_member(tenant, account, db.session, role="owner")
|
||||
tenant = TenantService.create_tenant(f"{account.name}'s Workspace", session=db.session())
|
||||
TenantService.create_tenant_member(tenant, account, db.session(), role="owner")
|
||||
account.current_tenant = tenant
|
||||
tenant_was_created.send(tenant)
|
||||
|
||||
@ -126,7 +126,7 @@ class LoginApi(Resource):
|
||||
invitation_data: InvitationDetailDict | None = None
|
||||
if invite_token:
|
||||
invitation_data = RegisterService.get_invitation_with_case_fallback(
|
||||
None, request_email, invite_token, session=db.session
|
||||
None, request_email, invite_token, session=db.session()
|
||||
)
|
||||
if invitation_data is None:
|
||||
invite_token = None
|
||||
@ -153,7 +153,7 @@ class LoginApi(Resource):
|
||||
_log_console_login_failure(email=normalized_email, reason=LoginFailureReason.INVALID_CREDENTIALS)
|
||||
raise AuthenticationFailedError() from exc
|
||||
# SELF_HOSTED only have one workspace
|
||||
tenants = TenantService.get_join_tenants(account, session=db.session)
|
||||
tenants = TenantService.get_join_tenants(account, session=db.session())
|
||||
if len(tenants) == 0:
|
||||
system_features = FeatureService.get_system_features()
|
||||
|
||||
@ -165,7 +165,7 @@ class LoginApi(Resource):
|
||||
data="workspace not found, please contact system admin to invite you to join in a workspace",
|
||||
).model_dump(mode="json")
|
||||
|
||||
token_pair = AccountService.login(account=account, session=db.session, ip_address=extract_remote_ip(request))
|
||||
token_pair = AccountService.login(account=account, session=db.session(), ip_address=extract_remote_ip(request))
|
||||
AccountService.reset_login_error_rate_limit(normalized_email)
|
||||
|
||||
# Create response with cookies instead of returning tokens in body
|
||||
@ -301,7 +301,7 @@ class EmailCodeLoginApi(Resource):
|
||||
_log_console_login_failure(email=user_email, reason=LoginFailureReason.ACCOUNT_IN_FREEZE)
|
||||
raise AccountInFreezeError()
|
||||
if account:
|
||||
tenants = TenantService.get_join_tenants(account, session=db.session)
|
||||
tenants = TenantService.get_join_tenants(account, session=db.session())
|
||||
if not tenants:
|
||||
workspaces = FeatureService.get_system_features().license.workspaces
|
||||
if not workspaces.is_available():
|
||||
@ -309,8 +309,8 @@ class EmailCodeLoginApi(Resource):
|
||||
if not FeatureService.get_system_features().is_allow_create_workspace:
|
||||
raise NotAllowedCreateWorkspace()
|
||||
else:
|
||||
new_tenant = TenantService.create_tenant(f"{account.name}'s Workspace", session=db.session)
|
||||
TenantService.create_tenant_member(new_tenant, account, db.session, role="owner")
|
||||
new_tenant = TenantService.create_tenant(f"{account.name}'s Workspace", session=db.session())
|
||||
TenantService.create_tenant_member(new_tenant, account, db.session(), role="owner")
|
||||
account.current_tenant = new_tenant
|
||||
tenant_was_created.send(new_tenant)
|
||||
|
||||
@ -321,7 +321,7 @@ class EmailCodeLoginApi(Resource):
|
||||
name=user_email,
|
||||
interface_language=get_valid_language(language),
|
||||
timezone=args.timezone,
|
||||
session=db.session,
|
||||
session=db.session(),
|
||||
)
|
||||
except WorkSpaceNotAllowedCreateError:
|
||||
raise NotAllowedCreateWorkspace()
|
||||
@ -330,7 +330,7 @@ class EmailCodeLoginApi(Resource):
|
||||
raise AccountInFreezeError()
|
||||
except WorkspacesLimitExceededError:
|
||||
raise WorkspacesLimitExceeded()
|
||||
token_pair = AccountService.login(account, session=db.session, ip_address=extract_remote_ip(request))
|
||||
token_pair = AccountService.login(account, session=db.session(), ip_address=extract_remote_ip(request))
|
||||
AccountService.reset_login_error_rate_limit(user_email)
|
||||
|
||||
# Create response with cookies instead of returning tokens in body
|
||||
@ -358,7 +358,7 @@ class RefreshTokenApi(Resource):
|
||||
), 401
|
||||
|
||||
try:
|
||||
new_token_pair = AccountService.refresh_token(refresh_token, session=db.session)
|
||||
new_token_pair = AccountService.refresh_token(refresh_token, session=db.session())
|
||||
except Unauthorized as exc:
|
||||
return SimpleResultMessageResponse(result="fail", message=exc.description or "Unauthorized.").model_dump(
|
||||
mode="json"
|
||||
@ -378,22 +378,22 @@ class RefreshTokenApi(Resource):
|
||||
|
||||
|
||||
def _get_account_with_case_fallback(email: str):
|
||||
account = AccountService.get_user_through_email(email, session=db.session)
|
||||
account = AccountService.get_user_through_email(email, session=db.session())
|
||||
if account or email == email.lower():
|
||||
return account
|
||||
|
||||
return AccountService.get_user_through_email(email.lower(), session=db.session)
|
||||
return AccountService.get_user_through_email(email.lower(), session=db.session())
|
||||
|
||||
|
||||
def _authenticate_account_with_case_fallback(
|
||||
original_email: str, normalized_email: str, password: str, invite_token: str | None
|
||||
):
|
||||
try:
|
||||
return AccountService.authenticate(original_email, password, invite_token, session=db.session)
|
||||
return AccountService.authenticate(original_email, password, invite_token, session=db.session())
|
||||
except services.errors.account.AccountPasswordError:
|
||||
if original_email == normalized_email:
|
||||
raise
|
||||
return AccountService.authenticate(normalized_email, password, invite_token, session=db.session)
|
||||
return AccountService.authenticate(normalized_email, password, invite_token, session=db.session())
|
||||
|
||||
|
||||
def _log_console_login_failure(*, email: str, reason: LoginFailureReason) -> None:
|
||||
|
||||
@ -195,7 +195,7 @@ class OAuthCallback(Resource):
|
||||
db.session.commit()
|
||||
|
||||
try:
|
||||
TenantService.create_owner_tenant_if_not_exist(account, session=db.session)
|
||||
TenantService.create_owner_tenant_if_not_exist(account, session=db.session())
|
||||
except Unauthorized:
|
||||
return redirect(f"{dify_config.CONSOLE_WEB_URL}/signin?message=Workspace not found.")
|
||||
except WorkSpaceNotAllowedCreateError:
|
||||
@ -206,7 +206,7 @@ class OAuthCallback(Resource):
|
||||
|
||||
token_pair = AccountService.login(
|
||||
account=account,
|
||||
session=db.session,
|
||||
session=db.session(),
|
||||
ip_address=extract_remote_ip(request),
|
||||
)
|
||||
|
||||
@ -225,7 +225,7 @@ def _get_account_by_openid_or_email(provider: str, user_info: OAuthUserInfo) ->
|
||||
account: Account | None = Account.get_by_openid(provider, user_info.id)
|
||||
|
||||
if not account:
|
||||
account = AccountService.get_account_by_email_with_case_fallback(db.session, user_info.email)
|
||||
account = AccountService.get_account_by_email_with_case_fallback(user_info.email, session=db.session())
|
||||
|
||||
return account
|
||||
|
||||
@ -241,13 +241,13 @@ def _generate_account(
|
||||
oauth_new_user = False
|
||||
|
||||
if account:
|
||||
tenants = TenantService.get_join_tenants(account, session=db.session)
|
||||
tenants = TenantService.get_join_tenants(account, session=db.session())
|
||||
if not tenants:
|
||||
if not FeatureService.get_system_features().is_allow_create_workspace:
|
||||
raise WorkSpaceNotAllowedCreateError()
|
||||
else:
|
||||
new_tenant = TenantService.create_tenant(f"{account.name}'s Workspace", session=db.session)
|
||||
TenantService.create_tenant_member(new_tenant, account, db.session, role="owner")
|
||||
new_tenant = TenantService.create_tenant(f"{account.name}'s Workspace", session=db.session())
|
||||
TenantService.create_tenant_member(new_tenant, account, db.session(), role="owner")
|
||||
account.current_tenant = new_tenant
|
||||
tenant_was_created.send(new_tenant)
|
||||
|
||||
@ -273,10 +273,10 @@ def _generate_account(
|
||||
provider=provider,
|
||||
language=interface_language,
|
||||
timezone=timezone,
|
||||
session=db.session,
|
||||
session=db.session(),
|
||||
)
|
||||
|
||||
# Link account
|
||||
AccountService.link_account_integrate(provider, user_info.id, account, session=db.session)
|
||||
AccountService.link_account_integrate(provider, user_info.id, account, session=db.session())
|
||||
|
||||
return account, oauth_new_user
|
||||
|
||||
@ -10,6 +10,7 @@ from werkzeug.exceptions import BadRequest, NotFound
|
||||
|
||||
from controllers.common.schema import register_response_schema_models, register_schema_models
|
||||
from controllers.console.wraps import account_initialization_required, setup_required, with_current_user
|
||||
from extensions.ext_database import db
|
||||
from graphon.model_runtime.utils.encoders import jsonable_encoder
|
||||
from libs.login import login_required
|
||||
from models import Account
|
||||
@ -131,7 +132,9 @@ def oauth_server_access_token_required[T, **P, R](
|
||||
response.headers["WWW-Authenticate"] = "Bearer"
|
||||
return response
|
||||
|
||||
account = OAuthServerService.validate_oauth_access_token(oauth_provider_app.client_id, access_token)
|
||||
account = OAuthServerService.validate_oauth_access_token(
|
||||
oauth_provider_app.client_id, access_token, db.session()
|
||||
)
|
||||
if not account:
|
||||
response = jsonify({"error": "access_token or client_id is invalid"})
|
||||
response.status_code = 401
|
||||
|
||||
@ -56,7 +56,7 @@ class Subscription(Resource):
|
||||
@with_current_tenant_id
|
||||
def get(self, current_tenant_id: str, current_user: Account):
|
||||
args = SubscriptionQuery.model_validate(request.args.to_dict(flat=True))
|
||||
BillingService.is_tenant_owner_or_admin(db.session, current_user)
|
||||
BillingService.is_tenant_owner_or_admin(current_user, session=db.session())
|
||||
return BillingService.get_subscription(args.plan, args.interval, current_user.email, current_tenant_id)
|
||||
|
||||
|
||||
@ -70,7 +70,7 @@ class Invoices(Resource):
|
||||
@with_current_user
|
||||
@with_current_tenant_id
|
||||
def get(self, current_tenant_id: str, current_user: Account):
|
||||
BillingService.is_tenant_owner_or_admin(db.session, current_user)
|
||||
BillingService.is_tenant_owner_or_admin(current_user, session=db.session())
|
||||
return BillingService.get_invoices(current_user.email, current_tenant_id)
|
||||
|
||||
|
||||
|
||||
@ -245,7 +245,7 @@ class DataSourceNotionListApi(Resource):
|
||||
exist_page_ids = []
|
||||
# import notion in the exist dataset
|
||||
if query.dataset_id:
|
||||
dataset = DatasetService.get_dataset(query.dataset_id, db.session)
|
||||
dataset = DatasetService.get_dataset(query.dataset_id, db.session())
|
||||
if not dataset:
|
||||
raise NotFound("Dataset not found.")
|
||||
if dataset.data_source_type != "notion_import":
|
||||
@ -400,11 +400,11 @@ class DataSourceNotionDatasetSyncApi(Resource):
|
||||
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_CREATE_AND_MANAGEMENT)
|
||||
def get(self, dataset_id: UUID) -> tuple[dict[str, str], int]:
|
||||
dataset_id_str = str(dataset_id)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session())
|
||||
if dataset is None:
|
||||
raise NotFound("Dataset not found.")
|
||||
|
||||
documents = DocumentService.get_document_by_dataset_id(dataset_id_str, db.session)
|
||||
documents = DocumentService.get_document_by_dataset_id(dataset_id_str, db.session())
|
||||
for document in documents:
|
||||
document_indexing_sync_task.delay(dataset_id_str, document.id)
|
||||
return {"result": "success"}, 200
|
||||
@ -420,11 +420,11 @@ class DataSourceNotionDocumentSyncApi(Resource):
|
||||
def get(self, dataset_id: UUID, document_id: UUID) -> tuple[dict[str, str], int]:
|
||||
dataset_id_str = str(dataset_id)
|
||||
document_id_str = str(document_id)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session())
|
||||
if dataset is None:
|
||||
raise NotFound("Dataset not found.")
|
||||
|
||||
document = DocumentService.get_document(dataset_id_str, document_id_str, session=db.session)
|
||||
document = DocumentService.get_document(dataset_id_str, document_id_str, session=db.session())
|
||||
if document is None:
|
||||
raise NotFound("Document not found.")
|
||||
document_indexing_sync_task.delay(dataset_id_str, document_id_str)
|
||||
|
||||
@ -418,6 +418,7 @@ class DatasetListApi(Resource):
|
||||
permissions = enterprise_rbac_service.RBACService.MyPermissions.get(
|
||||
str(current_tenant_id),
|
||||
current_user.id,
|
||||
session=db.session(),
|
||||
)
|
||||
|
||||
accessible_dataset_ids: list[str] | None = None
|
||||
@ -461,7 +462,7 @@ class DatasetListApi(Resource):
|
||||
datasets, total = DatasetService.get_datasets(
|
||||
query.page,
|
||||
query.limit,
|
||||
db.session,
|
||||
db.session(),
|
||||
current_tenant_id,
|
||||
current_user,
|
||||
query.keyword,
|
||||
@ -573,6 +574,7 @@ class DatasetListApi(Resource):
|
||||
current_tenant_id,
|
||||
current_user.id,
|
||||
[dataset.id],
|
||||
session=session,
|
||||
)
|
||||
|
||||
item = DatasetDetailWithPartialMembersResponse.model_validate(dataset, from_attributes=True).model_dump(
|
||||
@ -602,17 +604,18 @@ class DatasetApi(Resource):
|
||||
@with_current_tenant_id
|
||||
def get(self, current_tenant_id: str, current_user: Account, dataset_id: UUID):
|
||||
dataset_id_str = str(dataset_id)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session())
|
||||
if dataset is None:
|
||||
raise NotFound("Dataset not found.")
|
||||
try:
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session)
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session())
|
||||
except services.errors.account.NoPermissionError as e:
|
||||
raise Forbidden(str(e))
|
||||
permissions = enterprise_rbac_service.RBACService.MyPermissions.get(
|
||||
current_tenant_id,
|
||||
current_user.id,
|
||||
dataset_id=dataset_id_str,
|
||||
session=db.session(),
|
||||
)
|
||||
permission_keys_map = permissions.dataset.permission_keys_by_resource_ids([dataset_id_str])
|
||||
data = dump_response(DatasetDetailResponse, dataset)
|
||||
@ -622,7 +625,7 @@ class DatasetApi(Resource):
|
||||
provider_id = ModelProviderID(dataset.embedding_model_provider)
|
||||
data["embedding_model_provider"] = str(provider_id)
|
||||
if data.get("permission") == "partial_members":
|
||||
part_users_list = DatasetPermissionService.get_dataset_partial_member_list(dataset_id_str, db.session)
|
||||
part_users_list = DatasetPermissionService.get_dataset_partial_member_list(dataset_id_str, db.session())
|
||||
data.update({"partial_member_list": part_users_list})
|
||||
|
||||
# check embedding setting
|
||||
@ -666,7 +669,7 @@ class DatasetApi(Resource):
|
||||
@with_session
|
||||
def patch(self, session: Session, current_tenant_id: str, current_user: Account, dataset_id: UUID):
|
||||
dataset_id_str = str(dataset_id)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session())
|
||||
if dataset is None:
|
||||
raise NotFound("Dataset not found.")
|
||||
|
||||
@ -685,10 +688,10 @@ class DatasetApi(Resource):
|
||||
# The role of the current user in the ta table must be admin, owner, editor, or dataset_operator
|
||||
if not dify_config.RBAC_ENABLED:
|
||||
DatasetPermissionService.check_permission(
|
||||
session, current_user, dataset, payload.permission, payload.partial_member_list
|
||||
current_user, dataset, payload.permission, payload.partial_member_list, session=session
|
||||
)
|
||||
|
||||
dataset = DatasetService.update_dataset(session, dataset_id_str, payload_data, current_user)
|
||||
dataset = DatasetService.update_dataset(dataset_id_str, payload_data, current_user, session=session)
|
||||
|
||||
if dataset is None:
|
||||
raise NotFound("Dataset not found.")
|
||||
@ -697,6 +700,7 @@ class DatasetApi(Resource):
|
||||
current_tenant_id,
|
||||
current_user.id,
|
||||
[dataset_id_str],
|
||||
session=session,
|
||||
)
|
||||
result_data = dump_response(DatasetDetailResponse, dataset)
|
||||
result_data["permission_keys"] = permission_keys_map.get(dataset_id_str, [])
|
||||
@ -704,13 +708,13 @@ class DatasetApi(Resource):
|
||||
|
||||
if payload.partial_member_list is not None and payload.permission == DatasetPermissionEnum.PARTIAL_TEAM:
|
||||
DatasetPermissionService.update_partial_member_list(
|
||||
tenant_id, dataset_id_str, payload.partial_member_list, db.session
|
||||
tenant_id, dataset_id_str, payload.partial_member_list, db.session()
|
||||
)
|
||||
# clear partial member list when permission is only_me or all_team_members
|
||||
elif payload.permission in {DatasetPermissionEnum.ONLY_ME, DatasetPermissionEnum.ALL_TEAM}:
|
||||
DatasetPermissionService.clear_partial_member_list(dataset_id_str, db.session)
|
||||
DatasetPermissionService.clear_partial_member_list(dataset_id_str, db.session())
|
||||
|
||||
partial_member_list = DatasetPermissionService.get_dataset_partial_member_list(dataset_id_str, db.session)
|
||||
partial_member_list = DatasetPermissionService.get_dataset_partial_member_list(dataset_id_str, db.session())
|
||||
result_data.update({"partial_member_list": partial_member_list})
|
||||
|
||||
return result_data, 200
|
||||
@ -729,8 +733,8 @@ class DatasetApi(Resource):
|
||||
raise Forbidden()
|
||||
|
||||
try:
|
||||
if DatasetService.delete_dataset(dataset_id_str, current_user, db.session):
|
||||
DatasetPermissionService.clear_partial_member_list(dataset_id_str, db.session)
|
||||
if DatasetService.delete_dataset(dataset_id_str, current_user, db.session()):
|
||||
DatasetPermissionService.clear_partial_member_list(dataset_id_str, db.session())
|
||||
return "", 204
|
||||
else:
|
||||
raise NotFound("Dataset not found.")
|
||||
@ -755,7 +759,7 @@ class DatasetUseCheckApi(Resource):
|
||||
def get(self, dataset_id: UUID):
|
||||
dataset_id_str = str(dataset_id)
|
||||
|
||||
dataset_is_using = DatasetService.dataset_use_check(dataset_id_str, db.session)
|
||||
dataset_is_using = DatasetService.dataset_use_check(dataset_id_str, db.session())
|
||||
return {"is_using": dataset_is_using}, 200
|
||||
|
||||
|
||||
@ -776,12 +780,12 @@ class DatasetQueryApi(Resource):
|
||||
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_READONLY)
|
||||
def get(self, current_user: Account, dataset_id: UUID):
|
||||
dataset_id_str = str(dataset_id)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session())
|
||||
if dataset is None:
|
||||
raise NotFound("Dataset not found.")
|
||||
|
||||
try:
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session)
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session())
|
||||
except services.errors.account.NoPermissionError as e:
|
||||
raise Forbidden(str(e))
|
||||
|
||||
@ -917,16 +921,16 @@ class DatasetRelatedAppListApi(Resource):
|
||||
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_READONLY)
|
||||
def get(self, current_user: Account, dataset_id: UUID):
|
||||
dataset_id_str = str(dataset_id)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session())
|
||||
if dataset is None:
|
||||
raise NotFound("Dataset not found.")
|
||||
|
||||
try:
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session)
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session())
|
||||
except services.errors.account.NoPermissionError as e:
|
||||
raise Forbidden(str(e))
|
||||
|
||||
app_dataset_joins = DatasetService.get_related_apps(dataset.id, db.session)
|
||||
app_dataset_joins = DatasetService.get_related_apps(dataset.id, db.session())
|
||||
|
||||
related_apps = []
|
||||
for app_dataset_join in app_dataset_joins:
|
||||
@ -1101,7 +1105,7 @@ class DatasetEnableApiApi(Resource):
|
||||
def post(self, dataset_id: UUID, status: str):
|
||||
dataset_id_str = str(dataset_id)
|
||||
|
||||
DatasetService.update_dataset_api_status(dataset_id_str, status == "enable", db.session)
|
||||
DatasetService.update_dataset_api_status(dataset_id_str, status == "enable", db.session())
|
||||
|
||||
return {"result": "success"}, 200
|
||||
|
||||
@ -1170,10 +1174,10 @@ class DatasetErrorDocs(Resource):
|
||||
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_READONLY)
|
||||
def get(self, dataset_id: UUID):
|
||||
dataset_id_str = str(dataset_id)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session())
|
||||
if dataset is None:
|
||||
raise NotFound("Dataset not found.")
|
||||
results = DocumentService.get_error_documents_by_dataset_id(dataset_id_str, db.session)
|
||||
results = DocumentService.get_error_documents_by_dataset_id(dataset_id_str, db.session())
|
||||
|
||||
return dump_response(ErrorDocsResponse, {"data": results, "total": len(results)}), 200
|
||||
|
||||
@ -1197,15 +1201,15 @@ class DatasetPermissionUserListApi(Resource):
|
||||
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_READONLY)
|
||||
def get(self, current_user: Account, dataset_id: UUID):
|
||||
dataset_id_str = str(dataset_id)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session())
|
||||
if dataset is None:
|
||||
raise NotFound("Dataset not found.")
|
||||
try:
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session)
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session())
|
||||
except services.errors.account.NoPermissionError as e:
|
||||
raise Forbidden(str(e))
|
||||
|
||||
partial_members_list = DatasetPermissionService.get_dataset_partial_member_list(dataset_id_str, db.session)
|
||||
partial_members_list = DatasetPermissionService.get_dataset_partial_member_list(dataset_id_str, db.session())
|
||||
|
||||
return dump_response(PartialMemberListResponse, {"data": partial_members_list}), 200
|
||||
|
||||
@ -1227,8 +1231,8 @@ class DatasetAutoDisableLogApi(Resource):
|
||||
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_READONLY)
|
||||
def get(self, dataset_id: UUID):
|
||||
dataset_id_str = str(dataset_id)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session())
|
||||
if dataset is None:
|
||||
raise NotFound("Dataset not found.")
|
||||
auto_disable_logs = DatasetService.get_dataset_auto_disable_logs(dataset_id_str, db.session)
|
||||
auto_disable_logs = DatasetService.get_dataset_auto_disable_logs(dataset_id_str, db.session())
|
||||
return dump_response(AutoDisableLogsResponse, auto_disable_logs), 200
|
||||
|
||||
@ -183,16 +183,16 @@ class DocumentResource(Resource):
|
||||
def get_document(
|
||||
self, dataset_id: str, document_id: str, current_user: Account, current_tenant_id: str
|
||||
) -> Document:
|
||||
dataset = DatasetService.get_dataset(dataset_id, db.session)
|
||||
dataset = DatasetService.get_dataset(dataset_id, db.session())
|
||||
if not dataset:
|
||||
raise NotFound("Dataset not found.")
|
||||
|
||||
try:
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session)
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session())
|
||||
except services.errors.account.NoPermissionError as e:
|
||||
raise Forbidden(str(e))
|
||||
|
||||
document = DocumentService.get_document(dataset_id, document_id, session=db.session)
|
||||
document = DocumentService.get_document(dataset_id, document_id, session=db.session())
|
||||
|
||||
if not document:
|
||||
raise NotFound("Document not found.")
|
||||
@ -203,16 +203,16 @@ class DocumentResource(Resource):
|
||||
return document
|
||||
|
||||
def get_batch_documents(self, dataset_id: str, batch: str, current_user: Account) -> Sequence[Document]:
|
||||
dataset = DatasetService.get_dataset(dataset_id, db.session)
|
||||
dataset = DatasetService.get_dataset(dataset_id, db.session())
|
||||
if not dataset:
|
||||
raise NotFound("Dataset not found.")
|
||||
|
||||
try:
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session)
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session())
|
||||
except services.errors.account.NoPermissionError as e:
|
||||
raise Forbidden(str(e))
|
||||
|
||||
documents = DocumentService.get_batch_documents(dataset_id, batch, db.session)
|
||||
documents = DocumentService.get_batch_documents(dataset_id, batch, db.session())
|
||||
|
||||
if not documents:
|
||||
raise NotFound("Documents not found.")
|
||||
@ -243,13 +243,13 @@ class GetProcessRuleApi(Resource):
|
||||
# get the latest process rule
|
||||
document = db.get_or_404(Document, document_id)
|
||||
|
||||
dataset = DatasetService.get_dataset(document.dataset_id, db.session)
|
||||
dataset = DatasetService.get_dataset(document.dataset_id, db.session())
|
||||
|
||||
if not dataset:
|
||||
raise NotFound("Dataset not found.")
|
||||
|
||||
try:
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session)
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session())
|
||||
except services.errors.account.NoPermissionError as e:
|
||||
raise Forbidden(str(e))
|
||||
|
||||
@ -319,12 +319,12 @@ class DatasetDocumentListApi(Resource):
|
||||
)
|
||||
except (ArgumentTypeError, ValueError, Exception):
|
||||
fetch = False
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session())
|
||||
if not dataset:
|
||||
raise NotFound("Dataset not found.")
|
||||
|
||||
try:
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session)
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session())
|
||||
except services.errors.account.NoPermissionError as e:
|
||||
raise Forbidden(str(e))
|
||||
|
||||
@ -376,6 +376,7 @@ class DatasetDocumentListApi(Resource):
|
||||
documents=documents,
|
||||
dataset=dataset,
|
||||
tenant_id=current_tenant_id,
|
||||
session=db.session(),
|
||||
)
|
||||
|
||||
if fetch:
|
||||
@ -423,7 +424,7 @@ class DatasetDocumentListApi(Resource):
|
||||
def post(self, current_user: Account, dataset_id: UUID):
|
||||
dataset_id_str = str(dataset_id)
|
||||
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session())
|
||||
|
||||
if not dataset:
|
||||
raise NotFound("Dataset not found.")
|
||||
@ -433,7 +434,7 @@ class DatasetDocumentListApi(Resource):
|
||||
raise Forbidden()
|
||||
|
||||
try:
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session)
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session())
|
||||
except services.errors.account.NoPermissionError as e:
|
||||
raise Forbidden(str(e))
|
||||
|
||||
@ -447,9 +448,9 @@ class DatasetDocumentListApi(Resource):
|
||||
|
||||
try:
|
||||
documents, batch = DocumentService.save_document_with_dataset_id(
|
||||
dataset, knowledge_config, current_user, session=db.session
|
||||
dataset, knowledge_config, current_user, session=db.session()
|
||||
)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session())
|
||||
|
||||
except ProviderTokenNotInitError as ex:
|
||||
raise ProviderNotInitializeError(ex.description)
|
||||
@ -468,7 +469,7 @@ class DatasetDocumentListApi(Resource):
|
||||
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
|
||||
def delete(self, dataset_id: UUID):
|
||||
dataset_id_str = str(dataset_id)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session())
|
||||
if dataset is None:
|
||||
raise NotFound("Dataset not found.")
|
||||
# check user's model setting
|
||||
@ -477,7 +478,7 @@ class DatasetDocumentListApi(Resource):
|
||||
try:
|
||||
document_ids = request.args.getlist("document_id")
|
||||
dataset_ref = DatasetRefService.create_dataset_ref(dataset)
|
||||
DocumentService.delete_documents(dataset_ref, document_ids, dataset.doc_form, db.session)
|
||||
DocumentService.delete_documents(dataset_ref, document_ids, dataset.doc_form, db.session())
|
||||
except services.errors.document.DocumentIndexingError:
|
||||
raise DocumentIndexingError("Cannot delete document during indexing.")
|
||||
|
||||
@ -536,7 +537,7 @@ class DatasetInitApi(Resource):
|
||||
tenant_id=current_tenant_id,
|
||||
knowledge_config=knowledge_config,
|
||||
account=current_user,
|
||||
session=db.session,
|
||||
session=db.session(),
|
||||
)
|
||||
except ProviderTokenNotInitError as ex:
|
||||
raise ProviderNotInitializeError(ex.description)
|
||||
@ -873,7 +874,7 @@ class DocumentApi(DocumentResource):
|
||||
if metadata == "only":
|
||||
response = {"id": document.id, "doc_type": document.doc_type, "doc_metadata": document.doc_metadata_details}
|
||||
elif metadata == "without":
|
||||
dataset_process_rules = DatasetService.get_process_rules(dataset_id_str, db.session)
|
||||
dataset_process_rules = DatasetService.get_process_rules(dataset_id_str, db.session())
|
||||
document_process_rules = document.dataset_process_rule.to_dict() if document.dataset_process_rule else {}
|
||||
response = {
|
||||
"id": document.id,
|
||||
@ -907,7 +908,7 @@ class DocumentApi(DocumentResource):
|
||||
"need_summary": document.need_summary if document.need_summary is not None else False,
|
||||
}
|
||||
else:
|
||||
dataset_process_rules = DatasetService.get_process_rules(dataset_id_str, db.session)
|
||||
dataset_process_rules = DatasetService.get_process_rules(dataset_id_str, db.session())
|
||||
document_process_rules = document.dataset_process_rule.to_dict() if document.dataset_process_rule else {}
|
||||
response = {
|
||||
"id": document.id,
|
||||
@ -956,7 +957,7 @@ class DocumentApi(DocumentResource):
|
||||
def delete(self, current_tenant_id: str, current_user: Account, dataset_id: UUID, document_id: UUID):
|
||||
dataset_id_str = str(dataset_id)
|
||||
document_id_str = str(document_id)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session())
|
||||
if dataset is None:
|
||||
raise NotFound("Dataset not found.")
|
||||
# check user's model setting
|
||||
@ -965,7 +966,7 @@ class DocumentApi(DocumentResource):
|
||||
document = self.get_document(dataset_id_str, document_id_str, current_user, current_tenant_id)
|
||||
|
||||
try:
|
||||
DocumentService.delete_document(document, db.session)
|
||||
DocumentService.delete_document(document, db.session())
|
||||
except services.errors.document.DocumentIndexingError:
|
||||
raise DocumentIndexingError("Cannot delete document during indexing.")
|
||||
|
||||
@ -989,7 +990,7 @@ class DocumentDownloadApi(DocumentResource):
|
||||
def get(self, current_tenant_id: str, current_user: Account, dataset_id: UUID, document_id: UUID) -> dict[str, Any]:
|
||||
# Reuse the shared permission/tenant checks implemented in DocumentResource.
|
||||
document = self.get_document(str(dataset_id), str(document_id), current_user, current_tenant_id)
|
||||
return {"url": DocumentService.get_document_download_url(document, db.session)}
|
||||
return {"url": DocumentService.get_document_download_url(document, db.session())}
|
||||
|
||||
|
||||
@console_ns.route("/datasets/<uuid:dataset_id>/documents/download-zip")
|
||||
@ -1019,7 +1020,7 @@ class DocumentBatchDownloadZipApi(DocumentResource):
|
||||
document_ids=document_ids,
|
||||
tenant_id=current_tenant_id,
|
||||
current_user=current_user,
|
||||
session=db.session,
|
||||
session=db.session(),
|
||||
)
|
||||
|
||||
# Delegate ZIP packing to FileService, but keep Flask response+cleanup in the route.
|
||||
@ -1168,7 +1169,7 @@ class DocumentStatusApi(DocumentResource):
|
||||
self, current_user: Account, dataset_id: UUID, action: Literal["enable", "disable", "archive", "un_archive"]
|
||||
):
|
||||
dataset_id_str = str(dataset_id)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session())
|
||||
if dataset is None:
|
||||
raise NotFound("Dataset not found.")
|
||||
|
||||
@ -1180,12 +1181,12 @@ class DocumentStatusApi(DocumentResource):
|
||||
DatasetService.check_dataset_model_setting(dataset)
|
||||
|
||||
# check user's permission
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session)
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session())
|
||||
|
||||
document_ids = request.args.getlist("document_id")
|
||||
|
||||
try:
|
||||
DocumentService.batch_update_document_status(dataset, document_ids, action, current_user, db.session)
|
||||
DocumentService.batch_update_document_status(dataset, document_ids, action, current_user, db.session())
|
||||
except services.errors.document.DocumentIndexingError as e:
|
||||
raise InvalidActionError(str(e))
|
||||
except ValueError as e:
|
||||
@ -1209,11 +1210,11 @@ class DocumentPauseApi(DocumentResource):
|
||||
dataset_id_str = str(dataset_id)
|
||||
document_id_str = str(document_id)
|
||||
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session())
|
||||
if not dataset:
|
||||
raise NotFound("Dataset not found.")
|
||||
|
||||
document = DocumentService.get_document(dataset.id, document_id_str, session=db.session)
|
||||
document = DocumentService.get_document(dataset.id, document_id_str, session=db.session())
|
||||
|
||||
# 404 if document not found
|
||||
if document is None:
|
||||
@ -1225,7 +1226,7 @@ class DocumentPauseApi(DocumentResource):
|
||||
|
||||
try:
|
||||
# pause document
|
||||
DocumentService.pause_document(document, db.session)
|
||||
DocumentService.pause_document(document, db.session())
|
||||
except services.errors.document.DocumentIndexingError:
|
||||
raise DocumentIndexingError("Cannot pause completed document.")
|
||||
|
||||
@ -1244,10 +1245,10 @@ class DocumentRecoverApi(DocumentResource):
|
||||
"""recover document."""
|
||||
dataset_id_str = str(dataset_id)
|
||||
document_id_str = str(document_id)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session())
|
||||
if not dataset:
|
||||
raise NotFound("Dataset not found.")
|
||||
document = DocumentService.get_document(dataset.id, document_id_str, session=db.session)
|
||||
document = DocumentService.get_document(dataset.id, document_id_str, session=db.session())
|
||||
|
||||
# 404 if document not found
|
||||
if document is None:
|
||||
@ -1258,7 +1259,7 @@ class DocumentRecoverApi(DocumentResource):
|
||||
raise ArchivedDocumentImmutableError()
|
||||
try:
|
||||
# pause document
|
||||
DocumentService.recover_document(document, db.session)
|
||||
DocumentService.recover_document(document, db.session())
|
||||
except services.errors.document.DocumentIndexingError:
|
||||
raise DocumentIndexingError("Document is not in paused status.")
|
||||
|
||||
@ -1278,13 +1279,13 @@ class DocumentRetryApi(DocumentResource):
|
||||
"""retry document."""
|
||||
payload = DocumentRetryPayload.model_validate(console_ns.payload or {})
|
||||
dataset_id_str = str(dataset_id)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session())
|
||||
retry_documents = []
|
||||
if not dataset:
|
||||
raise NotFound("Dataset not found.")
|
||||
for document_id in payload.document_ids:
|
||||
try:
|
||||
document = DocumentService.get_document(dataset.id, document_id, session=db.session)
|
||||
document = DocumentService.get_document(dataset.id, document_id, session=db.session())
|
||||
|
||||
# 404 if document not found
|
||||
if document is None:
|
||||
@ -1302,7 +1303,7 @@ class DocumentRetryApi(DocumentResource):
|
||||
logger.exception("Failed to retry document, document id: %s", document_id)
|
||||
continue
|
||||
# retry document
|
||||
DocumentService.retry_document(dataset_id_str, retry_documents, db.session)
|
||||
DocumentService.retry_document(dataset_id_str, retry_documents, db.session())
|
||||
|
||||
return "", 204
|
||||
|
||||
@ -1320,14 +1321,14 @@ class DocumentRenameApi(DocumentResource):
|
||||
# The role of the current user in the ta table must be admin, owner, editor, or dataset_operator
|
||||
if not current_user.is_dataset_editor:
|
||||
raise Forbidden()
|
||||
dataset = DatasetService.get_dataset(dataset_id, db.session)
|
||||
dataset = DatasetService.get_dataset(dataset_id, db.session())
|
||||
if not dataset:
|
||||
raise NotFound("Dataset not found.")
|
||||
DatasetService.check_dataset_operator_permission(current_user, dataset, session=db.session)
|
||||
DatasetService.check_dataset_operator_permission(current_user, dataset, session=db.session())
|
||||
payload = DocumentRenamePayload.model_validate(console_ns.payload or {})
|
||||
|
||||
try:
|
||||
document = DocumentService.rename_document(str(dataset_id), str(document_id), payload.name, db.session)
|
||||
document = DocumentService.rename_document(str(dataset_id), str(document_id), payload.name, db.session())
|
||||
except services.errors.document.DocumentIndexingError:
|
||||
raise DocumentIndexingError("Cannot delete document during indexing.")
|
||||
|
||||
@ -1345,11 +1346,11 @@ class WebsiteDocumentSyncApi(DocumentResource):
|
||||
def get(self, current_tenant_id: str, dataset_id: UUID, document_id: UUID):
|
||||
"""sync website document."""
|
||||
dataset_id_str = str(dataset_id)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session())
|
||||
if not dataset:
|
||||
raise NotFound("Dataset not found.")
|
||||
document_id_str = str(document_id)
|
||||
document = DocumentService.get_document(dataset.id, document_id_str, session=db.session)
|
||||
document = DocumentService.get_document(dataset.id, document_id_str, session=db.session())
|
||||
if not document:
|
||||
raise NotFound("Document not found.")
|
||||
if document.tenant_id != current_tenant_id:
|
||||
@ -1360,7 +1361,7 @@ class WebsiteDocumentSyncApi(DocumentResource):
|
||||
if DocumentService.check_archived(document):
|
||||
raise ArchivedDocumentImmutableError()
|
||||
# sync document
|
||||
DocumentService.sync_website_document(dataset_id_str, document, db.session)
|
||||
DocumentService.sync_website_document(dataset_id_str, document, db.session())
|
||||
|
||||
return {"result": "success"}, 200
|
||||
|
||||
@ -1380,10 +1381,10 @@ class DocumentPipelineExecutionLogApi(DocumentResource):
|
||||
dataset_id_str = str(dataset_id)
|
||||
document_id_str = str(document_id)
|
||||
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session())
|
||||
if not dataset:
|
||||
raise NotFound("Dataset not found.")
|
||||
document = DocumentService.get_document(dataset.id, document_id_str, session=db.session)
|
||||
document = DocumentService.get_document(dataset.id, document_id_str, session=db.session())
|
||||
if not document:
|
||||
raise NotFound("Document not found.")
|
||||
log = db.session.scalar(
|
||||
@ -1438,7 +1439,7 @@ class DocumentGenerateSummaryApi(Resource):
|
||||
dataset_id_str = str(dataset_id)
|
||||
|
||||
# Get dataset
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session())
|
||||
if not dataset:
|
||||
raise NotFound("Dataset not found.")
|
||||
|
||||
@ -1447,7 +1448,7 @@ class DocumentGenerateSummaryApi(Resource):
|
||||
raise Forbidden()
|
||||
|
||||
try:
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session)
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session())
|
||||
except services.errors.account.NoPermissionError as e:
|
||||
raise Forbidden(str(e))
|
||||
|
||||
@ -1472,7 +1473,7 @@ class DocumentGenerateSummaryApi(Resource):
|
||||
raise ValueError("Summary index is not enabled for this dataset. Please enable it in the dataset settings.")
|
||||
|
||||
# Verify all documents exist and belong to the dataset
|
||||
documents = DocumentService.get_documents_by_ids(dataset_id_str, document_list, db.session)
|
||||
documents = DocumentService.get_documents_by_ids(dataset_id_str, document_list, db.session())
|
||||
|
||||
if len(documents) != len(document_list):
|
||||
found_ids = {doc.id for doc in documents}
|
||||
@ -1488,7 +1489,7 @@ class DocumentGenerateSummaryApi(Resource):
|
||||
DocumentService.update_documents_need_summary(
|
||||
dataset_id=dataset_id_str,
|
||||
document_ids=document_ids_to_update,
|
||||
session=db.session,
|
||||
session=db.session(),
|
||||
need_summary=True,
|
||||
)
|
||||
|
||||
@ -1539,13 +1540,13 @@ class DocumentSummaryStatusApi(DocumentResource):
|
||||
document_id_str = str(document_id)
|
||||
|
||||
# Get dataset
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session())
|
||||
if not dataset:
|
||||
raise NotFound("Dataset not found.")
|
||||
|
||||
# Check permissions
|
||||
try:
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session)
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session())
|
||||
except services.errors.account.NoPermissionError as e:
|
||||
raise Forbidden(str(e))
|
||||
|
||||
@ -1555,7 +1556,7 @@ class DocumentSummaryStatusApi(DocumentResource):
|
||||
result = SummaryIndexService.get_document_summary_status_detail(
|
||||
document_id=document_id_str,
|
||||
dataset_id=dataset_id_str,
|
||||
session=db.session,
|
||||
session=db.session(),
|
||||
)
|
||||
|
||||
return result, 200
|
||||
|
||||
@ -173,7 +173,7 @@ def _get_segment_for_document(
|
||||
raise NotFound("Document not found.")
|
||||
|
||||
segment_ref = DatasetRefService.create_segment_ref(document_ref, segment_id)
|
||||
segment = SegmentService.get_segment_by_ref(segment_ref)
|
||||
segment = SegmentService.get_segment_by_ref(segment_ref, db.session())
|
||||
if not segment:
|
||||
raise NotFound("Segment not found.")
|
||||
return segment_ref, segment
|
||||
@ -193,16 +193,16 @@ class DatasetDocumentSegmentListApi(Resource):
|
||||
def get(self, current_tenant_id: str, current_user: Account, dataset_id: UUID, document_id: UUID):
|
||||
dataset_id_str = str(dataset_id)
|
||||
document_id_str = str(document_id)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session())
|
||||
if not dataset:
|
||||
raise NotFound("Dataset not found.")
|
||||
|
||||
try:
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session)
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session())
|
||||
except services.errors.account.NoPermissionError as e:
|
||||
raise Forbidden(str(e))
|
||||
|
||||
document = DocumentService.get_document(dataset_id_str, document_id_str, session=db.session)
|
||||
document = DocumentService.get_document(dataset_id_str, document_id_str, session=db.session())
|
||||
|
||||
if not document:
|
||||
raise NotFound("Document not found.")
|
||||
@ -278,7 +278,7 @@ class DatasetDocumentSegmentListApi(Resource):
|
||||
summaries: dict[str, str | None] = {}
|
||||
if segment_ids:
|
||||
summary_records = SummaryIndexService.get_segments_summaries(
|
||||
segment_ids=segment_ids, dataset_id=dataset_id_str
|
||||
segment_ids=segment_ids, dataset_id=dataset_id_str, session=db.session()
|
||||
)
|
||||
summaries = {chunk_id: summary.summary_content for chunk_id, summary in summary_records.items()}
|
||||
|
||||
@ -303,14 +303,14 @@ class DatasetDocumentSegmentListApi(Resource):
|
||||
def delete(self, current_user: Account, dataset_id: UUID, document_id: UUID):
|
||||
# check dataset
|
||||
dataset_id_str = str(dataset_id)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session())
|
||||
if not dataset:
|
||||
raise NotFound("Dataset not found.")
|
||||
# check user's model setting
|
||||
DatasetService.check_dataset_model_setting(dataset)
|
||||
# check document
|
||||
document_id_str = str(document_id)
|
||||
document = DocumentService.get_document(dataset_id_str, document_id_str, session=db.session)
|
||||
document = DocumentService.get_document(dataset_id_str, document_id_str, session=db.session())
|
||||
if not document:
|
||||
raise NotFound("Document not found.")
|
||||
segment_ids = request.args.getlist("segment_id")
|
||||
@ -319,10 +319,10 @@ class DatasetDocumentSegmentListApi(Resource):
|
||||
if not current_user.is_dataset_editor:
|
||||
raise Forbidden()
|
||||
try:
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session)
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session())
|
||||
except services.errors.account.NoPermissionError as e:
|
||||
raise Forbidden(str(e))
|
||||
SegmentService.delete_segments(segment_ids, document, dataset, db.session)
|
||||
SegmentService.delete_segments(segment_ids, document, dataset, db.session())
|
||||
return "", 204
|
||||
|
||||
|
||||
@ -348,11 +348,11 @@ class DatasetDocumentSegmentApi(Resource):
|
||||
action: Literal["enable", "disable"],
|
||||
):
|
||||
dataset_id_str = str(dataset_id)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session())
|
||||
if not dataset:
|
||||
raise NotFound("Dataset not found.")
|
||||
document_id_str = str(document_id)
|
||||
document = DocumentService.get_document(dataset_id_str, document_id_str, session=db.session)
|
||||
document = DocumentService.get_document(dataset_id_str, document_id_str, session=db.session())
|
||||
if not document:
|
||||
raise NotFound("Document not found.")
|
||||
# check user's model setting
|
||||
@ -362,7 +362,7 @@ class DatasetDocumentSegmentApi(Resource):
|
||||
raise Forbidden()
|
||||
|
||||
try:
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session)
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session())
|
||||
except services.errors.account.NoPermissionError as e:
|
||||
raise Forbidden(str(e))
|
||||
if dataset.indexing_technique == IndexTechniqueType.HIGH_QUALITY:
|
||||
@ -388,7 +388,7 @@ class DatasetDocumentSegmentApi(Resource):
|
||||
if cache_result is not None:
|
||||
raise InvalidActionError("Document is being indexed, please try again later")
|
||||
try:
|
||||
SegmentService.update_segments_status(segment_ids, action, dataset, document, db.session)
|
||||
SegmentService.update_segments_status(segment_ids, action, dataset, document, db.session())
|
||||
except Exception as e:
|
||||
raise InvalidActionError(str(e))
|
||||
return dump_response(SimpleResultResponse, {"result": "success"}), 200
|
||||
@ -411,12 +411,12 @@ class DatasetDocumentSegmentAddApi(Resource):
|
||||
def post(self, current_tenant_id: str, current_user: Account, dataset_id: UUID, document_id: UUID):
|
||||
# check dataset
|
||||
dataset_id_str = str(dataset_id)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session())
|
||||
if not dataset:
|
||||
raise NotFound("Dataset not found.")
|
||||
# check document
|
||||
document_id_str = str(document_id)
|
||||
document = DocumentService.get_document(dataset_id_str, document_id_str, session=db.session)
|
||||
document = DocumentService.get_document(dataset_id_str, document_id_str, session=db.session())
|
||||
if not document:
|
||||
raise NotFound("Document not found.")
|
||||
if not current_user.is_dataset_editor:
|
||||
@ -438,15 +438,20 @@ class DatasetDocumentSegmentAddApi(Resource):
|
||||
except ProviderTokenNotInitError as ex:
|
||||
raise ProviderNotInitializeError(ex.description)
|
||||
try:
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session)
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session())
|
||||
except services.errors.account.NoPermissionError as e:
|
||||
raise Forbidden(str(e))
|
||||
# validate args
|
||||
payload = SegmentCreatePayload.model_validate(console_ns.payload or {})
|
||||
payload_dict = payload.model_dump(exclude_none=True)
|
||||
SegmentService.segment_create_args_validate(payload_dict, document)
|
||||
segment = type_cast(DocumentSegment, SegmentService.create_segment(payload_dict, document, dataset, db.session))
|
||||
summary = SummaryIndexService.get_segment_summary(segment_id=segment.id, dataset_id=dataset_id_str)
|
||||
segment = type_cast(
|
||||
DocumentSegment,
|
||||
SegmentService.create_segment(payload_dict, document, dataset, db.session()),
|
||||
)
|
||||
summary = SummaryIndexService.get_segment_summary(
|
||||
segment_id=segment.id, dataset_id=dataset_id_str, session=db.session()
|
||||
)
|
||||
response = {
|
||||
"data": segment_response_with_summary(segment, summary.summary_content if summary else None),
|
||||
"doc_form": document.doc_form,
|
||||
@ -472,21 +477,21 @@ class DatasetDocumentSegmentUpdateApi(Resource):
|
||||
):
|
||||
# check dataset
|
||||
dataset_id_str = str(dataset_id)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session())
|
||||
if not dataset:
|
||||
raise NotFound("Dataset not found.")
|
||||
# check user's model setting
|
||||
DatasetService.check_dataset_model_setting(dataset)
|
||||
# check document
|
||||
document_id_str = str(document_id)
|
||||
document = DocumentService.get_document(dataset_id_str, document_id_str, session=db.session)
|
||||
document = DocumentService.get_document(dataset_id_str, document_id_str, session=db.session())
|
||||
if not document:
|
||||
raise NotFound("Document not found.")
|
||||
# The role of the current user in the ta table must be admin, owner, dataset_operator, or editor
|
||||
if not current_user.is_dataset_editor:
|
||||
raise Forbidden()
|
||||
try:
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session)
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session())
|
||||
except services.errors.account.NoPermissionError as e:
|
||||
raise Forbidden(str(e))
|
||||
if dataset.indexing_technique == IndexTechniqueType.HIGH_QUALITY:
|
||||
@ -518,9 +523,11 @@ class DatasetDocumentSegmentUpdateApi(Resource):
|
||||
segment,
|
||||
document,
|
||||
dataset,
|
||||
db.session,
|
||||
db.session(),
|
||||
)
|
||||
summary = SummaryIndexService.get_segment_summary(
|
||||
segment_id=segment.id, dataset_id=dataset_id_str, session=db.session()
|
||||
)
|
||||
summary = SummaryIndexService.get_segment_summary(segment_id=segment.id, dataset_id=dataset_id_str)
|
||||
response = {
|
||||
"data": segment_response_with_summary(segment, summary.summary_content if summary else None),
|
||||
"doc_form": document.doc_form,
|
||||
@ -541,26 +548,26 @@ class DatasetDocumentSegmentUpdateApi(Resource):
|
||||
):
|
||||
# check dataset
|
||||
dataset_id_str = str(dataset_id)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session())
|
||||
if not dataset:
|
||||
raise NotFound("Dataset not found.")
|
||||
# check user's model setting
|
||||
DatasetService.check_dataset_model_setting(dataset)
|
||||
# check document
|
||||
document_id_str = str(document_id)
|
||||
document = DocumentService.get_document(dataset_id_str, document_id_str, session=db.session)
|
||||
document = DocumentService.get_document(dataset_id_str, document_id_str, session=db.session())
|
||||
if not document:
|
||||
raise NotFound("Document not found.")
|
||||
# The role of the current user in the ta table must be admin, owner, dataset_operator, or editor
|
||||
if not current_user.is_dataset_editor:
|
||||
raise Forbidden()
|
||||
try:
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session)
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session())
|
||||
except services.errors.account.NoPermissionError as e:
|
||||
raise Forbidden(str(e))
|
||||
segment_id_str = str(segment_id)
|
||||
_, segment = _get_segment_for_document(dataset, document, segment_id_str)
|
||||
SegmentService.delete_segment(segment, document, dataset, db.session)
|
||||
SegmentService.delete_segment(segment, document, dataset, db.session())
|
||||
return "", 204
|
||||
|
||||
|
||||
@ -583,12 +590,12 @@ class DatasetDocumentSegmentBatchImportApi(Resource):
|
||||
def post(self, current_tenant_id: str, current_user: Account, dataset_id: UUID, document_id: UUID):
|
||||
# check dataset
|
||||
dataset_id_str = str(dataset_id)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session())
|
||||
if not dataset:
|
||||
raise NotFound("Dataset not found.")
|
||||
# check document
|
||||
document_id_str = str(document_id)
|
||||
document = DocumentService.get_document(dataset_id_str, document_id_str, session=db.session)
|
||||
document = DocumentService.get_document(dataset_id_str, document_id_str, session=db.session())
|
||||
if not document:
|
||||
raise NotFound("Document not found.")
|
||||
|
||||
@ -658,18 +665,18 @@ class ChildChunkAddApi(Resource):
|
||||
):
|
||||
# check dataset
|
||||
dataset_id_str = str(dataset_id)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session())
|
||||
if not dataset:
|
||||
raise NotFound("Dataset not found.")
|
||||
# check document
|
||||
document_id_str = str(document_id)
|
||||
document = DocumentService.get_document(dataset_id_str, document_id_str, session=db.session)
|
||||
document = DocumentService.get_document(dataset_id_str, document_id_str, session=db.session())
|
||||
if not document:
|
||||
raise NotFound("Document not found.")
|
||||
if not current_user.is_dataset_editor:
|
||||
raise Forbidden()
|
||||
try:
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session)
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session())
|
||||
except services.errors.account.NoPermissionError as e:
|
||||
raise Forbidden(str(e))
|
||||
# check embedding model setting
|
||||
@ -693,7 +700,7 @@ class ChildChunkAddApi(Resource):
|
||||
# validate args
|
||||
try:
|
||||
payload = ChildChunkCreatePayload.model_validate(console_ns.payload or {})
|
||||
child_chunk = SegmentService.create_child_chunk(payload.content, segment, document, dataset, db.session)
|
||||
child_chunk = SegmentService.create_child_chunk(payload.content, segment, document, dataset, db.session())
|
||||
except ChildChunkIndexingServiceError as e:
|
||||
raise ChildChunkIndexingError(str(e))
|
||||
return dump_response(ChildChunkDetailResponse, {"data": child_chunk}), 200
|
||||
@ -709,14 +716,14 @@ class ChildChunkAddApi(Resource):
|
||||
def get(self, current_tenant_id: str, dataset_id: UUID, document_id: UUID, segment_id: UUID):
|
||||
# check dataset
|
||||
dataset_id_str = str(dataset_id)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session())
|
||||
if not dataset:
|
||||
raise NotFound("Dataset not found.")
|
||||
# check user's model setting
|
||||
DatasetService.check_dataset_model_setting(dataset)
|
||||
# check document
|
||||
document_id_str = str(document_id)
|
||||
document = DocumentService.get_document(dataset_id_str, document_id_str, session=db.session)
|
||||
document = DocumentService.get_document(dataset_id_str, document_id_str, session=db.session())
|
||||
if not document:
|
||||
raise NotFound("Document not found.")
|
||||
segment_id_str = str(segment_id)
|
||||
@ -759,21 +766,21 @@ class ChildChunkAddApi(Resource):
|
||||
):
|
||||
# check dataset
|
||||
dataset_id_str = str(dataset_id)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session())
|
||||
if not dataset:
|
||||
raise NotFound("Dataset not found.")
|
||||
# check user's model setting
|
||||
DatasetService.check_dataset_model_setting(dataset)
|
||||
# check document
|
||||
document_id_str = str(document_id)
|
||||
document = DocumentService.get_document(dataset_id_str, document_id_str, session=db.session)
|
||||
document = DocumentService.get_document(dataset_id_str, document_id_str, session=db.session())
|
||||
if not document:
|
||||
raise NotFound("Document not found.")
|
||||
# The role of the current user in the ta table must be admin, owner, dataset_operator, or editor
|
||||
if not current_user.is_dataset_editor:
|
||||
raise Forbidden()
|
||||
try:
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session)
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session())
|
||||
except services.errors.account.NoPermissionError as e:
|
||||
raise Forbidden(str(e))
|
||||
segment_id_str = str(segment_id)
|
||||
@ -781,7 +788,7 @@ class ChildChunkAddApi(Resource):
|
||||
# validate args
|
||||
payload = ChildChunkBatchUpdatePayload.model_validate(console_ns.payload or {})
|
||||
try:
|
||||
child_chunks = SegmentService.update_child_chunks(payload.chunks, segment, document, dataset, db.session)
|
||||
child_chunks = SegmentService.update_child_chunks(payload.chunks, segment, document, dataset, db.session())
|
||||
except ChildChunkIndexingServiceError as e:
|
||||
raise ChildChunkIndexingError(str(e))
|
||||
return dump_response(ChildChunkBatchUpdateResponse, {"data": child_chunks}), 200
|
||||
@ -811,31 +818,31 @@ class ChildChunkUpdateApi(Resource):
|
||||
):
|
||||
# check dataset
|
||||
dataset_id_str = str(dataset_id)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session())
|
||||
if not dataset:
|
||||
raise NotFound("Dataset not found.")
|
||||
# check user's model setting
|
||||
DatasetService.check_dataset_model_setting(dataset)
|
||||
# check document
|
||||
document_id_str = str(document_id)
|
||||
document = DocumentService.get_document(dataset_id_str, document_id_str, session=db.session)
|
||||
document = DocumentService.get_document(dataset_id_str, document_id_str, session=db.session())
|
||||
if not document:
|
||||
raise NotFound("Document not found.")
|
||||
# The role of the current user in the ta table must be admin, owner, dataset_operator, or editor
|
||||
if not current_user.is_dataset_editor:
|
||||
raise Forbidden()
|
||||
try:
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session)
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session())
|
||||
except services.errors.account.NoPermissionError as e:
|
||||
raise Forbidden(str(e))
|
||||
segment_id_str = str(segment_id)
|
||||
segment_ref, _ = _get_segment_for_document(dataset, document, segment_id_str)
|
||||
child_chunk_id_str = str(child_chunk_id)
|
||||
child_chunk = SegmentService.get_child_chunk_by_segment_ref(child_chunk_id_str, segment_ref)
|
||||
child_chunk = SegmentService.get_child_chunk_by_segment_ref(child_chunk_id_str, segment_ref, db.session())
|
||||
if not child_chunk:
|
||||
raise NotFound("Child chunk not found.")
|
||||
try:
|
||||
SegmentService.delete_child_chunk(child_chunk, dataset, db.session)
|
||||
SegmentService.delete_child_chunk(child_chunk, dataset, db.session())
|
||||
except ChildChunkDeleteIndexServiceError as e:
|
||||
raise ChildChunkDeleteIndexError(str(e))
|
||||
return "", 204
|
||||
@ -862,34 +869,34 @@ class ChildChunkUpdateApi(Resource):
|
||||
):
|
||||
# check dataset
|
||||
dataset_id_str = str(dataset_id)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session())
|
||||
if not dataset:
|
||||
raise NotFound("Dataset not found.")
|
||||
# check user's model setting
|
||||
DatasetService.check_dataset_model_setting(dataset)
|
||||
# check document
|
||||
document_id_str = str(document_id)
|
||||
document = DocumentService.get_document(dataset_id_str, document_id_str, session=db.session)
|
||||
document = DocumentService.get_document(dataset_id_str, document_id_str, session=db.session())
|
||||
if not document:
|
||||
raise NotFound("Document not found.")
|
||||
# The role of the current user in the ta table must be admin, owner, dataset_operator, or editor
|
||||
if not current_user.is_dataset_editor:
|
||||
raise Forbidden()
|
||||
try:
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session)
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session())
|
||||
except services.errors.account.NoPermissionError as e:
|
||||
raise Forbidden(str(e))
|
||||
segment_id_str = str(segment_id)
|
||||
segment_ref, segment = _get_segment_for_document(dataset, document, segment_id_str)
|
||||
child_chunk_id_str = str(child_chunk_id)
|
||||
child_chunk = SegmentService.get_child_chunk_by_segment_ref(child_chunk_id_str, segment_ref)
|
||||
child_chunk = SegmentService.get_child_chunk_by_segment_ref(child_chunk_id_str, segment_ref, db.session())
|
||||
if not child_chunk:
|
||||
raise NotFound("Child chunk not found.")
|
||||
# validate args
|
||||
try:
|
||||
payload = ChildChunkUpdatePayload.model_validate(console_ns.payload or {})
|
||||
child_chunk = SegmentService.update_child_chunk(
|
||||
payload.content, child_chunk, segment, document, dataset, db.session
|
||||
payload.content, child_chunk, segment, document, dataset, db.session()
|
||||
)
|
||||
except ChildChunkIndexingServiceError as e:
|
||||
raise ChildChunkIndexingError(str(e))
|
||||
|
||||
@ -299,7 +299,9 @@ class ExternalApiTemplateApi(Resource):
|
||||
if not (current_user.has_edit_permission or current_user.is_dataset_operator):
|
||||
raise Forbidden()
|
||||
|
||||
ExternalDatasetService.delete_external_knowledge_api(session, current_tenant_id, external_knowledge_api_id_str)
|
||||
ExternalDatasetService.delete_external_knowledge_api(
|
||||
current_tenant_id, external_knowledge_api_id_str, session=session
|
||||
)
|
||||
return "", 204
|
||||
|
||||
|
||||
@ -318,9 +320,7 @@ class ExternalApiUseCheckApi(Resource):
|
||||
external_knowledge_api_id_str = str(external_knowledge_api_id)
|
||||
|
||||
external_knowledge_api_is_using, count = ExternalDatasetService.external_knowledge_api_use_check(
|
||||
session,
|
||||
external_knowledge_api_id_str,
|
||||
current_tenant_id,
|
||||
external_knowledge_api_id_str, current_tenant_id, session=session
|
||||
)
|
||||
return {"is_using": external_knowledge_api_is_using, "count": count}, 200
|
||||
|
||||
@ -366,6 +366,7 @@ class ExternalDatasetCreateApi(Resource):
|
||||
str(current_tenant_id),
|
||||
current_user.id,
|
||||
[dataset_id_str],
|
||||
session=session,
|
||||
)
|
||||
item["permission_keys"] = permission_keys_map.get(dataset_id_str, [])
|
||||
|
||||
@ -393,12 +394,12 @@ class ExternalKnowledgeHitTestingApi(Resource):
|
||||
@with_session
|
||||
def post(self, session: Session, current_user: Account, dataset_id: UUID):
|
||||
dataset_id_str = str(dataset_id)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session())
|
||||
if dataset is None:
|
||||
raise NotFound("Dataset not found.")
|
||||
|
||||
try:
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session)
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session())
|
||||
except services.errors.account.NoPermissionError as e:
|
||||
raise Forbidden(str(e))
|
||||
|
||||
|
||||
@ -86,12 +86,12 @@ class DatasetsHitTestingBase:
|
||||
dataset_id: str, current_user: Account | None = None, current_tenant_id: str | None = None
|
||||
) -> Dataset:
|
||||
current_user, _ = resolve_account_fallback(current_user, current_tenant_id)
|
||||
dataset = DatasetService.get_dataset(dataset_id, db.session)
|
||||
dataset = DatasetService.get_dataset(dataset_id, db.session())
|
||||
if dataset is None:
|
||||
raise NotFound("Dataset not found.")
|
||||
|
||||
try:
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session)
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session())
|
||||
except services.errors.account.NoPermissionError as e:
|
||||
raise Forbidden(str(e))
|
||||
|
||||
|
||||
@ -61,13 +61,13 @@ class DatasetMetadataCreateApi(Resource):
|
||||
metadata_args = MetadataArgs.model_validate(console_ns.payload or {})
|
||||
|
||||
dataset_id_str = str(dataset_id)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session())
|
||||
if dataset is None:
|
||||
raise NotFound("Dataset not found.")
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session)
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session())
|
||||
|
||||
metadata = MetadataService.create_metadata(
|
||||
db.session(), dataset_id_str, metadata_args, current_user, current_tenant_id
|
||||
dataset_id_str, metadata_args, current_user, current_tenant_id, session=db.session()
|
||||
)
|
||||
return dump_response(DatasetMetadataResponse, metadata), 201
|
||||
|
||||
@ -81,10 +81,10 @@ class DatasetMetadataCreateApi(Resource):
|
||||
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_CREATE_AND_MANAGEMENT)
|
||||
def get(self, dataset_id: UUID):
|
||||
dataset_id_str = str(dataset_id)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session())
|
||||
if dataset is None:
|
||||
raise NotFound("Dataset not found.")
|
||||
metadata = MetadataService.get_dataset_metadatas(db.session(), dataset)
|
||||
metadata = MetadataService.get_dataset_metadatas(dataset, session=db.session())
|
||||
return dump_response(DatasetMetadataListResponse, metadata), 200
|
||||
|
||||
|
||||
@ -105,13 +105,13 @@ class DatasetMetadataApi(Resource):
|
||||
|
||||
dataset_id_str = str(dataset_id)
|
||||
metadata_id_str = str(metadata_id)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session())
|
||||
if dataset is None:
|
||||
raise NotFound("Dataset not found.")
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session)
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session())
|
||||
|
||||
metadata = MetadataService.update_metadata_name(
|
||||
db.session(), dataset_id_str, metadata_id_str, name, current_user, current_tenant_id
|
||||
dataset_id_str, metadata_id_str, name, current_user, current_tenant_id, session=db.session()
|
||||
)
|
||||
return dump_response(DatasetMetadataResponse, metadata), 200
|
||||
|
||||
@ -125,12 +125,12 @@ class DatasetMetadataApi(Resource):
|
||||
def delete(self, current_user: Account, dataset_id: UUID, metadata_id: UUID):
|
||||
dataset_id_str = str(dataset_id)
|
||||
metadata_id_str = str(metadata_id)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session())
|
||||
if dataset is None:
|
||||
raise NotFound("Dataset not found.")
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session)
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session())
|
||||
|
||||
MetadataService.delete_metadata(db.session(), dataset_id_str, metadata_id_str)
|
||||
MetadataService.delete_metadata(dataset_id_str, metadata_id_str, session=db.session())
|
||||
# Frontend callers only await success and invalidate metadata caches; no response body is consumed.
|
||||
return "", 204
|
||||
|
||||
@ -162,16 +162,16 @@ class DatasetMetadataBuiltInFieldActionApi(Resource):
|
||||
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
|
||||
def post(self, current_user: Account, dataset_id: UUID, action: Literal["enable", "disable"]):
|
||||
dataset_id_str = str(dataset_id)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session())
|
||||
if dataset is None:
|
||||
raise NotFound("Dataset not found.")
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session)
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session())
|
||||
|
||||
match action:
|
||||
case "enable":
|
||||
MetadataService.enable_built_in_field(db.session(), dataset)
|
||||
MetadataService.enable_built_in_field(dataset, session=db.session())
|
||||
case "disable":
|
||||
MetadataService.disable_built_in_field(db.session(), dataset)
|
||||
MetadataService.disable_built_in_field(dataset, session=db.session())
|
||||
# Frontend callers only await success and invalidate metadata caches; no response body is consumed.
|
||||
return "", 204
|
||||
|
||||
@ -191,14 +191,14 @@ class DocumentMetadataEditApi(Resource):
|
||||
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
|
||||
def post(self, current_user: Account, dataset_id: UUID):
|
||||
dataset_id_str = str(dataset_id)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session())
|
||||
if dataset is None:
|
||||
raise NotFound("Dataset not found.")
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session)
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session())
|
||||
|
||||
metadata_args = MetadataOperationData.model_validate(console_ns.payload or {})
|
||||
|
||||
MetadataService.update_documents_metadata(db.session(), dataset, metadata_args, current_user)
|
||||
MetadataService.update_documents_metadata(dataset, metadata_args, current_user, session=db.session())
|
||||
|
||||
# Frontend callers only await success and invalidate caches; no response body is consumed.
|
||||
return "", 204
|
||||
|
||||
@ -23,6 +23,7 @@ from core.entities.provider_entities import ProviderConfig
|
||||
from core.plugin.entities.plugin_daemon import PluginOAuthAuthorizationUrlResponse
|
||||
from core.plugin.impl.oauth import OAuthHandler
|
||||
from core.tools.entities.common_entities import I18nObject
|
||||
from extensions.ext_database import db
|
||||
from fields.base import ResponseModel
|
||||
from graphon.model_runtime.errors.validate import CredentialsValidateFailedError
|
||||
from libs.helper import dump_response
|
||||
@ -309,6 +310,7 @@ class DatasourceAuth(Resource):
|
||||
provider=datasource_provider_id.provider_name,
|
||||
plugin_id=datasource_provider_id.plugin_id,
|
||||
user=user,
|
||||
session=db.session(),
|
||||
)
|
||||
return dump_response(DatasourceCredentialListResponse, {"result": datasources}), 200
|
||||
|
||||
@ -335,6 +337,7 @@ class DatasourceAuthDeleteApi(Resource):
|
||||
auth_id=payload.credential_id,
|
||||
provider=provider_name,
|
||||
plugin_id=plugin_id,
|
||||
session=db.session(),
|
||||
)
|
||||
return SimpleResultResponse(result="success").model_dump(mode="json"), 200
|
||||
|
||||
@ -380,7 +383,9 @@ class DatasourceAuthListApi(Resource):
|
||||
@with_current_tenant_id
|
||||
def get(self, current_tenant_id: str):
|
||||
datasource_provider_service = DatasourceProviderService()
|
||||
datasources = datasource_provider_service.get_all_datasource_credentials(tenant_id=current_tenant_id)
|
||||
datasources = datasource_provider_service.get_all_datasource_credentials(
|
||||
tenant_id=current_tenant_id, session=db.session()
|
||||
)
|
||||
return dump_response(DatasourceProviderAuthListResponse, {"result": datasources}), 200
|
||||
|
||||
|
||||
@ -397,7 +402,9 @@ class DatasourceHardCodeAuthListApi(Resource):
|
||||
@with_current_tenant_id
|
||||
def get(self, current_tenant_id: str):
|
||||
datasource_provider_service = DatasourceProviderService()
|
||||
datasources = datasource_provider_service.get_hard_code_datasource_credentials(tenant_id=current_tenant_id)
|
||||
datasources = datasource_provider_service.get_hard_code_datasource_credentials(
|
||||
tenant_id=current_tenant_id, session=db.session()
|
||||
)
|
||||
return dump_response(DatasourceProviderAuthListResponse, {"result": datasources}), 200
|
||||
|
||||
|
||||
|
||||
@ -9,6 +9,7 @@ from controllers.common.schema import register_schema_models
|
||||
from controllers.console import console_ns
|
||||
from controllers.console.datasets.wraps import get_rag_pipeline
|
||||
from controllers.console.wraps import account_initialization_required, setup_required, with_current_user
|
||||
from extensions.ext_database import db
|
||||
from libs.login import login_required
|
||||
from models import Account
|
||||
from models.dataset import Pipeline
|
||||
@ -41,7 +42,7 @@ class DataSourceContentPreviewApi(Resource):
|
||||
|
||||
inputs = args.inputs
|
||||
datasource_type = args.datasource_type
|
||||
rag_pipeline_service = RagPipelineService()
|
||||
rag_pipeline_service = RagPipelineService(db.session())
|
||||
preview_content = rag_pipeline_service.run_datasource_node_preview(
|
||||
pipeline=pipeline,
|
||||
node_id=node_id,
|
||||
|
||||
@ -108,7 +108,10 @@ class PipelineTemplateListApi(Resource):
|
||||
query = PipelineTemplateListQuery.model_validate(request.args.to_dict(flat=True))
|
||||
# get pipeline templates
|
||||
pipeline_templates = RagPipelineService.get_pipeline_templates(
|
||||
session, query.type, query.language, current_tenant_id
|
||||
type=query.type,
|
||||
language=query.language,
|
||||
current_tenant_id=current_tenant_id,
|
||||
session=session,
|
||||
)
|
||||
return dump_response(PipelineTemplateListResponse, pipeline_templates), 200
|
||||
|
||||
@ -124,8 +127,11 @@ class PipelineTemplateDetailApi(Resource):
|
||||
@with_session
|
||||
def get(self, session: Session, template_id: str) -> JsonResponseWithStatus:
|
||||
query = PipelineTemplateDetailQuery.model_validate(request.args.to_dict(flat=True))
|
||||
rag_pipeline_service = RagPipelineService()
|
||||
pipeline_template = rag_pipeline_service.get_pipeline_template_detail(session, template_id, query.type)
|
||||
pipeline_template = RagPipelineService.get_pipeline_template_detail(
|
||||
template_id,
|
||||
type=query.type,
|
||||
session=session,
|
||||
)
|
||||
if pipeline_template is None:
|
||||
raise NotFound("Pipeline template not found from upstream service.")
|
||||
return dump_response(PipelineTemplateDetailResponse, pipeline_template), 200
|
||||
@ -145,7 +151,7 @@ class CustomizedPipelineTemplateApi(Resource):
|
||||
payload = CustomizedPipelineTemplatePayload.model_validate(console_ns.payload or {})
|
||||
pipeline_template_info = PipelineTemplateInfoEntity.model_validate(payload.model_dump())
|
||||
RagPipelineService.update_customized_pipeline_template(
|
||||
template_id, pipeline_template_info, current_user, current_tenant_id
|
||||
template_id, pipeline_template_info, current_user, current_tenant_id, session=db.session()
|
||||
)
|
||||
return "", 204
|
||||
|
||||
@ -156,7 +162,7 @@ class CustomizedPipelineTemplateApi(Resource):
|
||||
@enterprise_license_required
|
||||
@with_current_tenant_id
|
||||
def delete(self, current_tenant_id: str, template_id: str) -> tuple[str, int]:
|
||||
RagPipelineService.delete_customized_pipeline_template(template_id, current_tenant_id)
|
||||
RagPipelineService.delete_customized_pipeline_template(template_id, current_tenant_id, session=db.session())
|
||||
return "", 204
|
||||
|
||||
@setup_required
|
||||
@ -188,8 +194,8 @@ class PublishCustomizedPipelineTemplateApi(Resource):
|
||||
@with_current_tenant_id
|
||||
def post(self, current_tenant_id: str, current_user: Account, pipeline_id: str) -> tuple[str, int]:
|
||||
payload = CustomizedPipelineTemplatePayload.model_validate(console_ns.payload or {})
|
||||
rag_pipeline_service = RagPipelineService()
|
||||
rag_pipeline_service = RagPipelineService(db.session())
|
||||
rag_pipeline_service.publish_customized_pipeline_template(
|
||||
pipeline_id, payload.model_dump(), current_user, current_tenant_id
|
||||
pipeline_id, payload.model_dump(), current_user, current_tenant_id, session=db.session()
|
||||
)
|
||||
return "", 204
|
||||
|
||||
@ -65,7 +65,7 @@ class CreateRagPipelineDatasetApi(Resource):
|
||||
yaml_content=payload.yaml_content,
|
||||
)
|
||||
try:
|
||||
rag_pipeline_dsl_service = RagPipelineDslService(db.session)
|
||||
rag_pipeline_dsl_service = RagPipelineDslService(db.session())
|
||||
import_info = rag_pipeline_dsl_service.create_rag_pipeline_dataset(
|
||||
tenant_id=current_tenant_id,
|
||||
rag_pipeline_dataset_create_entity=rag_pipeline_dataset_create_entity,
|
||||
@ -75,7 +75,7 @@ class CreateRagPipelineDatasetApi(Resource):
|
||||
current_tenant_id,
|
||||
import_info["dataset_id"],
|
||||
rag_pipeline_dataset_create_entity.partial_member_list,
|
||||
db.session,
|
||||
db.session(),
|
||||
)
|
||||
db.session.commit()
|
||||
except services.errors.dataset.DatasetNameDuplicateError:
|
||||
@ -110,6 +110,6 @@ class CreateEmptyRagPipelineDatasetApi(Resource):
|
||||
permission=DatasetPermissionEnum.ONLY_ME,
|
||||
partial_member_list=None,
|
||||
),
|
||||
session=db.session,
|
||||
session=db.session(),
|
||||
)
|
||||
return dump_response(DatasetDetailResponse, dataset), 201
|
||||
|
||||
@ -98,7 +98,7 @@ class RagPipelineVariableCollectionApi(Resource):
|
||||
query = PaginationQuery.model_validate(request.args.to_dict())
|
||||
|
||||
# fetch draft workflow by app_model
|
||||
rag_pipeline_service = RagPipelineService()
|
||||
rag_pipeline_service = RagPipelineService(db.session())
|
||||
workflow_exist = rag_pipeline_service.is_workflow_exist(pipeline=pipeline)
|
||||
if not workflow_exist:
|
||||
raise DraftWorkflowNotExist()
|
||||
@ -290,7 +290,7 @@ class RagPipelineVariableResetApi(Resource):
|
||||
session=db.session(),
|
||||
)
|
||||
|
||||
rag_pipeline_service = RagPipelineService()
|
||||
rag_pipeline_service = RagPipelineService(db.session())
|
||||
draft_workflow = rag_pipeline_service.get_draft_workflow(pipeline=pipeline)
|
||||
if draft_workflow is None:
|
||||
raise NotFoundError(
|
||||
@ -347,7 +347,7 @@ class RagPipelineEnvironmentVariableCollectionApi(Resource):
|
||||
Get draft workflow
|
||||
"""
|
||||
# fetch draft workflow by app_model
|
||||
rag_pipeline_service = RagPipelineService()
|
||||
rag_pipeline_service = RagPipelineService(db.session())
|
||||
workflow = rag_pipeline_service.get_draft_workflow(pipeline=pipeline)
|
||||
if workflow is None:
|
||||
raise DraftWorkflowNotExist()
|
||||
|
||||
@ -197,7 +197,7 @@ class DraftRagPipelineApi(Resource):
|
||||
Get draft rag pipeline's workflow
|
||||
"""
|
||||
# fetch draft workflow by app_model
|
||||
rag_pipeline_service = RagPipelineService()
|
||||
rag_pipeline_service = RagPipelineService(db.session())
|
||||
workflow = rag_pipeline_service.get_draft_workflow(pipeline=pipeline)
|
||||
|
||||
if not workflow:
|
||||
@ -231,7 +231,7 @@ class DraftRagPipelineApi(Resource):
|
||||
return {"message": "Invalid JSON data"}, 400
|
||||
else:
|
||||
abort(415)
|
||||
rag_pipeline_service = RagPipelineService()
|
||||
rag_pipeline_service = RagPipelineService(db.session())
|
||||
|
||||
try:
|
||||
environment_variables_list = Workflow.normalize_environment_variable_mappings(
|
||||
@ -283,7 +283,7 @@ class RagPipelineDraftRunIterationNodeApi(Resource):
|
||||
|
||||
try:
|
||||
response = PipelineGenerateService.generate_single_iteration(
|
||||
pipeline=pipeline, user=current_user, node_id=node_id, args=args, streaming=True
|
||||
pipeline=pipeline, user=current_user, node_id=node_id, args=args, session=db.session(), streaming=True
|
||||
)
|
||||
|
||||
return helper.compact_generate_response(response)
|
||||
@ -318,7 +318,7 @@ class RagPipelineDraftRunLoopNodeApi(Resource):
|
||||
|
||||
try:
|
||||
response = PipelineGenerateService.generate_single_loop(
|
||||
pipeline=pipeline, user=current_user, node_id=node_id, args=args, streaming=True
|
||||
pipeline=pipeline, user=current_user, node_id=node_id, args=args, session=db.session(), streaming=True
|
||||
)
|
||||
|
||||
return helper.compact_generate_response(response)
|
||||
@ -343,8 +343,8 @@ class DraftRagPipelineRunApi(Resource):
|
||||
@edit_permission_required
|
||||
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
|
||||
@with_current_user
|
||||
@get_rag_pipeline
|
||||
@with_session
|
||||
@get_rag_pipeline
|
||||
def post(self, session: Session, current_user: Account, pipeline: Pipeline):
|
||||
"""
|
||||
Run draft workflow
|
||||
@ -377,8 +377,8 @@ class PublishedRagPipelineRunApi(Resource):
|
||||
@edit_permission_required
|
||||
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
|
||||
@with_current_user
|
||||
@get_rag_pipeline
|
||||
@with_session
|
||||
@get_rag_pipeline
|
||||
def post(self, session: Session, current_user: Account, pipeline: Pipeline):
|
||||
"""
|
||||
Run published workflow
|
||||
@ -419,7 +419,7 @@ class RagPipelinePublishedDatasourceNodeRunApi(Resource):
|
||||
"""
|
||||
payload = DatasourceNodeRunPayload.model_validate(console_ns.payload or {})
|
||||
|
||||
rag_pipeline_service = RagPipelineService()
|
||||
rag_pipeline_service = RagPipelineService(db.session())
|
||||
return helper.compact_generate_response(
|
||||
PipelineGenerator.convert_to_event_stream(
|
||||
rag_pipeline_service.run_datasource_workflow_node(
|
||||
@ -452,7 +452,7 @@ class RagPipelineDraftDatasourceNodeRunApi(Resource):
|
||||
"""
|
||||
payload = DatasourceNodeRunPayload.model_validate(console_ns.payload or {})
|
||||
|
||||
rag_pipeline_service = RagPipelineService()
|
||||
rag_pipeline_service = RagPipelineService(db.session())
|
||||
return helper.compact_generate_response(
|
||||
PipelineGenerator.convert_to_event_stream(
|
||||
rag_pipeline_service.run_datasource_workflow_node(
|
||||
@ -490,7 +490,7 @@ class RagPipelineDraftNodeRunApi(Resource):
|
||||
payload = NodeRunRequiredPayload.model_validate(console_ns.payload or {})
|
||||
inputs = payload.inputs
|
||||
|
||||
rag_pipeline_service = RagPipelineService()
|
||||
rag_pipeline_service = RagPipelineService(db.session())
|
||||
workflow_node_execution = rag_pipeline_service.run_draft_workflow_node(
|
||||
pipeline=pipeline, node_id=node_id, user_inputs=inputs, account=current_user
|
||||
)
|
||||
@ -543,7 +543,7 @@ class PublishedRagPipelineApi(Resource):
|
||||
if not pipeline.is_published:
|
||||
return None
|
||||
# fetch published workflow by pipeline
|
||||
rag_pipeline_service = RagPipelineService()
|
||||
rag_pipeline_service = RagPipelineService(db.session())
|
||||
workflow = rag_pipeline_service.get_published_workflow(pipeline=pipeline)
|
||||
|
||||
# return workflow, if not found, return None
|
||||
@ -564,9 +564,9 @@ class PublishedRagPipelineApi(Resource):
|
||||
"""
|
||||
Publish workflow
|
||||
"""
|
||||
rag_pipeline_service = RagPipelineService()
|
||||
rag_pipeline_service = RagPipelineService(db.session())
|
||||
workflow = rag_pipeline_service.publish_workflow(
|
||||
session=db.session, # type: ignore[reportArgumentType,arg-type]
|
||||
session=db.session(),
|
||||
pipeline=pipeline,
|
||||
account=current_user,
|
||||
)
|
||||
@ -599,7 +599,7 @@ class DefaultRagPipelineBlockConfigsApi(Resource):
|
||||
Get default block config
|
||||
"""
|
||||
# Get default block configs
|
||||
rag_pipeline_service = RagPipelineService()
|
||||
rag_pipeline_service = RagPipelineService(db.session())
|
||||
return rag_pipeline_service.get_default_block_configs()
|
||||
|
||||
|
||||
@ -631,7 +631,7 @@ class DefaultRagPipelineBlockConfigApi(Resource):
|
||||
raise ValueError("Invalid filters")
|
||||
|
||||
# Get default block configs
|
||||
rag_pipeline_service = RagPipelineService()
|
||||
rag_pipeline_service = RagPipelineService(db.session())
|
||||
return rag_pipeline_service.get_default_block_config(node_type=block_type, filters=filters)
|
||||
|
||||
|
||||
@ -666,7 +666,7 @@ class PublishedAllRagPipelineApi(Resource):
|
||||
if user_id != current_user.id:
|
||||
raise Forbidden()
|
||||
|
||||
rag_pipeline_service = RagPipelineService()
|
||||
rag_pipeline_service = RagPipelineService(db.session())
|
||||
with sessionmaker(db.engine).begin() as session:
|
||||
workflows, has_more = rag_pipeline_service.get_all_published_workflow(
|
||||
session=session,
|
||||
@ -698,7 +698,7 @@ class RagPipelineDraftWorkflowRestoreApi(Resource):
|
||||
@with_current_user
|
||||
@get_rag_pipeline
|
||||
def post(self, current_user: Account, pipeline: Pipeline, workflow_id: str):
|
||||
rag_pipeline_service = RagPipelineService()
|
||||
rag_pipeline_service = RagPipelineService(db.session())
|
||||
|
||||
try:
|
||||
workflow = rag_pipeline_service.restore_published_workflow_to_draft(
|
||||
@ -743,7 +743,7 @@ class RagPipelineByIdApi(Resource):
|
||||
if not update_data:
|
||||
return {"message": "No valid fields to update"}, 400
|
||||
|
||||
rag_pipeline_service = RagPipelineService()
|
||||
rag_pipeline_service = RagPipelineService(db.session())
|
||||
workflow_ref = WorkflowRefService.create_pipeline_workflow_ref(pipeline, workflow_id)
|
||||
|
||||
# Create a session and manage the transaction
|
||||
@ -809,7 +809,7 @@ class PublishedRagPipelineSecondStepApi(Resource):
|
||||
"""
|
||||
query = NodeIdQuery.model_validate(request.args.to_dict())
|
||||
node_id = query.node_id
|
||||
rag_pipeline_service = RagPipelineService()
|
||||
rag_pipeline_service = RagPipelineService(db.session())
|
||||
variables = rag_pipeline_service.get_second_step_parameters(pipeline=pipeline, node_id=node_id, is_draft=False)
|
||||
return {
|
||||
"variables": variables,
|
||||
@ -832,7 +832,7 @@ class PublishedRagPipelineFirstStepApi(Resource):
|
||||
"""
|
||||
query = NodeIdQuery.model_validate(request.args.to_dict())
|
||||
node_id = query.node_id
|
||||
rag_pipeline_service = RagPipelineService()
|
||||
rag_pipeline_service = RagPipelineService(db.session())
|
||||
variables = rag_pipeline_service.get_first_step_parameters(pipeline=pipeline, node_id=node_id, is_draft=False)
|
||||
return {
|
||||
"variables": variables,
|
||||
@ -855,7 +855,7 @@ class DraftRagPipelineFirstStepApi(Resource):
|
||||
"""
|
||||
query = NodeIdQuery.model_validate(request.args.to_dict())
|
||||
node_id = query.node_id
|
||||
rag_pipeline_service = RagPipelineService()
|
||||
rag_pipeline_service = RagPipelineService(db.session())
|
||||
variables = rag_pipeline_service.get_first_step_parameters(pipeline=pipeline, node_id=node_id, is_draft=True)
|
||||
return {
|
||||
"variables": variables,
|
||||
@ -879,7 +879,7 @@ class DraftRagPipelineSecondStepApi(Resource):
|
||||
query = NodeIdQuery.model_validate(request.args.to_dict())
|
||||
node_id = query.node_id
|
||||
|
||||
rag_pipeline_service = RagPipelineService()
|
||||
rag_pipeline_service = RagPipelineService(db.session())
|
||||
variables = rag_pipeline_service.get_second_step_parameters(pipeline=pipeline, node_id=node_id, is_draft=True)
|
||||
return {
|
||||
"variables": variables,
|
||||
@ -913,7 +913,7 @@ class RagPipelineWorkflowRunListApi(Resource):
|
||||
"limit": query.limit,
|
||||
}
|
||||
|
||||
rag_pipeline_service = RagPipelineService()
|
||||
rag_pipeline_service = RagPipelineService(db.session())
|
||||
result = rag_pipeline_service.get_rag_pipeline_paginate_workflow_runs(pipeline=pipeline, args=args)
|
||||
|
||||
return WorkflowRunPaginationResponse.model_validate(result, from_attributes=True).model_dump(mode="json")
|
||||
@ -936,7 +936,7 @@ class RagPipelineWorkflowRunDetailApi(Resource):
|
||||
"""
|
||||
run_id_str = str(run_id)
|
||||
|
||||
rag_pipeline_service = RagPipelineService()
|
||||
rag_pipeline_service = RagPipelineService(db.session())
|
||||
workflow_run = rag_pipeline_service.get_rag_pipeline_workflow_run(pipeline=pipeline, run_id=run_id_str)
|
||||
if workflow_run is None:
|
||||
raise NotFound("Workflow run not found")
|
||||
@ -962,7 +962,7 @@ class RagPipelineWorkflowRunNodeExecutionListApi(Resource):
|
||||
"""
|
||||
run_id_str = str(run_id)
|
||||
|
||||
rag_pipeline_service = RagPipelineService()
|
||||
rag_pipeline_service = RagPipelineService(db.session())
|
||||
user = cast("Account | EndUser", current_user)
|
||||
node_executions = rag_pipeline_service.get_rag_pipeline_workflow_run_node_executions(
|
||||
pipeline=pipeline,
|
||||
@ -998,7 +998,7 @@ class RagPipelineWorkflowLastRunApi(Resource):
|
||||
@account_initialization_required
|
||||
@get_rag_pipeline
|
||||
def get(self, pipeline: Pipeline, node_id: str):
|
||||
rag_pipeline_service = RagPipelineService()
|
||||
rag_pipeline_service = RagPipelineService(db.session())
|
||||
workflow = rag_pipeline_service.get_draft_workflow(pipeline=pipeline)
|
||||
if not workflow:
|
||||
raise NotFound("Workflow not found")
|
||||
@ -1051,7 +1051,7 @@ class RagPipelineDatasourceVariableApi(Resource):
|
||||
"""
|
||||
args = DatasourceVariablesPayload.model_validate(console_ns.payload or {}).model_dump()
|
||||
|
||||
rag_pipeline_service = RagPipelineService()
|
||||
rag_pipeline_service = RagPipelineService(db.session())
|
||||
workflow_node_execution = rag_pipeline_service.set_datasource_variables(
|
||||
pipeline=pipeline,
|
||||
args=args,
|
||||
@ -1074,6 +1074,6 @@ class RagPipelineRecommendedPluginApi(Resource):
|
||||
def get(self, current_tenant_id: str, current_user: Account):
|
||||
query = RagPipelineRecommendedPluginQuery.model_validate(request.args.to_dict())
|
||||
|
||||
rag_pipeline_service = RagPipelineService()
|
||||
rag_pipeline_service = RagPipelineService(db.session())
|
||||
recommended_plugins = rag_pipeline_service.get_recommended_plugins(query.type, current_user, current_tenant_id)
|
||||
return recommended_plugins
|
||||
|
||||
@ -2,6 +2,7 @@ from collections.abc import Callable
|
||||
from functools import wraps
|
||||
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from controllers.console.datasets.error import PipelineNotFoundError
|
||||
from extensions.ext_database import db
|
||||
@ -22,9 +23,10 @@ def get_rag_pipeline[**P, R](view_func: Callable[P, R]) -> Callable[P, R]:
|
||||
|
||||
del kwargs["pipeline_id"]
|
||||
|
||||
pipeline = db.session.scalar(
|
||||
select(Pipeline).where(Pipeline.id == pipeline_id, Pipeline.tenant_id == current_tenant_id).limit(1)
|
||||
)
|
||||
stmt = select(Pipeline).where(Pipeline.id == pipeline_id, Pipeline.tenant_id == current_tenant_id).limit(1)
|
||||
# Migrated handlers pass the request Session as args[1]; legacy handlers still use db.session.
|
||||
session = args[1] if len(args) > 1 and isinstance(args[1], Session) else db.session
|
||||
pipeline = session.scalar(stmt)
|
||||
|
||||
if not pipeline:
|
||||
raise PipelineNotFoundError()
|
||||
|
||||
@ -113,7 +113,7 @@ class ChatTextApi(InstalledAppResource):
|
||||
|
||||
response = AudioService.transcript_tts(
|
||||
app_model=app_model,
|
||||
session=db.session,
|
||||
session=db.session(),
|
||||
text=text,
|
||||
voice=voice,
|
||||
message_ref=message_ref,
|
||||
|
||||
@ -111,7 +111,7 @@ class ConversationApi(InstalledAppResource):
|
||||
|
||||
conversation_id = str(c_id)
|
||||
try:
|
||||
ConversationService.delete(app_model, conversation_id, current_user)
|
||||
ConversationService.delete(app_model, conversation_id, current_user, session=db.session())
|
||||
except ConversationNotExistsError:
|
||||
raise NotFound("Conversation Not Exists.")
|
||||
|
||||
@ -140,7 +140,7 @@ class ConversationRenameApi(InstalledAppResource):
|
||||
|
||||
try:
|
||||
conversation = ConversationService.rename(
|
||||
app_model, conversation_id, current_user, payload.name, payload.auto_generate
|
||||
app_model, conversation_id, current_user, payload.name, payload.auto_generate, session=db.session()
|
||||
)
|
||||
return (
|
||||
TypeAdapter(SimpleConversation)
|
||||
@ -169,7 +169,7 @@ class ConversationPinApi(InstalledAppResource):
|
||||
conversation_id = str(c_id)
|
||||
|
||||
try:
|
||||
WebConversationService.pin(app_model, conversation_id, current_user)
|
||||
WebConversationService.pin(app_model, conversation_id, current_user, db.session())
|
||||
except ConversationNotExistsError:
|
||||
raise NotFound("Conversation Not Exists.")
|
||||
|
||||
@ -192,6 +192,6 @@ class ConversationUnPinApi(InstalledAppResource):
|
||||
raise NotChatAppError()
|
||||
|
||||
conversation_id = str(c_id)
|
||||
WebConversationService.unpin(app_model, conversation_id, current_user)
|
||||
WebConversationService.unpin(app_model, conversation_id, current_user, db.session())
|
||||
|
||||
return ResultResponse(result="success").model_dump(mode="json")
|
||||
|
||||
@ -181,7 +181,7 @@ class InstalledAppsListApi(Resource):
|
||||
|
||||
if current_user.current_tenant is None:
|
||||
raise ValueError("current_user.current_tenant must not be None")
|
||||
current_user.role = TenantService.get_user_role(current_user, current_user.current_tenant, session=db.session)
|
||||
current_user.role = TenantService.get_user_role(current_user, current_user.current_tenant, session=db.session())
|
||||
installed_app_list: list[dict[str, Any]] = []
|
||||
for installed_app, app_model in installed_apps:
|
||||
installed_app_list.append(
|
||||
|
||||
@ -27,6 +27,7 @@ from controllers.console.explore.wraps import InstalledAppResource
|
||||
from controllers.console.wraps import with_current_user
|
||||
from core.app.entities.app_invoke_entities import InvokeFrom
|
||||
from core.errors.error import ModelCurrentlyNotSupportError, ProviderTokenNotInitError, QuotaExceededError
|
||||
from extensions.ext_database import db
|
||||
from fields.conversation_fields import ResultResponse
|
||||
from fields.message_fields import (
|
||||
ExploreMessageInfiniteScrollPagination,
|
||||
@ -91,6 +92,7 @@ class MessageListApi(InstalledAppResource):
|
||||
args.conversation_id,
|
||||
args.first_id or None,
|
||||
args.limit,
|
||||
session=db.session(),
|
||||
)
|
||||
adapter = TypeAdapter(ExploreMessageListItem)
|
||||
items = [adapter.validate_python(message, from_attributes=True) for message in pagination.data]
|
||||
@ -129,6 +131,7 @@ class MessageFeedbackApi(InstalledAppResource):
|
||||
user=current_user,
|
||||
rating=FeedbackRating(payload.rating) if payload.rating else None,
|
||||
content=payload.content,
|
||||
session=db.session(),
|
||||
)
|
||||
except MessageNotExistsError:
|
||||
raise NotFound("Message Not Exists.")
|
||||
@ -207,7 +210,11 @@ class MessageSuggestedQuestionApi(InstalledAppResource):
|
||||
|
||||
try:
|
||||
questions = MessageService.get_suggested_questions_after_answer(
|
||||
app_model=app_model, user=current_user, message_id=message_id_str, invoke_from=InvokeFrom.EXPLORE
|
||||
app_model=app_model,
|
||||
user=current_user,
|
||||
message_id=message_id_str,
|
||||
invoke_from=InvokeFrom.EXPLORE,
|
||||
session=db.session(),
|
||||
)
|
||||
except MessageNotExistsError:
|
||||
raise NotFound("Message not found")
|
||||
|
||||
@ -8,6 +8,7 @@ from controllers.console import console_ns
|
||||
from controllers.console.app.error import AppUnavailableError
|
||||
from controllers.console.explore.wraps import InstalledAppResource
|
||||
from core.app.app_config.common.parameters_mapping import get_parameters_from_feature_dict
|
||||
from extensions.ext_database import db
|
||||
from models.model import AppMode, InstalledApp
|
||||
from services.app_service import AppService
|
||||
|
||||
@ -64,4 +65,4 @@ class ExploreAppMetaApi(InstalledAppResource):
|
||||
app_model = installed_app.app
|
||||
if not app_model:
|
||||
raise ValueError("App not found")
|
||||
return AppService().get_app_meta(app_model)
|
||||
return AppService().get_app_meta(app_model, session=db.session())
|
||||
|
||||
@ -120,7 +120,7 @@ class RecommendedAppListApi(Resource):
|
||||
language_prefix = _resolve_language(args.language, current_user)
|
||||
|
||||
return RecommendedAppListResponse.model_validate(
|
||||
RecommendedAppService.get_recommended_apps_and_categories(db.session, language_prefix),
|
||||
RecommendedAppService.get_recommended_apps_and_categories(language_prefix, session=db.session()),
|
||||
from_attributes=True,
|
||||
).model_dump(mode="json")
|
||||
|
||||
@ -137,7 +137,7 @@ class LearnDifyAppListApi(Resource):
|
||||
language_prefix = _resolve_language(args.language, current_user)
|
||||
|
||||
return LearnDifyAppListResponse.model_validate(
|
||||
RecommendedAppService.get_learn_dify_apps(db.session, language_prefix),
|
||||
RecommendedAppService.get_learn_dify_apps(language_prefix, session=db.session()),
|
||||
from_attributes=True,
|
||||
).model_dump(mode="json")
|
||||
|
||||
@ -148,4 +148,4 @@ class RecommendedAppApi(Resource):
|
||||
@login_required
|
||||
@account_initialization_required
|
||||
def get(self, app_id: UUID):
|
||||
return RecommendedAppService.get_recommend_app_detail(db.session, str(app_id))
|
||||
return RecommendedAppService.get_recommend_app_detail(str(app_id), session=db.session())
|
||||
|
||||
@ -38,11 +38,7 @@ class SavedMessageListApi(InstalledAppResource):
|
||||
args = SavedMessageListQuery.model_validate(request.args.to_dict())
|
||||
|
||||
pagination = SavedMessageService.pagination_by_last_id(
|
||||
db.session(),
|
||||
app_model,
|
||||
current_user,
|
||||
str(args.last_id) if args.last_id else None,
|
||||
args.limit,
|
||||
app_model, current_user, str(args.last_id) if args.last_id else None, args.limit, session=db.session()
|
||||
)
|
||||
adapter = TypeAdapter(SavedMessageItem)
|
||||
items = [adapter.validate_python(message, from_attributes=True) for message in pagination.data]
|
||||
@ -65,7 +61,7 @@ class SavedMessageListApi(InstalledAppResource):
|
||||
payload = SavedMessageCreatePayload.model_validate(console_ns.payload or {})
|
||||
|
||||
try:
|
||||
SavedMessageService.save(db.session(), app_model, current_user, str(payload.message_id))
|
||||
SavedMessageService.save(app_model, current_user, str(payload.message_id), session=db.session())
|
||||
except MessageNotExistsError:
|
||||
raise NotFound("Message Not Exists.")
|
||||
|
||||
@ -88,6 +84,6 @@ class SavedMessageApi(InstalledAppResource):
|
||||
if app_model.mode != "completion":
|
||||
raise NotCompletionAppError()
|
||||
|
||||
SavedMessageService.delete(db.session(), app_model, current_user, message_id_str)
|
||||
SavedMessageService.delete(app_model, current_user, message_id_str, session=db.session())
|
||||
|
||||
return "", 204
|
||||
|
||||
@ -431,7 +431,7 @@ class TrialAppWorkflowRunApi(TrialAppResource):
|
||||
invoke_from=InvokeFrom.EXPLORE,
|
||||
streaming=True,
|
||||
)
|
||||
RecommendedAppService.add_trial_app_record(db.session, app_id, user_id)
|
||||
RecommendedAppService.add_trial_app_record(app_id, user_id, session=session)
|
||||
# response-contract:ignore compact_generate_response
|
||||
return helper.compact_generate_response(response)
|
||||
except ProviderTokenNotInitError as ex:
|
||||
@ -511,7 +511,7 @@ class TrialChatApi(TrialAppResource):
|
||||
invoke_from=InvokeFrom.EXPLORE,
|
||||
streaming=True,
|
||||
)
|
||||
RecommendedAppService.add_trial_app_record(db.session, app_id, user_id)
|
||||
RecommendedAppService.add_trial_app_record(app_id, user_id, session=session)
|
||||
# response-contract:ignore compact_generate_response
|
||||
return helper.compact_generate_response(response)
|
||||
except services.errors.conversation.ConversationNotExistsError:
|
||||
@ -551,7 +551,11 @@ class TrialMessageSuggestedQuestionApi(TrialAppResource):
|
||||
|
||||
try:
|
||||
questions = MessageService.get_suggested_questions_after_answer(
|
||||
app_model=app_model, user=current_user, message_id=message_id, invoke_from=InvokeFrom.EXPLORE
|
||||
app_model=app_model,
|
||||
user=current_user,
|
||||
message_id=message_id,
|
||||
invoke_from=InvokeFrom.EXPLORE,
|
||||
session=db.session(),
|
||||
)
|
||||
except MessageNotExistsError:
|
||||
raise NotFound("Message not found")
|
||||
@ -589,7 +593,7 @@ class TrialChatAudioApi(TrialAppResource):
|
||||
user_id = current_user.id
|
||||
|
||||
response = AudioService.transcript_asr(app_model=app_model, file=file, end_user=None)
|
||||
RecommendedAppService.add_trial_app_record(db.session, app_id, user_id)
|
||||
RecommendedAppService.add_trial_app_record(app_id, user_id, session=db.session())
|
||||
return response
|
||||
except services.errors.app_model_config.AppModelConfigBrokenError:
|
||||
logger.exception("App model config broken.")
|
||||
@ -645,12 +649,12 @@ class TrialChatTextApi(TrialAppResource):
|
||||
|
||||
response = AudioService.transcript_tts(
|
||||
app_model=app_model,
|
||||
session=db.session,
|
||||
session=db.session(),
|
||||
text=text,
|
||||
voice=voice,
|
||||
message_ref=message_ref,
|
||||
)
|
||||
RecommendedAppService.add_trial_app_record(db.session, app_id, user_id)
|
||||
RecommendedAppService.add_trial_app_record(app_id, user_id, session=db.session())
|
||||
return response
|
||||
except services.errors.app_model_config.AppModelConfigBrokenError:
|
||||
logger.exception("App model config broken.")
|
||||
@ -709,7 +713,7 @@ class TrialCompletionApi(TrialAppResource):
|
||||
streaming=streaming,
|
||||
)
|
||||
|
||||
RecommendedAppService.add_trial_app_record(db.session, app_id, user_id)
|
||||
RecommendedAppService.add_trial_app_record(app_id, user_id, session=session)
|
||||
# response-contract:ignore compact_generate_response
|
||||
return helper.compact_generate_response(response)
|
||||
except services.errors.conversation.ConversationNotExistsError:
|
||||
|
||||
@ -112,7 +112,7 @@ class APIBasedExtensionAPI(Resource):
|
||||
def get(self, current_tenant_id: str):
|
||||
return dump_response(
|
||||
APIBasedExtensionListResponse,
|
||||
APIBasedExtensionService.get_all_by_tenant_id(db.session(), current_tenant_id),
|
||||
APIBasedExtensionService.get_all_by_tenant_id(current_tenant_id, session=db.session()),
|
||||
)
|
||||
|
||||
@console_ns.doc("create_api_based_extension")
|
||||
@ -133,7 +133,7 @@ class APIBasedExtensionAPI(Resource):
|
||||
api_key=payload.api_key,
|
||||
)
|
||||
|
||||
extension = APIBasedExtensionService.save(db.session(), extension_data)
|
||||
extension = APIBasedExtensionService.save(extension_data, session=db.session())
|
||||
return APIBasedExtensionResponse(
|
||||
id=extension.id,
|
||||
name=extension.name,
|
||||
@ -158,7 +158,9 @@ class APIBasedExtensionDetailAPI(Resource):
|
||||
|
||||
return dump_response(
|
||||
APIBasedExtensionResponse,
|
||||
APIBasedExtensionService.get_with_tenant_id(db.session(), current_tenant_id, api_based_extension_id),
|
||||
APIBasedExtensionService.get_with_tenant_id(
|
||||
current_tenant_id, api_based_extension_id, session=db.session()
|
||||
),
|
||||
)
|
||||
|
||||
@console_ns.doc("update_api_based_extension")
|
||||
@ -174,7 +176,7 @@ class APIBasedExtensionDetailAPI(Resource):
|
||||
api_based_extension_id = str(id)
|
||||
|
||||
extension_data_from_db = APIBasedExtensionService.get_with_tenant_id(
|
||||
db.session(), current_tenant_id, api_based_extension_id
|
||||
current_tenant_id, api_based_extension_id, session=db.session()
|
||||
)
|
||||
|
||||
payload = APIBasedExtensionPayload.model_validate(console_ns.payload or {})
|
||||
@ -187,7 +189,7 @@ class APIBasedExtensionDetailAPI(Resource):
|
||||
extension_data_from_db.api_key = payload.api_key
|
||||
api_key_for_response = payload.api_key
|
||||
|
||||
APIBasedExtensionService.save(db.session(), extension_data_from_db)
|
||||
APIBasedExtensionService.save(extension_data_from_db, session=db.session())
|
||||
return APIBasedExtensionResponse(
|
||||
id=extension_data_from_db.id,
|
||||
name=extension_data_from_db.name,
|
||||
@ -208,9 +210,9 @@ class APIBasedExtensionDetailAPI(Resource):
|
||||
api_based_extension_id = str(id)
|
||||
|
||||
extension_data_from_db = APIBasedExtensionService.get_with_tenant_id(
|
||||
db.session(), current_tenant_id, api_based_extension_id
|
||||
current_tenant_id, api_based_extension_id, session=db.session()
|
||||
)
|
||||
|
||||
APIBasedExtensionService.delete(db.session(), extension_data_from_db)
|
||||
APIBasedExtensionService.delete(extension_data_from_db, session=db.session())
|
||||
|
||||
return "", 204
|
||||
|
||||
@ -50,7 +50,7 @@ def get_init_status() -> InitStatusResponse:
|
||||
@only_edition_self_hosted
|
||||
def validate_init_password(payload: InitValidatePayload) -> InitValidateResponse:
|
||||
"""Validate initialization password."""
|
||||
tenant_count = TenantService.get_tenant_count(session=db.session)
|
||||
tenant_count = TenantService.get_tenant_count(session=db.session())
|
||||
if tenant_count > 0:
|
||||
raise AlreadySetupError()
|
||||
|
||||
|
||||
@ -79,7 +79,7 @@ def setup_system(payload: SetupRequestPayload) -> SetupResponse:
|
||||
if get_setup_status():
|
||||
raise AlreadySetupError()
|
||||
|
||||
tenant_count = TenantService.get_tenant_count(session=db.session)
|
||||
tenant_count = TenantService.get_tenant_count(session=db.session())
|
||||
if tenant_count > 0:
|
||||
raise AlreadySetupError()
|
||||
|
||||
@ -94,7 +94,7 @@ def setup_system(payload: SetupRequestPayload) -> SetupResponse:
|
||||
password=payload.password,
|
||||
ip_address=extract_remote_ip(request),
|
||||
language=payload.language,
|
||||
session=db.session,
|
||||
session=db.session(),
|
||||
)
|
||||
mark_setup_completed()
|
||||
|
||||
|
||||
@ -44,7 +44,7 @@ def socket_connect(sid, environ, auth):
|
||||
return False
|
||||
|
||||
with sio.app.app_context():
|
||||
user = AccountService.load_logged_in_account(account_id=user_id, session=db.session)
|
||||
user = AccountService.load_logged_in_account(account_id=user_id, session=db.session())
|
||||
if not user:
|
||||
logging.warning("Socket connect rejected: user not found (user_id=%s, sid=%s)", user_id, sid)
|
||||
return False
|
||||
@ -69,7 +69,7 @@ def handle_user_connect(sid, data):
|
||||
if not workflow_id:
|
||||
return {"msg": "workflow_id is required"}, 400
|
||||
|
||||
result = collaboration_service.authorize_and_join_workflow_room(workflow_id, sid)
|
||||
result = collaboration_service.authorize_and_join_workflow_room(workflow_id, sid, session=db.session())
|
||||
if not result:
|
||||
return {"msg": "unauthorized"}, 401
|
||||
|
||||
|
||||
@ -137,7 +137,7 @@ class TagListApi(Resource):
|
||||
def get(self, current_tenant_id: str):
|
||||
raw_args = request.args.to_dict()
|
||||
param = TagListQueryParam.model_validate(raw_args)
|
||||
tags = TagService.get_tags(db.session(), param.type, current_tenant_id, param.keyword)
|
||||
tags = TagService.get_tags(param.type, current_tenant_id, param.keyword, session=db.session())
|
||||
|
||||
return dump_response(TagListResponse, tags), 200
|
||||
|
||||
@ -154,7 +154,7 @@ class TagListApi(Resource):
|
||||
|
||||
payload = TagBasePayload.model_validate(console_ns.payload or {})
|
||||
_enforce_snippet_tag_rbac_if_needed(payload.type)
|
||||
tag = TagService.save_tags(SaveTagPayload(name=payload.name, type=payload.type), db.session)
|
||||
tag = TagService.save_tags(SaveTagPayload(name=payload.name, type=payload.type), db.session())
|
||||
|
||||
return dump_response(TagResponse, {"id": tag.id, "name": tag.name, "type": tag.type, "binding_count": 0}), 200
|
||||
|
||||
@ -175,9 +175,9 @@ class TagUpdateDeleteApi(Resource):
|
||||
|
||||
payload = TagUpdateRequestPayload.model_validate(console_ns.payload or {})
|
||||
_enforce_snippet_tag_rbac_by_tag_id(tag_id_str)
|
||||
tag = TagService.update_tags(UpdateTagPayload(name=payload.name), tag_id_str, db.session)
|
||||
tag = TagService.update_tags(UpdateTagPayload(name=payload.name), tag_id_str, db.session())
|
||||
|
||||
binding_count = TagService.get_tag_binding_count(tag_id_str, db.session)
|
||||
binding_count = TagService.get_tag_binding_count(tag_id_str, db.session())
|
||||
|
||||
return (
|
||||
dump_response(
|
||||
@ -196,7 +196,7 @@ class TagUpdateDeleteApi(Resource):
|
||||
tag_id_str = str(tag_id)
|
||||
|
||||
_enforce_snippet_tag_rbac_by_tag_id(tag_id_str)
|
||||
TagService.delete_tag(tag_id_str, db.session)
|
||||
TagService.delete_tag(tag_id_str, db.session())
|
||||
|
||||
return "", 204
|
||||
|
||||
@ -223,7 +223,7 @@ def _create_tag_bindings(current_user: Account) -> tuple[dict[str, str], int]:
|
||||
target_id=payload.target_id,
|
||||
type=payload.type,
|
||||
),
|
||||
db.session,
|
||||
db.session(),
|
||||
)
|
||||
return {"result": "success"}, 200
|
||||
|
||||
@ -239,7 +239,7 @@ def _remove_tag_bindings(current_user: Account) -> tuple[dict[str, str], int]:
|
||||
target_id=payload.target_id,
|
||||
type=payload.type,
|
||||
),
|
||||
db.session,
|
||||
db.session(),
|
||||
)
|
||||
return {"result": "success"}, 200
|
||||
|
||||
|
||||
@ -317,7 +317,7 @@ class AccountNameApi(Resource):
|
||||
def post(self, current_user: Account):
|
||||
payload = console_ns.payload or {}
|
||||
args = AccountNamePayload.model_validate(payload)
|
||||
updated_account = AccountService.update_account(current_user, session=db.session, name=args.name)
|
||||
updated_account = AccountService.update_account(current_user, session=db.session(), name=args.name)
|
||||
|
||||
return dump_response(AccountResponse, updated_account)
|
||||
|
||||
@ -363,7 +363,7 @@ class AccountAvatarApi(Resource):
|
||||
payload = console_ns.payload or {}
|
||||
args = AccountAvatarPayload.model_validate(payload)
|
||||
|
||||
updated_account = AccountService.update_account(current_user, session=db.session, avatar=args.avatar)
|
||||
updated_account = AccountService.update_account(current_user, session=db.session(), avatar=args.avatar)
|
||||
|
||||
return dump_response(AccountResponse, updated_account)
|
||||
|
||||
@ -381,7 +381,7 @@ class AccountInterfaceLanguageApi(Resource):
|
||||
args = AccountInterfaceLanguagePayload.model_validate(payload)
|
||||
|
||||
updated_account = AccountService.update_account(
|
||||
current_user, session=db.session, interface_language=args.interface_language
|
||||
current_user, session=db.session(), interface_language=args.interface_language
|
||||
)
|
||||
|
||||
return dump_response(AccountResponse, updated_account)
|
||||
@ -400,7 +400,7 @@ class AccountInterfaceThemeApi(Resource):
|
||||
args = AccountInterfaceThemePayload.model_validate(payload)
|
||||
|
||||
updated_account = AccountService.update_account(
|
||||
current_user, session=db.session, interface_theme=args.interface_theme
|
||||
current_user, session=db.session(), interface_theme=args.interface_theme
|
||||
)
|
||||
|
||||
return dump_response(AccountResponse, updated_account)
|
||||
@ -418,7 +418,7 @@ class AccountTimezoneApi(Resource):
|
||||
payload = console_ns.payload or {}
|
||||
args = AccountTimezonePayload.model_validate(payload)
|
||||
|
||||
updated_account = AccountService.update_account(current_user, session=db.session, timezone=args.timezone)
|
||||
updated_account = AccountService.update_account(current_user, session=db.session(), timezone=args.timezone)
|
||||
|
||||
return dump_response(AccountResponse, updated_account)
|
||||
|
||||
@ -437,7 +437,7 @@ class AccountPasswordApi(Resource):
|
||||
|
||||
try:
|
||||
assert args.password is not None
|
||||
AccountService.update_account_password(current_user, args.password, args.new_password, session=db.session)
|
||||
AccountService.update_account_password(current_user, args.password, args.new_password, session=db.session())
|
||||
except ServiceCurrentPasswordIncorrectError:
|
||||
raise CurrentPasswordIncorrectError()
|
||||
|
||||
@ -514,7 +514,7 @@ class AccountDeleteApi(Resource):
|
||||
if not AccountService.verify_account_deletion_code(args.token, args.code):
|
||||
raise InvalidAccountDeletionCodeError()
|
||||
|
||||
AccountService.delete_account(account)
|
||||
AccountService.delete_account(account, session=db.session())
|
||||
|
||||
return SimpleResultResponse(result="success").model_dump(mode="json")
|
||||
|
||||
@ -726,7 +726,7 @@ class ChangeEmailResetApi(Resource):
|
||||
if AccountService.is_account_in_freeze(normalized_new_email):
|
||||
raise AccountInFreezeError()
|
||||
|
||||
if not AccountService.check_email_unique(normalized_new_email, session=db.session):
|
||||
if not AccountService.check_email_unique(normalized_new_email, session=db.session()):
|
||||
raise EmailAlreadyInUseError()
|
||||
|
||||
reset_data = AccountService.get_change_email_data(args.token)
|
||||
@ -751,7 +751,7 @@ class ChangeEmailResetApi(Resource):
|
||||
AccountService.revoke_change_email_token(args.token)
|
||||
|
||||
updated_account = AccountService.update_account_email(
|
||||
current_user, email=normalized_new_email, session=db.session
|
||||
current_user, email=normalized_new_email, session=db.session()
|
||||
)
|
||||
|
||||
AccountService.send_change_email_completed_notify_email(
|
||||
@ -772,6 +772,6 @@ class CheckEmailUnique(Resource):
|
||||
normalized_email = args.email.lower()
|
||||
if AccountService.is_account_in_freeze(normalized_email):
|
||||
raise AccountInFreezeError()
|
||||
if not AccountService.check_email_unique(normalized_email, session=db.session):
|
||||
if not AccountService.check_email_unique(normalized_email, session=db.session()):
|
||||
raise EmailAlreadyInUseError()
|
||||
return SimpleResultResponse(result="success").model_dump(mode="json")
|
||||
|
||||
@ -10,6 +10,7 @@ from controllers.console.wraps import (
|
||||
with_current_tenant_id,
|
||||
with_current_user,
|
||||
)
|
||||
from extensions.ext_database import db
|
||||
from fields.base import ResponseModel
|
||||
from graphon.model_runtime.entities.model_entities import ModelType
|
||||
from graphon.model_runtime.errors.validate import CredentialsValidateFailedError
|
||||
@ -69,6 +70,7 @@ class LoadBalancingCredentialsValidateApi(Resource):
|
||||
model=payload.model,
|
||||
model_type=payload.model_type,
|
||||
credentials=payload.credentials,
|
||||
session=db.session(),
|
||||
)
|
||||
except CredentialsValidateFailedError as ex:
|
||||
result = False
|
||||
@ -118,6 +120,7 @@ class LoadBalancingConfigCredentialsValidateApi(Resource):
|
||||
model=payload.model,
|
||||
model_type=payload.model_type,
|
||||
credentials=payload.credentials,
|
||||
session=db.session(),
|
||||
config_id=config_id,
|
||||
)
|
||||
except CredentialsValidateFailedError as ex:
|
||||
|
||||
@ -135,7 +135,7 @@ def _normalize_enum_value(value: object) -> str:
|
||||
def _count_new_member_invites(tenant_id: str, emails: list[str]) -> int:
|
||||
new_member_count = 0
|
||||
for email in emails:
|
||||
account = AccountService.get_account_by_email_with_case_fallback(db.session, email)
|
||||
account = AccountService.get_account_by_email_with_case_fallback(email, session=db.session())
|
||||
if not account:
|
||||
new_member_count += 1
|
||||
continue
|
||||
@ -190,7 +190,7 @@ class MemberListApi(Resource):
|
||||
current_user, _ = current_account_with_tenant()
|
||||
if not current_user.current_tenant:
|
||||
raise ValueError("No current tenant")
|
||||
members = TenantService.get_tenant_members(current_user.current_tenant, session=db.session)
|
||||
members = TenantService.get_tenant_members(current_user.current_tenant, session=db.session())
|
||||
if dify_config.RBAC_ENABLED:
|
||||
member_ids = [member.id for member in members]
|
||||
member_roles = enterprise_rbac_service.RBACService.MemberRoles.batch_get(
|
||||
@ -275,7 +275,7 @@ class MemberInviteEmailApi(Resource):
|
||||
language=interface_language,
|
||||
role=invitee_role,
|
||||
inviter=inviter,
|
||||
session=db.session,
|
||||
session=db.session(),
|
||||
)
|
||||
encoded_invitee_email = parse.quote(invitee_email)
|
||||
invitation_results.append(
|
||||
@ -323,7 +323,7 @@ class MemberCancelInviteApi(Resource):
|
||||
else:
|
||||
try:
|
||||
TenantService.remove_member_from_tenant(
|
||||
current_user.current_tenant, member, current_user, session=db.session
|
||||
current_user.current_tenant, member, current_user, session=db.session()
|
||||
)
|
||||
except services.errors.account.CannotOperateSelfError as e:
|
||||
return {"code": "cannot-operate-self", "message": str(e)}, HTTPStatus.BAD_REQUEST
|
||||
@ -368,7 +368,7 @@ class MemberUpdateRoleApi(Resource):
|
||||
try:
|
||||
assert member is not None, "Member not found"
|
||||
TenantService.update_member_role(
|
||||
current_user.current_tenant, member, new_role, current_user, session=db.session
|
||||
current_user.current_tenant, member, new_role, current_user, session=db.session()
|
||||
)
|
||||
except services.errors.account.CannotOperateSelfError as e:
|
||||
return {"code": "cannot-operate-self", "message": str(e)}, HTTPStatus.BAD_REQUEST
|
||||
@ -396,7 +396,7 @@ class DatasetOperatorMemberListApi(Resource):
|
||||
def get(self, current_user: Account):
|
||||
if not current_user.current_tenant:
|
||||
raise ValueError("No current tenant")
|
||||
members = TenantService.get_dataset_operator_members(current_user.current_tenant, session=db.session)
|
||||
members = TenantService.get_dataset_operator_members(current_user.current_tenant, session=db.session())
|
||||
return dump_response(AccountWithRoleListResponse, {"accounts": members}), HTTPStatus.OK
|
||||
|
||||
|
||||
@ -420,7 +420,7 @@ class SendOwnerTransferEmailApi(Resource):
|
||||
# check if the current user is the owner of the workspace
|
||||
if not current_user.current_tenant:
|
||||
raise ValueError("No current tenant")
|
||||
if not TenantService.is_owner(current_user, current_user.current_tenant, session=db.session):
|
||||
if not TenantService.is_owner(current_user, current_user.current_tenant, session=db.session()):
|
||||
raise NotOwnerError()
|
||||
|
||||
if args.language is not None and args.language == "zh-Hans":
|
||||
@ -455,7 +455,7 @@ class OwnerTransferCheckApi(Resource):
|
||||
# check if the current user is the owner of the workspace
|
||||
if not current_user.current_tenant:
|
||||
raise ValueError("No current tenant")
|
||||
if not TenantService.is_owner(current_user, current_user.current_tenant, session=db.session):
|
||||
if not TenantService.is_owner(current_user, current_user.current_tenant, session=db.session()):
|
||||
raise NotOwnerError()
|
||||
|
||||
user_email = current_user.email
|
||||
@ -501,7 +501,7 @@ class OwnerTransfer(Resource):
|
||||
# check if the current user is the owner of the workspace
|
||||
if not current_user.current_tenant:
|
||||
raise ValueError("No current tenant")
|
||||
if not TenantService.is_owner(current_user, current_user.current_tenant, session=db.session):
|
||||
if not TenantService.is_owner(current_user, current_user.current_tenant, session=db.session()):
|
||||
raise NotOwnerError()
|
||||
|
||||
if current_user.id == str(member_id):
|
||||
@ -522,13 +522,13 @@ class OwnerTransfer(Resource):
|
||||
|
||||
if not current_user.current_tenant:
|
||||
raise ValueError("No current tenant")
|
||||
if not TenantService.is_member(member, current_user.current_tenant, session=db.session):
|
||||
if not TenantService.is_member(member, current_user.current_tenant, session=db.session()):
|
||||
raise MemberNotInTenantError()
|
||||
|
||||
try:
|
||||
assert member is not None, "Member not found"
|
||||
TenantService.update_member_role(
|
||||
current_user.current_tenant, member, "owner", current_user, session=db.session
|
||||
current_user.current_tenant, member, "owner", current_user, session=db.session()
|
||||
)
|
||||
|
||||
AccountService.send_new_owner_transfer_notify_email(
|
||||
|
||||
@ -353,7 +353,7 @@ class ModelProviderPaymentCheckoutUrlApi(Resource):
|
||||
def get(self, current_tenant_id: str, current_user: Account, provider: str):
|
||||
if provider != "anthropic":
|
||||
raise ValueError(f"provider name {provider} is invalid")
|
||||
BillingService.is_tenant_owner_or_admin(db.session, current_user)
|
||||
BillingService.is_tenant_owner_or_admin(current_user, session=db.session())
|
||||
data = BillingService.get_model_provider_payment_link(
|
||||
provider_name=provider,
|
||||
tenant_id=current_tenant_id,
|
||||
|
||||
@ -24,6 +24,7 @@ from controllers.console.wraps import (
|
||||
with_current_user,
|
||||
)
|
||||
from core.entities.provider_entities import CredentialConfiguration
|
||||
from extensions.ext_database import db
|
||||
from fields.base import ResponseModel
|
||||
from graphon.model_runtime.entities.model_entities import ModelType, ParameterRule
|
||||
from graphon.model_runtime.errors.validate import CredentialsValidateFailedError
|
||||
@ -297,6 +298,7 @@ class ModelProviderModelApi(Resource):
|
||||
model_type=args.model_type,
|
||||
configs=args.load_balancing.configs,
|
||||
config_from=args.config_from or "",
|
||||
session=db.session(),
|
||||
)
|
||||
|
||||
if args.load_balancing.enabled:
|
||||
@ -356,6 +358,7 @@ class ModelProviderModelCredentialApi(Resource):
|
||||
provider=provider,
|
||||
model=args.model,
|
||||
model_type=args.model_type,
|
||||
session=db.session(),
|
||||
config_from=args.config_from or "",
|
||||
)
|
||||
|
||||
|
||||
@ -38,6 +38,7 @@ from core.tools.builtin_tool.providers._positions import BuiltinToolProviderSort
|
||||
from core.tools.entities.common_entities import I18nObject
|
||||
from core.tools.entities.tool_entities import ToolProviderType
|
||||
from core.tools.tool_manager import ToolManager
|
||||
from extensions.ext_database import db
|
||||
from fields.base import ResponseModel
|
||||
from graphon.model_runtime.utils.encoders import jsonable_encoder
|
||||
from libs.helper import dump_response
|
||||
@ -973,7 +974,7 @@ class PluginChangePermissionApi(Resource):
|
||||
args = ParserPermissionChange.model_validate(console_ns.payload)
|
||||
|
||||
set_permission_result = PluginPermissionService.change_permission(
|
||||
tenant_id, args.install_permission, args.debug_permission
|
||||
tenant_id, args.install_permission, args.debug_permission, session=db.session()
|
||||
)
|
||||
if not set_permission_result:
|
||||
return jsonable_encoder({"success": False, "message": "Failed to set permission"})
|
||||
@ -989,7 +990,7 @@ class PluginFetchPermissionApi(Resource):
|
||||
@account_initialization_required
|
||||
@with_current_tenant_id
|
||||
def get(self, tenant_id: str):
|
||||
permission = PluginPermissionService.get_permission(tenant_id)
|
||||
permission = PluginPermissionService.get_permission(tenant_id, session=db.session())
|
||||
if not permission:
|
||||
return jsonable_encoder(
|
||||
{
|
||||
@ -1094,6 +1095,7 @@ class PluginChangeAutoUpgradeApi(Resource):
|
||||
auto_upgrade.exclude_plugins,
|
||||
auto_upgrade.include_plugins,
|
||||
category=args.category,
|
||||
session=db.session(),
|
||||
)
|
||||
if not set_auto_upgrade_strategy_result:
|
||||
return jsonable_encoder({"success": False, "message": "Failed to set auto upgrade strategy"})
|
||||
@ -1111,7 +1113,7 @@ class PluginFetchAutoUpgradeApi(Resource):
|
||||
@with_current_tenant_id
|
||||
def get(self, tenant_id: str):
|
||||
args = ParserAutoUpgradeFetch.model_validate(request.args.to_dict(flat=True))
|
||||
auto_upgrade = PluginAutoUpgradeService.get_strategy(tenant_id, args.category)
|
||||
auto_upgrade = PluginAutoUpgradeService.get_strategy(tenant_id, args.category, session=db.session())
|
||||
auto_upgrade_dict = (
|
||||
_auto_upgrade_settings_to_dict(auto_upgrade)
|
||||
if auto_upgrade
|
||||
@ -1140,7 +1142,11 @@ class PluginAutoUpgradeExcludePluginApi(Resource):
|
||||
args = ParserExcludePlugin.model_validate(console_ns.payload)
|
||||
|
||||
return jsonable_encoder(
|
||||
{"success": PluginAutoUpgradeService.exclude_plugin(tenant_id, args.plugin_id, args.category)}
|
||||
{
|
||||
"success": PluginAutoUpgradeService.exclude_plugin(
|
||||
tenant_id, args.plugin_id, args.category, session=db.session()
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
|
||||
@ -14,6 +14,7 @@ from controllers.console import console_ns
|
||||
from controllers.console.wraps import RBACPermission, RBACResourceScope, rbac_permission_required
|
||||
from core.db.session_factory import session_factory
|
||||
from core.rbac import RBACResourceWhitelistScope
|
||||
from extensions.ext_database import db
|
||||
from libs.login import current_account_with_tenant, login_required
|
||||
from models import Account
|
||||
from services.enterprise import rbac_service as svc
|
||||
@ -564,6 +565,7 @@ class RBACMyPermissionsApi(Resource):
|
||||
account_id,
|
||||
app_id=request.args.get("app_id") or None,
|
||||
dataset_id=request.args.get("dataset_id") or None,
|
||||
session=db.session(),
|
||||
)
|
||||
)
|
||||
|
||||
@ -902,7 +904,7 @@ class RBACMemberRolesApi(Resource):
|
||||
@console_ns.response(200, "Success", console_ns.models[svc.MemberRolesResponse.__name__])
|
||||
def get(self, member_id):
|
||||
tenant_id, account_id = _current_ids()
|
||||
return _dump(svc.RBACService.MemberRoles.get(tenant_id, account_id, str(member_id)))
|
||||
return _dump(svc.RBACService.MemberRoles.get(tenant_id, account_id, str(member_id), session=db.session()))
|
||||
|
||||
@login_required
|
||||
@console_ns.expect(console_ns.models[_ReplaceMemberRolesRequest.__name__])
|
||||
@ -916,6 +918,7 @@ class RBACMemberRolesApi(Resource):
|
||||
account_id,
|
||||
str(member_id),
|
||||
role_ids=list(request.role_ids),
|
||||
session=db.session(),
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@ -188,7 +188,7 @@ class CustomizedSnippetsApi(Resource):
|
||||
snippet_service = _snippet_service()
|
||||
snippets, total, has_more = snippet_service.get_snippets(
|
||||
tenant_id=current_tenant_id,
|
||||
session=db.session,
|
||||
session=db.session(),
|
||||
page=query.page,
|
||||
limit=query.limit,
|
||||
keyword=query.keyword,
|
||||
|
||||
@ -459,6 +459,7 @@ class ToolBuiltinProviderGetCredentialsApi(Resource):
|
||||
BuiltinToolManageService.get_builtin_tool_provider_credentials(
|
||||
tenant_id=tenant_id,
|
||||
provider_name=provider,
|
||||
session=db.session(),
|
||||
user=user,
|
||||
include_credential_ids=query.include_credential_ids or None,
|
||||
)
|
||||
@ -1064,6 +1065,7 @@ class ToolBuiltinProviderGetCredentialInfoApi(Resource):
|
||||
BuiltinToolManageService.get_builtin_tool_provider_credential_info(
|
||||
tenant_id=tenant_id,
|
||||
provider=provider,
|
||||
session=db.session(),
|
||||
user=user,
|
||||
include_credential_ids=query.include_credential_ids or None,
|
||||
)
|
||||
|
||||
@ -223,7 +223,7 @@ class TenantListApi(Resource):
|
||||
def get(self, current_tenant_id: str, current_user: Account):
|
||||
tenant_rows: list[tuple[Tenant, TenantAccountJoin]] = [
|
||||
(tenant, membership)
|
||||
for tenant, membership in TenantService.get_workspaces_for_account(db.session, current_user.id)
|
||||
for tenant, membership in TenantService.get_workspaces_for_account(current_user.id, session=db.session())
|
||||
if tenant.status == TenantStatus.NORMAL
|
||||
]
|
||||
tenants = [tenant for tenant, _ in tenant_rows]
|
||||
@ -306,16 +306,19 @@ class TenantApi(Resource):
|
||||
raise ValueError("No current tenant")
|
||||
|
||||
if tenant.status == TenantStatus.ARCHIVE:
|
||||
tenants = TenantService.get_join_tenants(current_user, session=db.session)
|
||||
tenants = TenantService.get_join_tenants(current_user, session=db.session())
|
||||
# if there is any tenant, switch to the first one
|
||||
if len(tenants) > 0:
|
||||
TenantService.switch_tenant(current_user, tenants[0].id, session=db.session)
|
||||
TenantService.switch_tenant(current_user, tenants[0].id, session=db.session())
|
||||
tenant = tenants[0]
|
||||
# else, raise Unauthorized
|
||||
else:
|
||||
raise Unauthorized("workspace is archived")
|
||||
|
||||
return dump_response(TenantInfoResponse, WorkspaceService.get_tenant_info(tenant)), HTTPStatus.OK
|
||||
return (
|
||||
dump_response(TenantInfoResponse, WorkspaceService.get_tenant_info(tenant, session=db.session())),
|
||||
HTTPStatus.OK,
|
||||
)
|
||||
|
||||
|
||||
@console_ns.route("/workspaces/switch")
|
||||
@ -332,7 +335,7 @@ class SwitchWorkspaceApi(Resource):
|
||||
|
||||
# Check whether the tenant_id belongs to the current account.
|
||||
try:
|
||||
TenantService.switch_tenant(current_user, args.tenant_id, session=db.session)
|
||||
TenantService.switch_tenant(current_user, args.tenant_id, session=db.session())
|
||||
except Exception:
|
||||
raise AccountNotLinkTenantError("Account not link tenant")
|
||||
|
||||
@ -341,7 +344,7 @@ class SwitchWorkspaceApi(Resource):
|
||||
raise ValueError("Tenant not found")
|
||||
|
||||
return SwitchWorkspaceResponse(
|
||||
result="success", new_tenant=WorkspaceService.get_tenant_info(new_tenant)
|
||||
result="success", new_tenant=WorkspaceService.get_tenant_info(new_tenant, session=db.session())
|
||||
).model_dump(mode="json")
|
||||
|
||||
|
||||
@ -372,7 +375,7 @@ class CustomConfigWorkspaceApi(Resource):
|
||||
db.session.commit()
|
||||
|
||||
return WorkspaceTenantResultResponse(
|
||||
result="success", tenant=WorkspaceService.get_tenant_info(tenant)
|
||||
result="success", tenant=WorkspaceService.get_tenant_info(tenant, session=db.session())
|
||||
).model_dump(mode="json")
|
||||
|
||||
|
||||
@ -438,7 +441,7 @@ class WorkspaceInfoApi(Resource):
|
||||
db.session.commit()
|
||||
|
||||
return WorkspaceTenantResultResponse(
|
||||
result="success", tenant=WorkspaceService.get_tenant_info(tenant)
|
||||
result="success", tenant=WorkspaceService.get_tenant_info(tenant, session=db.session())
|
||||
).model_dump(mode="json")
|
||||
|
||||
|
||||
|
||||
@ -8,6 +8,7 @@ from werkzeug.exceptions import Forbidden, NotFound
|
||||
from controllers.common.file_response import enforce_download_for_html
|
||||
from controllers.common.schema import register_schema_models
|
||||
from controllers.files import files_ns
|
||||
from extensions.ext_database import db
|
||||
from models.agent import AgentDriveFileKind
|
||||
from services.agent_drive_service import AgentDriveError, AgentDriveService
|
||||
|
||||
@ -54,6 +55,7 @@ class AgentDriveArchiveMemberApi(Resource):
|
||||
archive_file_kind=args.archive_file_kind,
|
||||
archive_file_id=args.archive_file_id,
|
||||
member_path=args.member_path,
|
||||
session=db.session(),
|
||||
)
|
||||
except AgentDriveError as exc:
|
||||
raise NotFound(exc.message) from exc
|
||||
|
||||
@ -98,6 +98,7 @@ class EnterpriseAppDSLExport(Resource):
|
||||
|
||||
data = AppDslService.export_dsl(
|
||||
app_model=app_model,
|
||||
session=db.session(),
|
||||
include_secret=include_secret,
|
||||
)
|
||||
|
||||
|
||||
@ -17,6 +17,7 @@ from controllers.console.wraps import setup_required
|
||||
from controllers.inner_api import inner_api_ns
|
||||
from controllers.inner_api.plugin.wraps import get_user
|
||||
from controllers.inner_api.wraps import plugin_inner_api_only
|
||||
from extensions.ext_database import db
|
||||
from services.agent_drive_service import (
|
||||
AgentDriveError,
|
||||
AgentDriveService,
|
||||
@ -53,6 +54,7 @@ class AgentDriveManifestApi(Resource):
|
||||
agent_id=agent_id,
|
||||
prefix=request.args.get("prefix", ""),
|
||||
include_download_url=include_download_url,
|
||||
session=db.session(),
|
||||
)
|
||||
except AgentDriveError as exc:
|
||||
return _error_response(exc)
|
||||
@ -71,7 +73,7 @@ class AgentDriveSkillsApi(Resource):
|
||||
tenant_id = (request.args.get("tenant_id") or "").strip()
|
||||
if not tenant_id:
|
||||
raise AgentDriveError("missing_tenant_id", "tenant_id is required", status_code=400)
|
||||
items = AgentDriveService().list_skills(tenant_id=tenant_id, agent_id=agent_id)
|
||||
items = AgentDriveService().list_skills(tenant_id=tenant_id, agent_id=agent_id, session=db.session())
|
||||
except AgentDriveError as exc:
|
||||
return _error_response(exc)
|
||||
return {"items": items}
|
||||
@ -96,6 +98,7 @@ class AgentDriveCommitApi(Resource):
|
||||
user_id=user.id,
|
||||
agent_id=agent_id,
|
||||
items=body.items,
|
||||
session=db.session(),
|
||||
)
|
||||
except AgentDriveError as exc:
|
||||
return _error_response(exc)
|
||||
|
||||
@ -47,8 +47,8 @@ class EnterpriseWorkspace(Resource):
|
||||
if account is None:
|
||||
return {"message": "owner account not found."}, 404
|
||||
|
||||
tenant = TenantService.create_tenant(args.name, is_from_dashboard=True, session=db.session)
|
||||
TenantService.create_tenant_member(tenant, account, db.session, role="owner")
|
||||
tenant = TenantService.create_tenant(args.name, is_from_dashboard=True, session=db.session())
|
||||
TenantService.create_tenant_member(tenant, account, db.session(), role="owner")
|
||||
|
||||
tenant_was_created.send(tenant)
|
||||
|
||||
@ -84,7 +84,7 @@ class EnterpriseWorkspaceNoOwnerEmail(Resource):
|
||||
def post(self):
|
||||
args = WorkspaceOwnerlessPayload.model_validate(inner_api_ns.payload or {})
|
||||
|
||||
tenant = TenantService.create_tenant(args.name, is_from_dashboard=True, session=db.session)
|
||||
tenant = TenantService.create_tenant(args.name, is_from_dashboard=True, session=db.session())
|
||||
|
||||
tenant_was_created.send(tenant)
|
||||
|
||||
|
||||
@ -45,8 +45,10 @@ class AccountApi(Resource):
|
||||
enforce(LIMIT_ME_PER_ACCOUNT, key=f"account:{auth_data.account_id}")
|
||||
|
||||
account_id_str = str(auth_data.account_id) if auth_data.account_id else None
|
||||
account = AccountService.get_account_by_id(db.session, account_id_str) if account_id_str else None
|
||||
memberships = TenantService.get_account_memberships(db.session, account_id_str) if account_id_str else []
|
||||
account = AccountService.get_account_by_id(account_id_str, session=db.session()) if account_id_str else None
|
||||
memberships = (
|
||||
TenantService.get_account_memberships(account_id_str, session=db.session()) if account_id_str else []
|
||||
)
|
||||
default_ws_id = _pick_default_workspace(memberships)
|
||||
|
||||
return AccountResponse(
|
||||
@ -63,7 +65,7 @@ class AccountSessionsSelfApi(Resource):
|
||||
@auth_router.guard(scope=Scope.FULL, allowed_token_types=frozenset({TokenType.OAUTH_ACCOUNT}))
|
||||
@returns(200, RevokeResponse, description="Session revoked")
|
||||
def delete(self, *, auth_data: AuthData):
|
||||
revoke_oauth_token(db.session, redis_client, str(auth_data.token_id))
|
||||
revoke_oauth_token(redis_client, str(auth_data.token_id), session=db.session())
|
||||
return RevokeResponse(status="revoked")
|
||||
|
||||
|
||||
@ -81,7 +83,7 @@ class AccountSessionsApi(Resource):
|
||||
page = query.page
|
||||
limit = query.limit
|
||||
|
||||
all_rows = list_active_sessions(db.session, ctx, now)
|
||||
all_rows = list_active_sessions(ctx, now, session=db.session())
|
||||
|
||||
total = len(all_rows)
|
||||
sliced = all_rows[(page - 1) * limit : page * limit]
|
||||
@ -117,10 +119,10 @@ class AccountSessionByIdApi(Resource):
|
||||
|
||||
# 404 (not 403) on cross-subject so the endpoint doesn't leak
|
||||
# token IDs that belong to other subjects.
|
||||
if not token_belongs_to_subject(db.session, session_id, ctx):
|
||||
if not token_belongs_to_subject(session_id, ctx, session=db.session()):
|
||||
raise NotFound("session not found")
|
||||
|
||||
revoke_oauth_token(db.session, redis_client, session_id)
|
||||
revoke_oauth_token(redis_client, session_id, session=db.session())
|
||||
return RevokeResponse(status="revoked")
|
||||
|
||||
|
||||
|
||||
@ -145,6 +145,7 @@ class AppDslExportApi(Resource):
|
||||
try:
|
||||
data = AppDslService.export_dsl(
|
||||
app_model=app,
|
||||
session=db.session(),
|
||||
include_secret=query.include_secret,
|
||||
workflow_id=query.workflow_id,
|
||||
)
|
||||
|
||||
@ -66,13 +66,13 @@ class AppReadResource(Resource):
|
||||
|
||||
if is_uuid:
|
||||
# ``str(parsed_uuid)`` normalises to the canonical dashed form.
|
||||
app = AppService.get_visible_app_by_id(db.session, str(parsed_uuid))
|
||||
app = AppService.get_visible_app_by_id(str(parsed_uuid), session=db.session())
|
||||
if app is None:
|
||||
raise NotFound("app not found")
|
||||
else:
|
||||
if not workspace_id:
|
||||
raise UnprocessableEntity("workspace_id is required for name-based lookup")
|
||||
matches = AppService.find_visible_apps_by_name(db.session, name=app_id, tenant_id=workspace_id)
|
||||
matches = AppService.find_visible_apps_by_name(name=app_id, tenant_id=workspace_id, session=db.session())
|
||||
if len(matches) == 0:
|
||||
raise NotFound("app not found")
|
||||
if len(matches) > 1:
|
||||
@ -177,7 +177,7 @@ class AppListApi(Resource):
|
||||
|
||||
tenant_name: str | None = None
|
||||
if parsed_uuid is not None:
|
||||
app: App | None = AppService.get_visible_app_by_id(db.session, str(parsed_uuid))
|
||||
app: App | None = AppService.get_visible_app_by_id(str(parsed_uuid), session=db.session())
|
||||
if app is None or str(app.tenant_id) != workspace_id:
|
||||
return empty
|
||||
if not _is_listable(app):
|
||||
@ -188,7 +188,7 @@ class AppListApi(Resource):
|
||||
str(app.id), str(app.maintainer) if app.maintainer else None, str(auth_data.account_id)
|
||||
):
|
||||
return empty
|
||||
tenant_name = TenantService.get_tenant_name(db.session, workspace_id)
|
||||
tenant_name = TenantService.get_tenant_name(workspace_id, session=db.session())
|
||||
item = AppListRow(
|
||||
id=str(app.id),
|
||||
name=app.name,
|
||||
@ -215,13 +215,13 @@ class AppListApi(Resource):
|
||||
if apply_rbac_filter:
|
||||
access_filter.apply_to_params(params)
|
||||
|
||||
pagination = AppService().get_paginate_apps(str(auth_data.account_id), workspace_id, params, db.session)
|
||||
pagination = AppService().get_paginate_apps(str(auth_data.account_id), workspace_id, params, db.session())
|
||||
if pagination is None:
|
||||
return empty
|
||||
|
||||
tenant_name = None
|
||||
if pagination.items:
|
||||
tenant_name = TenantService.get_tenant_name(db.session, workspace_id)
|
||||
tenant_name = TenantService.get_tenant_name(workspace_id, session=db.session())
|
||||
|
||||
items = [
|
||||
AppListRow(
|
||||
|
||||
@ -55,10 +55,10 @@ class PermittedExternalAppsListApi(Resource):
|
||||
return env
|
||||
|
||||
apps_by_id: dict[str, App] = {
|
||||
str(a.id): a for a in AppService.find_visible_apps_by_ids(db.session, page_result.app_ids)
|
||||
str(a.id): a for a in AppService.find_visible_apps_by_ids(page_result.app_ids, session=db.session())
|
||||
}
|
||||
tenant_ids = list({str(a.tenant_id) for a in apps_by_id.values()})
|
||||
tenants_by_id = {str(t.id): t for t in TenantService.get_tenants_by_ids(db.session, tenant_ids)}
|
||||
tenants_by_id = {str(t.id): t for t in TenantService.get_tenants_by_ids(tenant_ids, session=db.session())}
|
||||
|
||||
items: list[AppListRow] = []
|
||||
for app_id in page_result.app_ids:
|
||||
|
||||
@ -23,7 +23,7 @@ def load_app(data: AuthData) -> None:
|
||||
uuid.UUID(app_id)
|
||||
except ValueError:
|
||||
raise NotFound("app not found")
|
||||
app = AppService.get_app_by_id(db.session, app_id)
|
||||
app = AppService.get_app_by_id(app_id, session=db.session())
|
||||
if not app or app.status != AppStatus.NORMAL:
|
||||
raise NotFound("app not found")
|
||||
data.app = app
|
||||
@ -34,7 +34,7 @@ def load_tenant(data: AuthData) -> None:
|
||||
return
|
||||
if data.app is None:
|
||||
raise InternalServerError("pipeline_invariant_violated: app not loaded before load_tenant")
|
||||
tenant = TenantService.get_tenant_by_id(db.session, str(data.app.tenant_id))
|
||||
tenant = TenantService.get_tenant_by_id(str(data.app.tenant_id), session=db.session())
|
||||
if tenant is None or tenant.status == TenantStatus.ARCHIVE:
|
||||
raise Forbidden("workspace unavailable")
|
||||
data.tenant = tenant
|
||||
@ -50,7 +50,7 @@ def load_tenant_from_request(data: AuthData) -> None:
|
||||
uuid.UUID(workspace_id)
|
||||
except ValueError:
|
||||
raise NotFound("workspace not found")
|
||||
tenant = TenantService.get_tenant_by_id(db.session, workspace_id)
|
||||
tenant = TenantService.get_tenant_by_id(workspace_id, session=db.session())
|
||||
if tenant is None or tenant.status == TenantStatus.ARCHIVE:
|
||||
raise NotFound("workspace not found")
|
||||
data.tenant = tenant
|
||||
@ -59,7 +59,7 @@ def load_tenant_from_request(data: AuthData) -> None:
|
||||
def load_account(data: AuthData) -> None:
|
||||
if data.caller is not None:
|
||||
return
|
||||
account = AccountService.get_account_by_id(db.session, str(data.account_id))
|
||||
account = AccountService.get_account_by_id(str(data.account_id), session=db.session())
|
||||
if account is None:
|
||||
raise Unauthorized("account not found")
|
||||
if data.tenant:
|
||||
@ -75,7 +75,7 @@ def load_workspace_role(data: AuthData) -> None:
|
||||
return
|
||||
if data.caller is not None and getattr(data.caller, "status", None) != AccountStatus.ACTIVE:
|
||||
return
|
||||
role = TenantService.get_account_role_in_tenant(db.session, str(data.account_id), str(data.tenant.id))
|
||||
role = TenantService.get_account_role_in_tenant(str(data.account_id), str(data.tenant.id), session=db.session())
|
||||
if role is None:
|
||||
return
|
||||
data.tenant_role = role
|
||||
|
||||
@ -82,7 +82,7 @@ def check_app_api_enabled(data: AuthData) -> None:
|
||||
def check_app_access(data: AuthData) -> None:
|
||||
if data.tenant is None:
|
||||
return
|
||||
if not TenantService.account_belongs_to_tenant(db.session, data.account_id, data.tenant.id):
|
||||
if not TenantService.account_belongs_to_tenant(data.account_id, data.tenant.id, session=db.session()):
|
||||
raise Forbidden("subject_no_app_access")
|
||||
|
||||
|
||||
@ -127,5 +127,5 @@ def _resolve_user_id(data: AuthData) -> str | None:
|
||||
return str(data.account_id) if data.account_id is not None else None
|
||||
if data.external_identity is None:
|
||||
return None
|
||||
account = AccountService.get_account_by_email(db.session, data.external_identity.email)
|
||||
account = AccountService.get_account_by_email(data.external_identity.email, session=db.session())
|
||||
return str(account.id) if account is not None else None
|
||||
|
||||
@ -247,7 +247,6 @@ class DeviceApproveApi(Resource):
|
||||
raise BadRequest(description=str(e)) from None
|
||||
ttl_days = oauth_ttl_days(tenant_id=tenant)
|
||||
mint = mint_oauth_token(
|
||||
db.session,
|
||||
redis_client,
|
||||
subject_email=account.email,
|
||||
subject_issuer=ACCOUNT_ISSUER_SENTINEL,
|
||||
@ -256,6 +255,7 @@ class DeviceApproveApi(Resource):
|
||||
device_label=state.device_label,
|
||||
prefix=profile.prefix,
|
||||
ttl_days=ttl_days,
|
||||
session=db.session(),
|
||||
)
|
||||
|
||||
poll_payload = _build_account_poll_payload(account, tenant, mint)
|
||||
@ -342,7 +342,7 @@ def _audit_cross_ip_if_needed(state) -> None:
|
||||
|
||||
|
||||
def _build_account_poll_payload(account, tenant, mint) -> PollPayload:
|
||||
rows = TenantService.get_workspaces_for_account(db.session, str(account.id))
|
||||
rows = TenantService.get_workspaces_for_account(str(account.id), session=db.session())
|
||||
workspaces = [WorkspacePayload(id=str(t.id), name=t.name, role=getattr(m, "role", "")) for t, m in rows]
|
||||
# Prefer active session tenant → DB-flagged current join → first membership.
|
||||
default_ws_id = None
|
||||
|
||||
@ -194,7 +194,7 @@ def _sso_complete_impl():
|
||||
if state.status is not DeviceFlowStatus.PENDING:
|
||||
return _device_error_redirect("sso_failed", user_code)
|
||||
|
||||
if AccountService.has_active_account_with_email(db.session, claims.email):
|
||||
if AccountService.has_active_account_with_email(claims.email, session=db.session()):
|
||||
_emit_external_rejection_audit(
|
||||
state,
|
||||
_RejectedClaims(subject_email=claims.email, subject_issuer=claims.issuer),
|
||||
@ -274,7 +274,7 @@ def approve_external():
|
||||
if state.status is not DeviceFlowStatus.PENDING:
|
||||
raise Conflict("user_code_not_pending")
|
||||
|
||||
if AccountService.has_active_account_with_email(db.session, claims.subject_email):
|
||||
if AccountService.has_active_account_with_email(claims.subject_email, session=db.session()):
|
||||
_emit_external_rejection_audit(state, claims, reason="email_belongs_to_dify_account")
|
||||
raise Forbidden("email_belongs_to_dify_account")
|
||||
|
||||
@ -293,7 +293,6 @@ def approve_external():
|
||||
|
||||
ttl_days = oauth_ttl_days(tenant_id=None)
|
||||
mint = mint_oauth_token(
|
||||
db.session,
|
||||
redis_client,
|
||||
subject_email=claims.subject_email,
|
||||
subject_issuer=claims.subject_issuer,
|
||||
@ -302,6 +301,7 @@ def approve_external():
|
||||
device_label=state.device_label,
|
||||
prefix=profile.prefix,
|
||||
ttl_days=ttl_days,
|
||||
session=db.session(),
|
||||
)
|
||||
|
||||
# SSO branch of the shared PollPayload contract: account/workspace
|
||||
|
||||
@ -64,14 +64,14 @@ def _member_response(account: Account) -> MemberResponse:
|
||||
|
||||
|
||||
def _load_tenant(workspace_id: str) -> Tenant:
|
||||
tenant = TenantService.get_tenant_by_id(db.session, workspace_id)
|
||||
tenant = TenantService.get_tenant_by_id(workspace_id, session=db.session())
|
||||
if tenant is None or tenant.status != TenantStatus.NORMAL:
|
||||
raise NotFound("workspace not found")
|
||||
return tenant
|
||||
|
||||
|
||||
def _load_account(account_id: object) -> Account:
|
||||
account = AccountService.get_account_by_id(db.session, str(account_id)) if account_id else None
|
||||
account = AccountService.get_account_by_id(str(account_id), session=db.session()) if account_id else None
|
||||
if account is None:
|
||||
raise RuntimeError("authenticated account_id has no Account row")
|
||||
return account
|
||||
@ -94,7 +94,7 @@ class WorkspacesApi(Resource):
|
||||
@auth_router.guard(scope=Scope.WORKSPACE_READ, allowed_token_types=frozenset({TokenType.OAUTH_ACCOUNT}))
|
||||
@returns(200, WorkspaceListResponse, description="Workspace list")
|
||||
def get(self, *, auth_data: AuthData):
|
||||
rows = TenantService.get_workspaces_for_account(db.session, str(auth_data.account_id))
|
||||
rows = TenantService.get_workspaces_for_account(str(auth_data.account_id), session=db.session())
|
||||
|
||||
return WorkspaceListResponse(workspaces=list(starmap(_workspace_summary, rows)))
|
||||
|
||||
@ -104,7 +104,7 @@ class WorkspaceByIdApi(Resource):
|
||||
@auth_router.guard(scope=Scope.WORKSPACE_READ, allowed_token_types=frozenset({TokenType.OAUTH_ACCOUNT}))
|
||||
@returns(200, WorkspaceDetailResponse, description="Workspace detail")
|
||||
def get(self, workspace_id: str, *, auth_data: AuthData):
|
||||
row = TenantService.find_workspace_for_account(db.session, str(auth_data.account_id), workspace_id)
|
||||
row = TenantService.find_workspace_for_account(str(auth_data.account_id), workspace_id, session=db.session())
|
||||
# 404 (not 403) on non-member so workspace IDs don't leak across tenants.
|
||||
if row is None:
|
||||
raise NotFound("workspace not found")
|
||||
@ -128,11 +128,11 @@ class WorkspaceSwitchApi(Resource):
|
||||
account = _load_account(auth_data.account_id)
|
||||
|
||||
try:
|
||||
TenantService.switch_tenant(account, workspace_id, session=db.session)
|
||||
TenantService.switch_tenant(account, workspace_id, session=db.session())
|
||||
except AccountNotLinkTenantError:
|
||||
raise NotFound("workspace not found")
|
||||
|
||||
row = TenantService.find_workspace_for_account(db.session, str(auth_data.account_id), workspace_id)
|
||||
row = TenantService.find_workspace_for_account(str(auth_data.account_id), workspace_id, session=db.session())
|
||||
if row is None:
|
||||
raise NotFound("workspace not found")
|
||||
tenant, membership = row
|
||||
@ -152,7 +152,7 @@ class WorkspaceMembersApi(Resource):
|
||||
@accepts(query=MemberListQuery)
|
||||
def get(self, workspace_id: str, *, auth_data: AuthData, query: MemberListQuery):
|
||||
tenant = _load_tenant(workspace_id)
|
||||
members = TenantService.get_tenant_members(tenant, session=db.session)
|
||||
members = TenantService.get_tenant_members(tenant, session=db.session())
|
||||
total = len(members)
|
||||
start = (query.page - 1) * query.limit
|
||||
page_items = members[start : start + query.limit]
|
||||
@ -184,7 +184,7 @@ class WorkspaceMembersApi(Resource):
|
||||
language=None,
|
||||
role=body.role,
|
||||
inviter=inviter,
|
||||
session=db.session,
|
||||
session=db.session(),
|
||||
)
|
||||
except AccountAlreadyInTenantError as exc:
|
||||
raise BadRequest(str(exc))
|
||||
@ -194,7 +194,7 @@ class WorkspaceMembersApi(Resource):
|
||||
raise BadRequest(str(exc))
|
||||
|
||||
normalized_email = body.email.lower()
|
||||
member = AccountService.get_account_by_email_with_case_fallback(db.session, normalized_email)
|
||||
member = AccountService.get_account_by_email_with_case_fallback(normalized_email, session=db.session())
|
||||
if member is None:
|
||||
# invite_new_member just created or fetched this account.
|
||||
raise RuntimeError("invited member missing from DB after invite")
|
||||
@ -229,12 +229,12 @@ class WorkspaceMemberApi(Resource):
|
||||
def delete(self, workspace_id: str, member_id: str, *, auth_data: AuthData):
|
||||
operator = _load_account(auth_data.account_id)
|
||||
tenant = _load_tenant(workspace_id)
|
||||
member = AccountService.get_account_by_id(db.session, member_id)
|
||||
member = AccountService.get_account_by_id(member_id, session=db.session())
|
||||
if member is None:
|
||||
raise NotFound("member not found")
|
||||
|
||||
try:
|
||||
TenantService.remove_member_from_tenant(tenant, member, operator, session=db.session)
|
||||
TenantService.remove_member_from_tenant(tenant, member, operator, session=db.session())
|
||||
except CannotOperateSelfError as exc:
|
||||
raise BadRequest(str(exc))
|
||||
except NoPermissionError as exc:
|
||||
@ -254,12 +254,12 @@ class WorkspaceMemberApi(Resource):
|
||||
def patch(self, workspace_id: str, member_id: str, *, auth_data: AuthData, body: MemberRoleUpdatePayload):
|
||||
operator = _load_account(auth_data.account_id)
|
||||
tenant = _load_tenant(workspace_id)
|
||||
member = AccountService.get_account_by_id(db.session, member_id)
|
||||
member = AccountService.get_account_by_id(member_id, session=db.session())
|
||||
if member is None:
|
||||
raise NotFound("member not found")
|
||||
|
||||
try:
|
||||
TenantService.update_member_role(tenant, member, body.role, operator, session=db.session)
|
||||
TenantService.update_member_role(tenant, member, body.role, operator, session=db.session())
|
||||
except CannotOperateSelfError as exc:
|
||||
raise BadRequest(str(exc))
|
||||
except NoPermissionError as exc:
|
||||
|
||||
@ -201,7 +201,7 @@ class AnnotationListApi(Resource):
|
||||
query = AnnotationListQuery.model_validate(request.args.to_dict(flat=True))
|
||||
|
||||
annotation_list, total = AppAnnotationService.get_annotation_list_by_app_id(
|
||||
app_model.id, query.page, query.limit, query.keyword
|
||||
app_model.id, query.page, query.limit, query.keyword, session=db.session()
|
||||
)
|
||||
annotation_models = TypeAdapter(list[Annotation]).validate_python(annotation_list, from_attributes=True)
|
||||
response = AnnotationList(
|
||||
@ -243,7 +243,9 @@ class AnnotationListApi(Resource):
|
||||
"""Create a new annotation."""
|
||||
payload = AnnotationCreatePayload.model_validate(service_api_ns.payload or {})
|
||||
insert_args: InsertAnnotationArgs = {"question": payload.question, "answer": payload.answer}
|
||||
annotation = AppAnnotationService.insert_app_annotation_directly(insert_args, app_model.id)
|
||||
annotation = AppAnnotationService.insert_app_annotation_directly(
|
||||
insert_args, app_model.id, session=db.session()
|
||||
)
|
||||
response = Annotation.model_validate(annotation, from_attributes=True)
|
||||
return response.model_dump(mode="json"), HTTPStatus.CREATED
|
||||
|
||||
@ -285,7 +287,7 @@ class AnnotationUpdateDeleteApi(Resource):
|
||||
update_args: UpdateAnnotationArgs = {"question": payload.question, "answer": payload.answer}
|
||||
app_ref = AppRefService.create_app_ref(app_model)
|
||||
annotation_ref = AppRefService.create_annotation_ref(app_ref, str(annotation_id))
|
||||
annotation = AppAnnotationService.update_app_annotation_directly(update_args, annotation_ref, db.session)
|
||||
annotation = AppAnnotationService.update_app_annotation_directly(update_args, annotation_ref, db.session())
|
||||
response = Annotation.model_validate(annotation, from_attributes=True)
|
||||
return response.model_dump(mode="json")
|
||||
|
||||
@ -316,5 +318,5 @@ class AnnotationUpdateDeleteApi(Resource):
|
||||
"""Delete an annotation."""
|
||||
app_ref = AppRefService.create_app_ref(app_model)
|
||||
annotation_ref = AppRefService.create_annotation_ref(app_ref, str(annotation_id))
|
||||
AppAnnotationService.delete_app_annotation(annotation_ref, db.session)
|
||||
AppAnnotationService.delete_app_annotation(annotation_ref, db.session())
|
||||
return "", 204
|
||||
|
||||
@ -11,6 +11,7 @@ from controllers.service_api.app.error import AgentNotPublishedError, AppUnavail
|
||||
from controllers.service_api.wraps import validate_app_token
|
||||
from core.app.app_config.common.parameters_mapping import get_parameters_from_feature_dict
|
||||
from core.app.apps.agent_app.errors import AgentAppGeneratorError, AgentAppNotPublishedError
|
||||
from extensions.ext_database import db
|
||||
from fields.base import ResponseModel
|
||||
from models.model import App, AppMode
|
||||
from services.app_service import AppService
|
||||
@ -122,7 +123,7 @@ class AppMetaApi(Resource):
|
||||
|
||||
Returns metadata about the application including configuration and settings.
|
||||
"""
|
||||
return AppService().get_app_meta(app_model)
|
||||
return AppService().get_app_meta(app_model, session=db.session())
|
||||
|
||||
|
||||
@service_api_ns.route("/info")
|
||||
|
||||
@ -188,7 +188,7 @@ class TextApi(Resource):
|
||||
)
|
||||
response = AudioService.transcript_tts(
|
||||
app_model=app_model,
|
||||
session=db.session,
|
||||
session=db.session(),
|
||||
text=text,
|
||||
voice=voice,
|
||||
end_user=end_user.external_user_id,
|
||||
|
||||
@ -249,7 +249,7 @@ class ConversationDetailApi(Resource):
|
||||
conversation_id = str(c_id)
|
||||
|
||||
try:
|
||||
ConversationService.delete(app_model, conversation_id, end_user)
|
||||
ConversationService.delete(app_model, conversation_id, end_user, session=db.session())
|
||||
except services.errors.conversation.ConversationNotExistsError:
|
||||
raise NotFound("Conversation Not Exists.")
|
||||
return "", 204
|
||||
@ -299,7 +299,7 @@ class ConversationRenameApi(Resource):
|
||||
|
||||
try:
|
||||
conversation = ConversationService.rename(
|
||||
app_model, conversation_id, end_user, payload.name, payload.auto_generate
|
||||
app_model, conversation_id, end_user, payload.name, payload.auto_generate, session=db.session()
|
||||
)
|
||||
return (
|
||||
TypeAdapter(SimpleConversation)
|
||||
@ -356,7 +356,13 @@ class ConversationVariablesApi(Resource):
|
||||
|
||||
try:
|
||||
pagination = ConversationService.get_conversational_variable(
|
||||
app_model, conversation_id, end_user, query_args.limit, last_id, query_args.variable_name
|
||||
app_model,
|
||||
conversation_id,
|
||||
end_user,
|
||||
query_args.limit,
|
||||
last_id,
|
||||
query_args.variable_name,
|
||||
session=db.session(),
|
||||
)
|
||||
return ConversationVariableInfiniteScrollPaginationResponse.model_validate(
|
||||
pagination, from_attributes=True
|
||||
@ -417,7 +423,7 @@ class ConversationVariableDetailApi(Resource):
|
||||
|
||||
try:
|
||||
variable = ConversationService.update_conversation_variable(
|
||||
app_model, conversation_id, variable_id_str, end_user, payload.value
|
||||
app_model, conversation_id, variable_id_str, end_user, payload.value, session=db.session()
|
||||
)
|
||||
return ConversationVariableResponse.model_validate(variable, from_attributes=True).model_dump(mode="json")
|
||||
except services.errors.conversation.ConversationNotExistsError:
|
||||
|
||||
@ -15,6 +15,7 @@ from controllers.service_api.app.error import NotChatAppError
|
||||
from controllers.service_api.schema import expect_with_user
|
||||
from controllers.service_api.wraps import FetchUserArg, WhereisUserArg, validate_app_token
|
||||
from core.app.entities.app_invoke_entities import InvokeFrom
|
||||
from extensions.ext_database import db
|
||||
from fields.base import ResponseModel
|
||||
from fields.conversation_fields import ResultResponse
|
||||
from fields.message_fields import MessageInfiniteScrollPagination, MessageListItem
|
||||
@ -109,7 +110,7 @@ class MessageListApi(Resource):
|
||||
|
||||
try:
|
||||
pagination = MessageService.pagination_by_first_id(
|
||||
app_model, end_user, conversation_id, first_id, query_args.limit
|
||||
app_model, end_user, conversation_id, first_id, query_args.limit, session=db.session()
|
||||
)
|
||||
adapter = TypeAdapter(MessageListItem)
|
||||
items = [adapter.validate_python(message, from_attributes=True) for message in pagination.data]
|
||||
@ -167,6 +168,7 @@ class MessageFeedbackApi(Resource):
|
||||
user=end_user,
|
||||
rating=FeedbackRating(payload.rating) if payload.rating else None,
|
||||
content=payload.content,
|
||||
session=db.session(),
|
||||
)
|
||||
except MessageNotExistsError:
|
||||
raise NotFound("Message Not Exists.")
|
||||
@ -208,7 +210,9 @@ class AppGetFeedbacksApi(Resource):
|
||||
Returns paginated list of all feedback submitted for messages in this app.
|
||||
"""
|
||||
query_args = FeedbackListQuery.model_validate(request.args.to_dict())
|
||||
feedbacks = MessageService.get_all_messages_feedbacks(app_model, page=query_args.page, limit=query_args.limit)
|
||||
feedbacks = MessageService.get_all_messages_feedbacks(
|
||||
app_model, page=query_args.page, limit=query_args.limit, session=db.session()
|
||||
)
|
||||
return {"data": feedbacks}
|
||||
|
||||
|
||||
@ -258,7 +262,11 @@ class MessageSuggestedApi(Resource):
|
||||
|
||||
try:
|
||||
questions = MessageService.get_suggested_questions_after_answer(
|
||||
app_model=app_model, user=end_user, message_id=message_id_str, invoke_from=InvokeFrom.SERVICE_API
|
||||
app_model=app_model,
|
||||
user=end_user,
|
||||
message_id=message_id_str,
|
||||
invoke_from=InvokeFrom.SERVICE_API,
|
||||
session=db.session(),
|
||||
)
|
||||
except MessageNotExistsError:
|
||||
raise NotFound("Message Not Exists.")
|
||||
|
||||
@ -414,7 +414,7 @@ class DatasetListApi(DatasetApiResource):
|
||||
datasets, total = DatasetService.get_datasets(
|
||||
query.page,
|
||||
query.limit,
|
||||
db.session,
|
||||
db.session(),
|
||||
tenant_id,
|
||||
current_user,
|
||||
query.keyword,
|
||||
@ -565,11 +565,11 @@ class DatasetApi(DatasetApiResource):
|
||||
)
|
||||
def get(self, _, dataset_id: UUID):
|
||||
dataset_id_str = str(dataset_id)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session())
|
||||
if dataset is None:
|
||||
raise NotFound("Dataset not found.")
|
||||
try:
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session)
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session())
|
||||
except services.errors.account.NoPermissionError as e:
|
||||
raise Forbidden(str(e))
|
||||
data = _dump_service_dataset_detail(dataset)
|
||||
@ -601,7 +601,7 @@ class DatasetApi(DatasetApiResource):
|
||||
retrieval_model_dict["search_method"] = "keyword_search"
|
||||
|
||||
if data.get("permission") == "partial_members":
|
||||
part_users_list = DatasetPermissionService.get_dataset_partial_member_list(dataset_id_str, db.session)
|
||||
part_users_list = DatasetPermissionService.get_dataset_partial_member_list(dataset_id_str, db.session())
|
||||
data.update({"partial_member_list": part_users_list})
|
||||
|
||||
return _dump_service_dataset_with_partial_members(data), 200
|
||||
@ -640,7 +640,7 @@ class DatasetApi(DatasetApiResource):
|
||||
@with_session
|
||||
def patch(self, session: Session, _, dataset_id: UUID):
|
||||
dataset_id_str = str(dataset_id)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session())
|
||||
if dataset is None:
|
||||
raise NotFound("Dataset not found.")
|
||||
|
||||
@ -681,10 +681,10 @@ class DatasetApi(DatasetApiResource):
|
||||
dataset,
|
||||
str(payload.permission) if payload.permission else None,
|
||||
payload.partial_member_list,
|
||||
db.session,
|
||||
session=db.session(),
|
||||
)
|
||||
|
||||
dataset = DatasetService.update_dataset(session, dataset_id_str, update_data, current_user)
|
||||
dataset = DatasetService.update_dataset(dataset_id_str, update_data, current_user, session=session)
|
||||
|
||||
if dataset is None:
|
||||
raise NotFound("Dataset not found.")
|
||||
@ -695,13 +695,13 @@ class DatasetApi(DatasetApiResource):
|
||||
|
||||
if payload.partial_member_list and payload.permission == DatasetPermissionEnum.PARTIAL_TEAM:
|
||||
DatasetPermissionService.update_partial_member_list(
|
||||
tenant_id, dataset_id_str, payload.partial_member_list, db.session
|
||||
tenant_id, dataset_id_str, payload.partial_member_list, db.session()
|
||||
)
|
||||
# clear partial member list when permission is only_me or all_team_members
|
||||
elif payload.permission in {DatasetPermissionEnum.ONLY_ME, DatasetPermissionEnum.ALL_TEAM}:
|
||||
DatasetPermissionService.clear_partial_member_list(dataset_id_str, db.session)
|
||||
DatasetPermissionService.clear_partial_member_list(dataset_id_str, db.session())
|
||||
|
||||
partial_member_list = DatasetPermissionService.get_dataset_partial_member_list(dataset_id_str, db.session)
|
||||
partial_member_list = DatasetPermissionService.get_dataset_partial_member_list(dataset_id_str, db.session())
|
||||
result_data.update({"partial_member_list": partial_member_list})
|
||||
|
||||
return _dump_service_dataset_with_partial_members(result_data), 200
|
||||
@ -754,8 +754,8 @@ class DatasetApi(DatasetApiResource):
|
||||
dataset_id_str = str(dataset_id)
|
||||
|
||||
try:
|
||||
if DatasetService.delete_dataset(dataset_id_str, current_user, db.session):
|
||||
DatasetPermissionService.clear_partial_member_list(dataset_id_str, db.session)
|
||||
if DatasetService.delete_dataset(dataset_id_str, current_user, db.session()):
|
||||
DatasetPermissionService.clear_partial_member_list(dataset_id_str, db.session())
|
||||
return "", 204
|
||||
else:
|
||||
raise NotFound("Dataset not found.")
|
||||
@ -820,14 +820,14 @@ class DocumentStatusApi(DatasetApiResource):
|
||||
InvalidActionError: If the action is invalid or cannot be performed.
|
||||
"""
|
||||
dataset_id_str = str(dataset_id)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session())
|
||||
|
||||
if dataset is None:
|
||||
raise NotFound("Dataset not found.")
|
||||
|
||||
# Check user's permission
|
||||
try:
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session)
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session())
|
||||
except services.errors.account.NoPermissionError as e:
|
||||
raise Forbidden(str(e))
|
||||
|
||||
@ -839,7 +839,7 @@ class DocumentStatusApi(DatasetApiResource):
|
||||
document_ids = data.get("document_ids", [])
|
||||
|
||||
try:
|
||||
DocumentService.batch_update_document_status(dataset, document_ids, action, current_user, db.session)
|
||||
DocumentService.batch_update_document_status(dataset, document_ids, action, current_user, db.session())
|
||||
except services.errors.document.DocumentIndexingError as e:
|
||||
raise InvalidActionError(str(e))
|
||||
except ValueError as e:
|
||||
@ -876,7 +876,7 @@ class DatasetTagsApi(DatasetApiResource):
|
||||
assert isinstance(current_user, Account)
|
||||
cid = current_user.current_tenant_id
|
||||
assert cid is not None
|
||||
tags = TagService.get_tags(db.session(), "knowledge", cid)
|
||||
tags = TagService.get_tags("knowledge", cid, session=db.session())
|
||||
return dump_response(KnowledgeTagListResponse, tags), 200
|
||||
|
||||
@service_api_ns.doc(
|
||||
@ -909,7 +909,7 @@ class DatasetTagsApi(DatasetApiResource):
|
||||
raise Forbidden()
|
||||
|
||||
payload = TagCreatePayload.model_validate(service_api_ns.payload or {})
|
||||
tag = TagService.save_tags(SaveTagPayload(name=payload.name, type=TagType.KNOWLEDGE), db.session)
|
||||
tag = TagService.save_tags(SaveTagPayload(name=payload.name, type=TagType.KNOWLEDGE), db.session())
|
||||
|
||||
response = dump_response(
|
||||
KnowledgeTagResponse,
|
||||
@ -948,10 +948,10 @@ class DatasetTagsApi(DatasetApiResource):
|
||||
payload = TagUpdatePayload.model_validate(service_api_ns.payload or {})
|
||||
tag_id = payload.tag_id
|
||||
tag = TagService.update_tags(
|
||||
UpdateTagServicePayload(name=payload.name), tag_id, db.session, tag_type=TagType.KNOWLEDGE
|
||||
UpdateTagServicePayload(name=payload.name), tag_id, db.session(), tag_type=TagType.KNOWLEDGE
|
||||
)
|
||||
|
||||
binding_count = TagService.get_tag_binding_count(tag_id, db.session, tag_type=TagType.KNOWLEDGE)
|
||||
binding_count = TagService.get_tag_binding_count(tag_id, db.session(), tag_type=TagType.KNOWLEDGE)
|
||||
|
||||
response = dump_response(
|
||||
KnowledgeTagResponse,
|
||||
@ -981,7 +981,7 @@ class DatasetTagsApi(DatasetApiResource):
|
||||
def delete(self, _):
|
||||
"""Delete a knowledge type tag."""
|
||||
payload = TagDeletePayload.model_validate(service_api_ns.payload or {})
|
||||
TagService.delete_tag(payload.tag_id, db.session, tag_type=TagType.KNOWLEDGE)
|
||||
TagService.delete_tag(payload.tag_id, db.session(), tag_type=TagType.KNOWLEDGE)
|
||||
|
||||
return "", 204
|
||||
|
||||
@ -1015,7 +1015,7 @@ class DatasetTagBindingApi(DatasetApiResource):
|
||||
payload = TagBindingPayload.model_validate(service_api_ns.payload or {})
|
||||
TagService.save_tag_binding(
|
||||
TagBindingCreatePayload(tag_ids=payload.tag_ids, target_id=payload.target_id, type=TagType.KNOWLEDGE),
|
||||
db.session,
|
||||
db.session(),
|
||||
)
|
||||
|
||||
return "", 204
|
||||
@ -1050,7 +1050,7 @@ class DatasetTagUnbindingApi(DatasetApiResource):
|
||||
payload = TagUnbindingPayload.model_validate(service_api_ns.payload or {})
|
||||
TagService.delete_tag_binding(
|
||||
TagBindingDeletePayload(tag_ids=payload.tag_ids, target_id=payload.target_id, type=TagType.KNOWLEDGE),
|
||||
db.session,
|
||||
db.session(),
|
||||
)
|
||||
|
||||
return "", 204
|
||||
@ -1086,7 +1086,7 @@ class DatasetTagsBindingStatusApi(DatasetApiResource):
|
||||
assert isinstance(current_user, Account)
|
||||
assert current_user.current_tenant_id is not None
|
||||
tags = TagService.get_tags_by_target_id(
|
||||
"knowledge", current_user.current_tenant_id, str(dataset_id), db.session
|
||||
"knowledge", current_user.current_tenant_id, str(dataset_id), db.session()
|
||||
)
|
||||
tags_list = [{"id": tag.id, "name": tag.name} for tag in tags]
|
||||
return dump_response(DatasetBoundTagListResponse, {"data": tags_list, "total": len(tags)}), 200
|
||||
|
||||
@ -401,7 +401,7 @@ def _create_document_by_text(tenant_id: str, dataset_id: UUID) -> tuple[Mapping[
|
||||
account=current_user,
|
||||
dataset_process_rule=dataset.latest_process_rule if "process_rule" not in args else None,
|
||||
created_from="api",
|
||||
session=db.session,
|
||||
session=db.session(),
|
||||
)
|
||||
except ProviderTokenNotInitError as ex:
|
||||
raise ProviderNotInitializeError(ex.description)
|
||||
@ -461,7 +461,7 @@ def _update_document_by_text(tenant_id: str, dataset_id: UUID, document_id: UUID
|
||||
account=current_user,
|
||||
dataset_process_rule=dataset.latest_process_rule if "process_rule" not in args else None,
|
||||
created_from="api",
|
||||
session=db.session,
|
||||
session=db.session(),
|
||||
)
|
||||
except ProviderTokenNotInitError as ex:
|
||||
raise ProviderNotInitializeError(ex.description)
|
||||
@ -759,7 +759,7 @@ class DocumentAddByFileApi(DatasetApiResource):
|
||||
account=dataset.created_by_account,
|
||||
dataset_process_rule=dataset_process_rule,
|
||||
created_from="api",
|
||||
session=db.session,
|
||||
session=db.session(),
|
||||
)
|
||||
except ProviderTokenNotInitError as ex:
|
||||
raise ProviderNotInitializeError(ex.description)
|
||||
@ -836,7 +836,7 @@ def _update_document_by_file(tenant_id: str, dataset_id: UUID, document_id: UUID
|
||||
account=dataset.created_by_account,
|
||||
dataset_process_rule=dataset.latest_process_rule if "process_rule" not in args else None,
|
||||
created_from="api",
|
||||
session=db.session,
|
||||
session=db.session(),
|
||||
)
|
||||
except ProviderTokenNotInitError as ex:
|
||||
raise ProviderNotInitializeError(ex.description)
|
||||
@ -955,6 +955,7 @@ class DocumentListApi(DatasetApiResource):
|
||||
documents=documents,
|
||||
dataset=dataset,
|
||||
tenant_id=tenant_id,
|
||||
session=db.session(),
|
||||
)
|
||||
|
||||
response = {
|
||||
@ -1007,7 +1008,7 @@ class DocumentBatchDownloadZipApi(DatasetApiResource):
|
||||
document_ids=[str(document_id) for document_id in payload.document_ids],
|
||||
tenant_id=str(tenant_id),
|
||||
current_user=current_user,
|
||||
session=db.session,
|
||||
session=db.session(),
|
||||
)
|
||||
|
||||
with ExitStack() as stack:
|
||||
@ -1064,7 +1065,7 @@ class DocumentIndexingStatusApi(DatasetApiResource):
|
||||
if not dataset:
|
||||
raise NotFound("Dataset not found.")
|
||||
# get documents
|
||||
documents = DocumentService.get_batch_documents(dataset_id_str, batch, db.session)
|
||||
documents = DocumentService.get_batch_documents(dataset_id_str, batch, db.session())
|
||||
if not documents:
|
||||
raise NotFound("Documents not found.")
|
||||
documents_status = []
|
||||
@ -1140,7 +1141,7 @@ class DocumentDownloadApi(DatasetApiResource):
|
||||
@cloud_edition_billing_rate_limit_check("knowledge", "dataset")
|
||||
def get(self, tenant_id, dataset_id: UUID, document_id: UUID):
|
||||
dataset = self.get_dataset(str(dataset_id), str(tenant_id))
|
||||
document = DocumentService.get_document(dataset.id, str(document_id), session=db.session)
|
||||
document = DocumentService.get_document(dataset.id, str(document_id), session=db.session())
|
||||
|
||||
if not document:
|
||||
raise NotFound("Document not found.")
|
||||
@ -1148,7 +1149,7 @@ class DocumentDownloadApi(DatasetApiResource):
|
||||
if document.tenant_id != str(tenant_id):
|
||||
raise Forbidden("No permission.")
|
||||
|
||||
return {"url": DocumentService.get_document_download_url(document, db.session)}
|
||||
return {"url": DocumentService.get_document_download_url(document, db.session())}
|
||||
|
||||
|
||||
@service_api_ns.route("/datasets/<uuid:dataset_id>/documents/<uuid:document_id>")
|
||||
@ -1196,7 +1197,7 @@ class DocumentApi(DatasetApiResource):
|
||||
|
||||
dataset = self.get_dataset(dataset_id_str, tenant_id)
|
||||
|
||||
document = DocumentService.get_document(dataset.id, document_id_str, session=db.session)
|
||||
document = DocumentService.get_document(dataset.id, document_id_str, session=db.session())
|
||||
|
||||
if not document:
|
||||
raise NotFound("Document not found.")
|
||||
@ -1216,12 +1217,13 @@ class DocumentApi(DatasetApiResource):
|
||||
document_id=document_id_str,
|
||||
dataset_id=dataset_id_str,
|
||||
tenant_id=tenant_id,
|
||||
session=db.session(),
|
||||
)
|
||||
|
||||
if metadata == "only":
|
||||
response = {"id": document.id, "doc_type": document.doc_type, "doc_metadata": document.doc_metadata_details}
|
||||
elif metadata == "without":
|
||||
dataset_process_rules = DatasetService.get_process_rules(dataset_id_str, db.session)
|
||||
dataset_process_rules = DatasetService.get_process_rules(dataset_id_str, db.session())
|
||||
document_process_rules = document.dataset_process_rule.to_dict() if document.dataset_process_rule else {}
|
||||
data_source_info = document.data_source_detail_dict
|
||||
response = {
|
||||
@ -1256,7 +1258,7 @@ class DocumentApi(DatasetApiResource):
|
||||
"need_summary": document.need_summary if document.need_summary is not None else False,
|
||||
}
|
||||
else:
|
||||
dataset_process_rules = DatasetService.get_process_rules(dataset_id_str, db.session)
|
||||
dataset_process_rules = DatasetService.get_process_rules(dataset_id_str, db.session())
|
||||
document_process_rules = document.dataset_process_rule.to_dict() if document.dataset_process_rule else {}
|
||||
data_source_info = document.data_source_detail_dict
|
||||
response = {
|
||||
@ -1351,7 +1353,7 @@ class DocumentApi(DatasetApiResource):
|
||||
if not dataset:
|
||||
raise ValueError("Dataset does not exist.")
|
||||
|
||||
document = DocumentService.get_document(dataset.id, document_id_str, session=db.session)
|
||||
document = DocumentService.get_document(dataset.id, document_id_str, session=db.session())
|
||||
|
||||
# 404 if document not found
|
||||
if document is None:
|
||||
@ -1363,7 +1365,7 @@ class DocumentApi(DatasetApiResource):
|
||||
|
||||
try:
|
||||
# delete document
|
||||
DocumentService.delete_document(document, db.session)
|
||||
DocumentService.delete_document(document, db.session())
|
||||
except services.errors.document.DocumentIndexingError:
|
||||
raise DocumentIndexingError("Cannot delete document during indexing.")
|
||||
|
||||
|
||||
@ -81,12 +81,12 @@ class DatasetMetadataCreateServiceApi(DatasetApiResource):
|
||||
metadata_args = MetadataArgs.model_validate(service_api_ns.payload or {})
|
||||
|
||||
dataset_id_str = str(dataset_id)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session())
|
||||
if dataset is None:
|
||||
raise NotFound("Dataset not found.")
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session)
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session())
|
||||
|
||||
metadata = MetadataService.create_metadata(db.session(), dataset_id_str, metadata_args)
|
||||
metadata = MetadataService.create_metadata(dataset_id_str, metadata_args, session=db.session())
|
||||
return dump_response(DatasetMetadataResponse, metadata), 201
|
||||
|
||||
@service_api_ns.doc(
|
||||
@ -116,10 +116,10 @@ class DatasetMetadataCreateServiceApi(DatasetApiResource):
|
||||
def get(self, tenant_id, dataset_id: UUID):
|
||||
"""Get all metadata for a dataset."""
|
||||
dataset_id_str = str(dataset_id)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session())
|
||||
if dataset is None:
|
||||
raise NotFound("Dataset not found.")
|
||||
metadata = MetadataService.get_dataset_metadatas(db.session(), dataset)
|
||||
metadata = MetadataService.get_dataset_metadatas(dataset, session=db.session())
|
||||
return dump_response(DatasetMetadataListResponse, metadata), 200
|
||||
|
||||
|
||||
@ -154,12 +154,14 @@ class DatasetMetadataServiceApi(DatasetApiResource):
|
||||
|
||||
dataset_id_str = str(dataset_id)
|
||||
metadata_id_str = str(metadata_id)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session())
|
||||
if dataset is None:
|
||||
raise NotFound("Dataset not found.")
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session)
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session())
|
||||
|
||||
metadata = MetadataService.update_metadata_name(db.session(), dataset_id_str, metadata_id_str, payload.name)
|
||||
metadata = MetadataService.update_metadata_name(
|
||||
dataset_id_str, metadata_id_str, payload.name, session=db.session()
|
||||
)
|
||||
return dump_response(DatasetMetadataResponse, metadata), 200
|
||||
|
||||
@service_api_ns.doc(
|
||||
@ -189,12 +191,12 @@ class DatasetMetadataServiceApi(DatasetApiResource):
|
||||
"""Delete metadata."""
|
||||
dataset_id_str = str(dataset_id)
|
||||
metadata_id_str = str(metadata_id)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session())
|
||||
if dataset is None:
|
||||
raise NotFound("Dataset not found.")
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session)
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session())
|
||||
|
||||
MetadataService.delete_metadata(db.session(), dataset_id_str, metadata_id_str)
|
||||
MetadataService.delete_metadata(dataset_id_str, metadata_id_str, session=db.session())
|
||||
return "", 204
|
||||
|
||||
|
||||
@ -257,16 +259,16 @@ class DatasetMetadataBuiltInFieldActionServiceApi(DatasetApiResource):
|
||||
def post(self, tenant_id, dataset_id: UUID, action: Literal["enable", "disable"]):
|
||||
"""Enable or disable built-in metadata field."""
|
||||
dataset_id_str = str(dataset_id)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session())
|
||||
if dataset is None:
|
||||
raise NotFound("Dataset not found.")
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session)
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session())
|
||||
|
||||
match action:
|
||||
case "enable":
|
||||
MetadataService.enable_built_in_field(db.session(), dataset)
|
||||
MetadataService.enable_built_in_field(dataset, session=db.session())
|
||||
case "disable":
|
||||
MetadataService.disable_built_in_field(db.session(), dataset)
|
||||
MetadataService.disable_built_in_field(dataset, session=db.session())
|
||||
return dump_response(DatasetMetadataActionResponse, {"result": "success"}), 200
|
||||
|
||||
|
||||
@ -303,13 +305,13 @@ class DocumentMetadataEditServiceApi(DatasetApiResource):
|
||||
def post(self, tenant_id, dataset_id: UUID):
|
||||
"""Update metadata for multiple documents."""
|
||||
dataset_id_str = str(dataset_id)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session)
|
||||
dataset = DatasetService.get_dataset(dataset_id_str, db.session())
|
||||
if dataset is None:
|
||||
raise NotFound("Dataset not found.")
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session)
|
||||
DatasetService.check_dataset_permission(dataset, current_user, db.session())
|
||||
|
||||
metadata_args = MetadataOperationData.model_validate(service_api_ns.payload or {})
|
||||
|
||||
MetadataService.update_documents_metadata(db.session(), dataset, metadata_args)
|
||||
MetadataService.update_documents_metadata(dataset, metadata_args, session=db.session())
|
||||
|
||||
return dump_response(DatasetMetadataActionResponse, {"result": "success"}), 200
|
||||
|
||||
@ -159,7 +159,7 @@ class DatasourcePluginsApi(DatasetApiResource):
|
||||
|
||||
query = query_params_from_request(DatasourcePluginsQuery)
|
||||
|
||||
rag_pipeline_service: RagPipelineService = RagPipelineService()
|
||||
rag_pipeline_service = RagPipelineService(db.session())
|
||||
datasource_plugins: list[dict[Any, Any]] = rag_pipeline_service.get_datasource_plugins(
|
||||
tenant_id=tenant_id, dataset_id=dataset_id_str, is_published=query.is_published
|
||||
)
|
||||
@ -204,7 +204,7 @@ class DatasourceNodeRunApi(DatasetApiResource):
|
||||
|
||||
payload = DatasourceNodeRunPayload.model_validate(service_api_ns.payload or {})
|
||||
assert isinstance(current_user, Account)
|
||||
rag_pipeline_service: RagPipelineService = RagPipelineService()
|
||||
rag_pipeline_service: RagPipelineService = RagPipelineService(db.session())
|
||||
pipeline: Pipeline = rag_pipeline_service.get_pipeline(tenant_id=tenant_id, dataset_id=dataset_id_str)
|
||||
datasource_node_run_api_entity = DatasourceNodeRunApiEntity.model_validate(
|
||||
{
|
||||
@ -272,7 +272,7 @@ class PipelineRunApi(DatasetApiResource):
|
||||
dataset_id_str = str(dataset_id)
|
||||
# Verify dataset ownership
|
||||
stmt = select(Dataset).where(Dataset.tenant_id == tenant_id, Dataset.id == dataset_id_str)
|
||||
dataset = db.session.scalar(stmt)
|
||||
dataset = session.scalar(stmt)
|
||||
if not dataset:
|
||||
raise NotFound("Dataset not found.")
|
||||
|
||||
@ -281,8 +281,8 @@ class PipelineRunApi(DatasetApiResource):
|
||||
if not isinstance(current_user, Account):
|
||||
raise Forbidden()
|
||||
|
||||
rag_pipeline_service: RagPipelineService = RagPipelineService()
|
||||
pipeline: Pipeline = rag_pipeline_service.get_pipeline(tenant_id=tenant_id, dataset_id=dataset_id_str)
|
||||
rag_pipeline_service = RagPipelineService(session)
|
||||
pipeline = rag_pipeline_service.get_pipeline(tenant_id=tenant_id, dataset_id=dataset_id_str)
|
||||
try:
|
||||
response: dict[Any, Any] | Generator[str, Any, None] = PipelineGenerateService.generate(
|
||||
session=session,
|
||||
|
||||
@ -137,7 +137,7 @@ def _get_segment_for_document(
|
||||
raise NotFound("Document not found.")
|
||||
|
||||
segment_ref = DatasetRefService.create_segment_ref(document_ref, segment_id)
|
||||
segment = SegmentService.get_segment_by_ref(segment_ref)
|
||||
segment = SegmentService.get_segment_by_ref(segment_ref, db.session())
|
||||
if not segment:
|
||||
raise NotFound("Segment not found.")
|
||||
return segment_ref, segment
|
||||
@ -191,7 +191,7 @@ class SegmentApi(DatasetApiResource):
|
||||
raise NotFound("Dataset not found.")
|
||||
document_id_str = str(document_id)
|
||||
# check document
|
||||
document = DocumentService.get_document(dataset.id, document_id_str, session=db.session)
|
||||
document = DocumentService.get_document(dataset.id, document_id_str, session=db.session())
|
||||
if not document:
|
||||
raise NotFound("Document not found.")
|
||||
if document.indexing_status != "completed":
|
||||
@ -227,13 +227,13 @@ class SegmentApi(DatasetApiResource):
|
||||
for args_item in segment_items:
|
||||
SegmentService.segment_create_args_validate(args_item, document)
|
||||
segments = cast(
|
||||
list[DocumentSegment], SegmentService.multi_create_segment(segment_items, document, dataset, db.session)
|
||||
list[DocumentSegment], SegmentService.multi_create_segment(segment_items, document, dataset, db.session())
|
||||
)
|
||||
segment_ids = [segment.id for segment in segments]
|
||||
summaries: dict[str, str | None] = {}
|
||||
if segment_ids:
|
||||
summary_records = SummaryIndexService.get_segments_summaries(
|
||||
segment_ids=segment_ids, dataset_id=dataset_id_str
|
||||
segment_ids=segment_ids, dataset_id=dataset_id_str, session=db.session()
|
||||
)
|
||||
summaries = {chunk_id: record.summary_content for chunk_id, record in summary_records.items()}
|
||||
response = {
|
||||
@ -285,7 +285,7 @@ class SegmentApi(DatasetApiResource):
|
||||
raise NotFound("Dataset not found.")
|
||||
document_id_str = str(document_id)
|
||||
# check document
|
||||
document = DocumentService.get_document(dataset.id, document_id_str, session=db.session)
|
||||
document = DocumentService.get_document(dataset.id, document_id_str, session=db.session())
|
||||
if not document:
|
||||
raise NotFound("Document not found.")
|
||||
# check embedding model setting
|
||||
@ -317,7 +317,7 @@ class SegmentApi(DatasetApiResource):
|
||||
summaries: dict[str, str | None] = {}
|
||||
if segment_ids:
|
||||
summary_records = SummaryIndexService.get_segments_summaries(
|
||||
segment_ids=segment_ids, dataset_id=dataset_id_str
|
||||
segment_ids=segment_ids, dataset_id=dataset_id_str, session=db.session()
|
||||
)
|
||||
summaries = {chunk_id: record.summary_content for chunk_id, record in summary_records.items()}
|
||||
|
||||
@ -367,12 +367,12 @@ class DatasetSegmentApi(DatasetApiResource):
|
||||
DatasetService.check_dataset_model_setting(dataset)
|
||||
document_id_str = str(document_id)
|
||||
# check document
|
||||
document = DocumentService.get_document(dataset_id_str, document_id_str, session=db.session)
|
||||
document = DocumentService.get_document(dataset_id_str, document_id_str, session=db.session())
|
||||
if not document:
|
||||
raise NotFound("Document not found.")
|
||||
segment_id_str = str(segment_id)
|
||||
_, segment = _get_segment_for_document(dataset, document, segment_id_str)
|
||||
SegmentService.delete_segment(segment, document, dataset, db.session)
|
||||
SegmentService.delete_segment(segment, document, dataset, db.session())
|
||||
return "", 204
|
||||
|
||||
@service_api_ns.doc(
|
||||
@ -410,7 +410,7 @@ class DatasetSegmentApi(DatasetApiResource):
|
||||
DatasetService.check_dataset_model_setting(dataset)
|
||||
document_id_str = str(document_id)
|
||||
# check document
|
||||
document = DocumentService.get_document(dataset_id_str, document_id_str, session=db.session)
|
||||
document = DocumentService.get_document(dataset_id_str, document_id_str, session=db.session())
|
||||
if not document:
|
||||
raise NotFound("Document not found.")
|
||||
if dataset.indexing_technique == IndexTechniqueType.HIGH_QUALITY:
|
||||
@ -434,8 +434,10 @@ class DatasetSegmentApi(DatasetApiResource):
|
||||
|
||||
payload = SegmentUpdatePayload.model_validate(service_api_ns.payload or {})
|
||||
|
||||
updated_segment = SegmentService.update_segment(payload.segment, segment, document, dataset, db.session)
|
||||
summary = SummaryIndexService.get_segment_summary(segment_id=updated_segment.id, dataset_id=dataset_id_str)
|
||||
updated_segment = SegmentService.update_segment(payload.segment, segment, document, dataset, db.session())
|
||||
summary = SummaryIndexService.get_segment_summary(
|
||||
segment_id=updated_segment.id, dataset_id=dataset_id_str, session=db.session()
|
||||
)
|
||||
response = {
|
||||
"data": segment_response_with_summary(updated_segment, summary.summary_content if summary else None),
|
||||
"doc_form": document.doc_form,
|
||||
@ -481,13 +483,15 @@ class DatasetSegmentApi(DatasetApiResource):
|
||||
DatasetService.check_dataset_model_setting(dataset)
|
||||
document_id_str = str(document_id)
|
||||
# check document
|
||||
document = DocumentService.get_document(dataset_id_str, document_id_str, session=db.session)
|
||||
document = DocumentService.get_document(dataset_id_str, document_id_str, session=db.session())
|
||||
if not document:
|
||||
raise NotFound("Document not found.")
|
||||
segment_id_str = str(segment_id)
|
||||
_, segment = _get_segment_for_document(dataset, document, segment_id_str)
|
||||
|
||||
summary = SummaryIndexService.get_segment_summary(segment_id=segment.id, dataset_id=dataset_id_str)
|
||||
summary = SummaryIndexService.get_segment_summary(
|
||||
segment_id=segment.id, dataset_id=dataset_id_str, session=db.session()
|
||||
)
|
||||
response = {
|
||||
"data": segment_response_with_summary(segment, summary.summary_content if summary else None),
|
||||
"doc_form": document.doc_form,
|
||||
@ -542,7 +546,7 @@ class ChildChunkApi(DatasetApiResource):
|
||||
|
||||
document_id_str = str(document_id)
|
||||
# check document
|
||||
document = DocumentService.get_document(dataset.id, document_id_str, session=db.session)
|
||||
document = DocumentService.get_document(dataset.id, document_id_str, session=db.session())
|
||||
if not document:
|
||||
raise NotFound("Document not found.")
|
||||
|
||||
@ -570,7 +574,7 @@ class ChildChunkApi(DatasetApiResource):
|
||||
payload = ChildChunkCreatePayload.model_validate(service_api_ns.payload or {})
|
||||
|
||||
try:
|
||||
child_chunk = SegmentService.create_child_chunk(payload.content, segment, document, dataset, db.session)
|
||||
child_chunk = SegmentService.create_child_chunk(payload.content, segment, document, dataset, db.session())
|
||||
except ChildChunkIndexingServiceError as e:
|
||||
raise ChildChunkIndexingError(str(e))
|
||||
|
||||
@ -613,7 +617,7 @@ class ChildChunkApi(DatasetApiResource):
|
||||
|
||||
document_id_str = str(document_id)
|
||||
# check document
|
||||
document = DocumentService.get_document(dataset.id, document_id_str, session=db.session)
|
||||
document = DocumentService.get_document(dataset.id, document_id_str, session=db.session())
|
||||
if not document:
|
||||
raise NotFound("Document not found.")
|
||||
|
||||
@ -680,7 +684,7 @@ class DatasetChildChunkApi(DatasetApiResource):
|
||||
|
||||
document_id_str = str(document_id)
|
||||
# check document
|
||||
document = DocumentService.get_document(dataset.id, document_id_str, session=db.session)
|
||||
document = DocumentService.get_document(dataset.id, document_id_str, session=db.session())
|
||||
if not document:
|
||||
raise NotFound("Document not found.")
|
||||
|
||||
@ -689,12 +693,12 @@ class DatasetChildChunkApi(DatasetApiResource):
|
||||
|
||||
child_chunk_id_str = str(child_chunk_id)
|
||||
# check child chunk
|
||||
child_chunk = SegmentService.get_child_chunk_by_segment_ref(child_chunk_id_str, segment_ref)
|
||||
child_chunk = SegmentService.get_child_chunk_by_segment_ref(child_chunk_id_str, segment_ref, db.session())
|
||||
if not child_chunk:
|
||||
raise NotFound("Child chunk not found.")
|
||||
|
||||
try:
|
||||
SegmentService.delete_child_chunk(child_chunk, dataset, db.session)
|
||||
SegmentService.delete_child_chunk(child_chunk, dataset, db.session())
|
||||
except ChildChunkDeleteIndexServiceError as e:
|
||||
raise ChildChunkDeleteIndexError(str(e))
|
||||
|
||||
@ -741,7 +745,7 @@ class DatasetChildChunkApi(DatasetApiResource):
|
||||
|
||||
document_id_str = str(document_id)
|
||||
# get document
|
||||
document = DocumentService.get_document(dataset_id_str, document_id_str, session=db.session)
|
||||
document = DocumentService.get_document(dataset_id_str, document_id_str, session=db.session())
|
||||
if not document:
|
||||
raise NotFound("Document not found.")
|
||||
|
||||
@ -750,7 +754,7 @@ class DatasetChildChunkApi(DatasetApiResource):
|
||||
|
||||
child_chunk_id_str = str(child_chunk_id)
|
||||
# get child chunk
|
||||
child_chunk = SegmentService.get_child_chunk_by_segment_ref(child_chunk_id_str, segment_ref)
|
||||
child_chunk = SegmentService.get_child_chunk_by_segment_ref(child_chunk_id_str, segment_ref, db.session())
|
||||
if not child_chunk:
|
||||
raise NotFound("Child chunk not found.")
|
||||
|
||||
@ -759,7 +763,7 @@ class DatasetChildChunkApi(DatasetApiResource):
|
||||
|
||||
try:
|
||||
child_chunk = SegmentService.update_child_chunk(
|
||||
payload.content, child_chunk, segment, document, dataset, db.session
|
||||
payload.content, child_chunk, segment, document, dataset, db.session()
|
||||
)
|
||||
except ChildChunkIndexingServiceError as e:
|
||||
raise ChildChunkIndexingError(str(e))
|
||||
|
||||
@ -12,6 +12,7 @@ from controllers.common.agent_app_parameters import get_published_agent_app_feat
|
||||
from controllers.common.schema import query_params_from_model, register_response_schema_models, register_schema_models
|
||||
from core.app.app_config.common.parameters_mapping import get_parameters_from_feature_dict
|
||||
from core.app.apps.agent_app.errors import AgentAppGeneratorError, AgentAppNotPublishedError
|
||||
from extensions.ext_database import db
|
||||
from libs.passport import PassportService
|
||||
from libs.token import extract_webapp_passport
|
||||
from models.model import App, AppMode, EndUser
|
||||
@ -122,7 +123,7 @@ class AppMeta(WebApiResource):
|
||||
@web_ns.response(200, "Success", web_ns.models[AppMetaResponse.__name__])
|
||||
def get(self, app_model: App, end_user: EndUser):
|
||||
"""Get app meta"""
|
||||
return AppService().get_app_meta(app_model)
|
||||
return AppService().get_app_meta(app_model, session=db.session())
|
||||
|
||||
|
||||
@web_ns.route("/webapp/access-mode")
|
||||
@ -148,7 +149,7 @@ class AppAccessMode(Resource):
|
||||
|
||||
app_id = args.app_id
|
||||
if args.app_code:
|
||||
app_id = AppService.get_app_id_by_code(args.app_code)
|
||||
app_id = AppService.get_app_id_by_code(args.app_code, session=db.session())
|
||||
|
||||
if not app_id:
|
||||
raise ValueError("appId or appCode must be provided")
|
||||
@ -179,7 +180,9 @@ class AppWebAuthPermission(Resource):
|
||||
if not app_id or not app_code:
|
||||
raise ValueError("appId must be provided")
|
||||
|
||||
require_permission_check = WebAppAuthService.is_app_require_permission_check(app_id=app_id)
|
||||
require_permission_check = WebAppAuthService.is_app_require_permission_check(
|
||||
app_id=app_id, session=db.session()
|
||||
)
|
||||
if not require_permission_check:
|
||||
return {"result": True}
|
||||
|
||||
@ -200,6 +203,6 @@ class AppWebAuthPermission(Resource):
|
||||
return {"result": True}
|
||||
|
||||
res = True
|
||||
if WebAppAuthService.is_app_require_permission_check(app_id=app_id):
|
||||
if WebAppAuthService.is_app_require_permission_check(app_id=app_id, session=db.session()):
|
||||
res = EnterpriseService.WebAppAuth.is_user_allowed_to_access_webapp(str(user_id), app_id)
|
||||
return {"result": res}
|
||||
|
||||
@ -141,7 +141,7 @@ class TextApi(WebApiResource):
|
||||
)
|
||||
response = AudioService.transcript_tts(
|
||||
app_model=app_model,
|
||||
session=db.session,
|
||||
session=db.session(),
|
||||
text=text,
|
||||
voice=voice,
|
||||
end_user=end_user.external_user_id,
|
||||
|
||||
@ -30,6 +30,7 @@ from core.errors.error import (
|
||||
ProviderTokenNotInitError,
|
||||
QuotaExceededError,
|
||||
)
|
||||
from extensions.ext_database import db
|
||||
from graphon.model_runtime.errors.invoke import InvokeError
|
||||
from libs import helper
|
||||
from libs.helper import uuid_value
|
||||
@ -219,7 +220,10 @@ class ChatApi(WebApiResource):
|
||||
# Eagerly validate conversation to avoid hanging on invalid conversation_id
|
||||
if payload.conversation_id:
|
||||
ConversationService.get_conversation(
|
||||
app_model=app_model, conversation_id=payload.conversation_id, user=end_user
|
||||
app_model=app_model,
|
||||
conversation_id=payload.conversation_id,
|
||||
user=end_user,
|
||||
session=db.session(),
|
||||
)
|
||||
|
||||
response = AppGenerateService.generate(
|
||||
|
||||
@ -112,7 +112,7 @@ class ConversationApi(WebApiResource):
|
||||
|
||||
conversation_id = str(c_id)
|
||||
try:
|
||||
ConversationService.delete(app_model, conversation_id, end_user)
|
||||
ConversationService.delete(app_model, conversation_id, end_user, session=db.session())
|
||||
except ConversationNotExistsError:
|
||||
raise NotFound("Conversation Not Exists.")
|
||||
return "", 204
|
||||
@ -157,7 +157,7 @@ class ConversationRenameApi(WebApiResource):
|
||||
|
||||
try:
|
||||
conversation = ConversationService.rename(
|
||||
app_model, conversation_id, end_user, payload.name, payload.auto_generate
|
||||
app_model, conversation_id, end_user, payload.name, payload.auto_generate, session=db.session()
|
||||
)
|
||||
return (
|
||||
TypeAdapter(SimpleConversation)
|
||||
@ -192,7 +192,7 @@ class ConversationPinApi(WebApiResource):
|
||||
conversation_id = str(c_id)
|
||||
|
||||
try:
|
||||
WebConversationService.pin(app_model, conversation_id, end_user)
|
||||
WebConversationService.pin(app_model, conversation_id, end_user, db.session())
|
||||
except ConversationNotExistsError:
|
||||
raise NotFound("Conversation Not Exists.")
|
||||
|
||||
@ -221,6 +221,6 @@ class ConversationUnPinApi(WebApiResource):
|
||||
raise NotChatAppError()
|
||||
|
||||
conversation_id = str(c_id)
|
||||
WebConversationService.unpin(app_model, conversation_id, end_user)
|
||||
WebConversationService.unpin(app_model, conversation_id, end_user, db.session())
|
||||
|
||||
return ResultResponse(result="success").model_dump(mode="json")
|
||||
|
||||
@ -69,7 +69,7 @@ class ForgotPasswordSendEmailApi(Resource):
|
||||
else:
|
||||
language = "en-US"
|
||||
|
||||
account = AccountService.get_account_by_email_with_case_fallback(db.session, request_email)
|
||||
account = AccountService.get_account_by_email_with_case_fallback(request_email, session=db.session())
|
||||
if account is None:
|
||||
raise AuthenticationFailedError()
|
||||
else:
|
||||
@ -168,7 +168,7 @@ class ForgotPasswordResetApi(Resource):
|
||||
|
||||
email = reset_data.get("email", "")
|
||||
|
||||
account = AccountService.get_account_by_email_with_case_fallback(db.session, email)
|
||||
account = AccountService.get_account_by_email_with_case_fallback(email, session=db.session())
|
||||
|
||||
if account:
|
||||
account = db.session.merge(account)
|
||||
|
||||
@ -30,6 +30,7 @@ from controllers.console.wraps import (
|
||||
)
|
||||
from controllers.web import web_ns
|
||||
from controllers.web.wraps import decode_jwt_token
|
||||
from extensions.ext_database import db
|
||||
from libs.helper import EmailStr, extract_remote_ip
|
||||
from libs.passport import PassportService
|
||||
from libs.password import valid_password
|
||||
@ -104,7 +105,7 @@ class LoginApi(Resource):
|
||||
normalized_email = payload.email.lower()
|
||||
|
||||
try:
|
||||
account = WebAppAuthService.authenticate(payload.email, payload.password)
|
||||
account = WebAppAuthService.authenticate(payload.email, payload.password, db.session())
|
||||
except services.errors.account.AccountLoginError:
|
||||
_log_web_login_failure(email=normalized_email, reason=LoginFailureReason.ACCOUNT_BANNED)
|
||||
raise AccountBannedError()
|
||||
@ -144,9 +145,9 @@ class LoginStatusApi(Resource):
|
||||
token = extract_webapp_access_token(request)
|
||||
if not app_code:
|
||||
return LoginStatusResponse(logged_in=bool(token), app_logged_in=False).model_dump(mode="json")
|
||||
app_id = AppService.get_app_id_by_code(app_code)
|
||||
app_id = AppService.get_app_id_by_code(app_code, session=db.session())
|
||||
is_public = not dify_config.ENTERPRISE_ENABLED or not WebAppAuthService.is_app_require_permission_check(
|
||||
app_id=app_id
|
||||
app_id=app_id, session=db.session()
|
||||
)
|
||||
user_logged_in = False
|
||||
|
||||
@ -211,7 +212,7 @@ class EmailCodeLoginSendEmailApi(Resource):
|
||||
else:
|
||||
language = "en-US"
|
||||
|
||||
account = WebAppAuthService.get_user_through_email(payload.email)
|
||||
account = WebAppAuthService.get_user_through_email(payload.email, db.session())
|
||||
if account is None:
|
||||
raise AuthenticationFailedError()
|
||||
token = WebAppAuthService.send_email_code_login_email(account=account, language=language)
|
||||
@ -264,7 +265,7 @@ class EmailCodeLoginApi(Resource):
|
||||
|
||||
WebAppAuthService.revoke_email_code_login_token(payload.token)
|
||||
try:
|
||||
account = WebAppAuthService.get_user_through_email(token_email)
|
||||
account = WebAppAuthService.get_user_through_email(token_email, db.session())
|
||||
except Unauthorized as exc:
|
||||
_log_web_login_failure(email=user_email, reason=LoginFailureReason.ACCOUNT_BANNED)
|
||||
raise AccountBannedError() from exc
|
||||
|
||||
@ -25,6 +25,7 @@ from controllers.web.error import (
|
||||
from controllers.web.wraps import WebApiResource
|
||||
from core.app.entities.app_invoke_entities import InvokeFrom
|
||||
from core.errors.error import ModelCurrentlyNotSupportError, ProviderTokenNotInitError, QuotaExceededError
|
||||
from extensions.ext_database import db
|
||||
from fields.conversation_fields import ResultResponse
|
||||
from fields.message_fields import SuggestedQuestionsResponse, WebMessageInfiniteScrollPagination, WebMessageListItem
|
||||
from graphon.model_runtime.errors.invoke import InvokeError
|
||||
@ -86,7 +87,7 @@ class MessageListApi(WebApiResource):
|
||||
|
||||
try:
|
||||
pagination = MessageService.pagination_by_first_id(
|
||||
app_model, end_user, query.conversation_id, query.first_id, query.limit
|
||||
app_model, end_user, query.conversation_id, query.first_id, query.limit, session=db.session()
|
||||
)
|
||||
adapter = TypeAdapter(WebMessageListItem)
|
||||
items = [adapter.validate_python(message, from_attributes=True) for message in pagination.data]
|
||||
@ -141,6 +142,7 @@ class MessageFeedbackApi(WebApiResource):
|
||||
user=end_user,
|
||||
rating=FeedbackRating(payload.rating) if payload.rating else None,
|
||||
content=payload.content,
|
||||
session=db.session(),
|
||||
)
|
||||
except MessageNotExistsError:
|
||||
raise NotFound("Message Not Exists.")
|
||||
@ -231,7 +233,11 @@ class MessageSuggestedQuestionApi(WebApiResource):
|
||||
|
||||
try:
|
||||
questions = MessageService.get_suggested_questions_after_answer(
|
||||
app_model=app_model, user=end_user, message_id=message_id_str, invoke_from=InvokeFrom.WEB_APP
|
||||
app_model=app_model,
|
||||
user=end_user,
|
||||
message_id=message_id_str,
|
||||
invoke_from=InvokeFrom.WEB_APP,
|
||||
session=db.session(),
|
||||
)
|
||||
# questions is a list of strings, not a list of Message objects
|
||||
except MessageNotExistsError:
|
||||
|
||||
@ -62,7 +62,7 @@ class PassportResource(Resource):
|
||||
raise Unauthorized("X-App-Code header is missing.")
|
||||
if system_features.webapp_auth.enabled:
|
||||
enterprise_user_decoded = decode_enterprise_webapp_user_id(access_token)
|
||||
app_auth_type = WebAppAuthService.get_app_auth_type(app_code=app_code)
|
||||
app_auth_type = WebAppAuthService.get_app_auth_type(app_code=app_code, session=db.session())
|
||||
if app_auth_type != WebAppAuthType.PUBLIC:
|
||||
if not enterprise_user_decoded:
|
||||
raise WebAppAuthRequiredError()
|
||||
|
||||
@ -44,7 +44,7 @@ class SavedMessageListApi(WebApiResource):
|
||||
query = SavedMessageListQuery.model_validate(raw_args)
|
||||
|
||||
pagination = SavedMessageService.pagination_by_last_id(
|
||||
db.session(), app_model, end_user, query.last_id, query.limit
|
||||
app_model, end_user, query.last_id, query.limit, session=db.session()
|
||||
)
|
||||
adapter = TypeAdapter(SavedMessageItem)
|
||||
items = [adapter.validate_python(message, from_attributes=True) for message in pagination.data]
|
||||
@ -80,7 +80,7 @@ class SavedMessageListApi(WebApiResource):
|
||||
payload = SavedMessageCreatePayload.model_validate(web_ns.payload or {})
|
||||
|
||||
try:
|
||||
SavedMessageService.save(db.session(), app_model, end_user, payload.message_id)
|
||||
SavedMessageService.save(app_model, end_user, payload.message_id, session=db.session())
|
||||
except MessageNotExistsError:
|
||||
raise NotFound("Message Not Exists.")
|
||||
|
||||
@ -108,6 +108,6 @@ class SavedMessageApi(WebApiResource):
|
||||
if app_model.mode != "completion":
|
||||
raise NotCompletionAppError()
|
||||
|
||||
SavedMessageService.delete(db.session(), app_model, end_user, message_id_str)
|
||||
SavedMessageService.delete(app_model, end_user, message_id_str, session=db.session())
|
||||
|
||||
return "", 204
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user