Merge remote-tracking branch 'origin/main' into feat/queue-based-graph-engine

This commit is contained in:
-LAN-
2025-09-15 15:54:42 +08:00
341 changed files with 1981 additions and 2124 deletions

View File

@ -1,5 +1,3 @@
from typing import Optional
import flask_restx
from flask_login import current_user
from flask_restx import Resource, fields, marshal_with
@ -50,7 +48,7 @@ class BaseApiKeyListResource(Resource):
method_decorators = [account_initialization_required, login_required, setup_required]
resource_type: str | None = None
resource_model: Optional[type] = None
resource_model: type | None = None
resource_id_field: str | None = None
token_prefix: str | None = None
max_keys = 10
@ -103,7 +101,7 @@ class BaseApiKeyResource(Resource):
method_decorators = [account_initialization_required, login_required, setup_required]
resource_type: str | None = None
resource_model: Optional[type] = None
resource_model: type | None = None
resource_id_field: str | None = None
def delete(self, resource_id, api_key_id):

View File

@ -1,6 +1,6 @@
from collections.abc import Callable
from functools import wraps
from typing import Optional, ParamSpec, TypeVar, Union
from typing import ParamSpec, TypeVar, Union
from controllers.console.app.error import AppNotFoundError
from extensions.ext_database import db
@ -12,7 +12,7 @@ P = ParamSpec("P")
R = TypeVar("R")
def _load_app_model(app_id: str) -> Optional[App]:
def _load_app_model(app_id: str) -> App | None:
assert isinstance(current_user, Account)
app_model = (
db.session.query(App)
@ -22,7 +22,7 @@ def _load_app_model(app_id: str) -> Optional[App]:
return app_model
def get_app_model(view: Optional[Callable[P, R]] = None, *, mode: Union[AppMode, list[AppMode], None] = None):
def get_app_model(view: Callable[P, R] | None = None, *, mode: Union[AppMode, list[AppMode], None] = None):
def decorator(view_func: Callable[P, R]):
@wraps(view_func)
def decorated_view(*args: P.args, **kwargs: P.kwargs):

View File

@ -1,5 +1,4 @@
import logging
from typing import Optional
import requests
from flask import current_app, redirect, request
@ -157,8 +156,8 @@ class OAuthCallback(Resource):
)
def _get_account_by_openid_or_email(provider: str, user_info: OAuthUserInfo) -> Optional[Account]:
account: Optional[Account] = Account.get_by_openid(provider, user_info.id)
def _get_account_by_openid_or_email(provider: str, user_info: OAuthUserInfo) -> Account | None:
account: Account | None = Account.get_by_openid(provider, user_info.id)
if not account:
with Session(db.engine) as session:

View File

@ -1,6 +1,6 @@
from collections.abc import Callable
from functools import wraps
from typing import Concatenate, Optional, ParamSpec, TypeVar
from typing import Concatenate, ParamSpec, TypeVar
from flask_login import current_user
from flask_restx import Resource
@ -20,7 +20,7 @@ R = TypeVar("R")
T = TypeVar("T")
def installed_app_required(view: Optional[Callable[Concatenate[InstalledApp, P], R]] = None):
def installed_app_required(view: Callable[Concatenate[InstalledApp, P], R] | None = None):
def decorator(view: Callable[Concatenate[InstalledApp, P], R]):
@wraps(view)
def decorated(installed_app_id: str, *args: P.args, **kwargs: P.kwargs):
@ -50,7 +50,7 @@ def installed_app_required(view: Optional[Callable[Concatenate[InstalledApp, P],
return decorator
def user_allowed_to_access_app(view: Optional[Callable[Concatenate[InstalledApp, P], R]] = None):
def user_allowed_to_access_app(view: Callable[Concatenate[InstalledApp, P], R] | None = None):
def decorator(view: Callable[Concatenate[InstalledApp, P], R]):
@wraps(view)
def decorated(installed_app: InstalledApp, *args: P.args, **kwargs: P.kwargs):

View File

@ -1,5 +1,4 @@
from mimetypes import guess_extension
from typing import Optional
from flask_restx import Resource, reqparse
from flask_restx.api import HTTPStatus
@ -73,11 +72,11 @@ class PluginUploadFileApi(Resource):
nonce: str = args["nonce"]
sign: str = args["sign"]
tenant_id: str = args["tenant_id"]
user_id: Optional[str] = args.get("user_id")
user_id: str | None = args.get("user_id")
user = get_user(tenant_id, user_id)
filename: Optional[str] = file.filename
mimetype: Optional[str] = file.mimetype
filename: str | None = file.filename
mimetype: str | None = file.mimetype
if not filename or not mimetype:
raise Forbidden("Invalid request.")

View File

@ -1,6 +1,6 @@
from collections.abc import Callable
from functools import wraps
from typing import Optional, ParamSpec, TypeVar, cast
from typing import ParamSpec, TypeVar, cast
from flask import current_app, request
from flask_login import user_logged_in
@ -54,7 +54,7 @@ def get_user(tenant_id: str, user_id: str | None) -> EndUser:
return user_model
def get_user_tenant(view: Optional[Callable[P, R]] = None):
def get_user_tenant(view: Callable[P, R] | None = None):
def decorator(view_func: Callable[P, R]):
@wraps(view_func)
def decorated_view(*args: P.args, **kwargs: P.kwargs):
@ -106,7 +106,7 @@ def get_user_tenant(view: Optional[Callable[P, R]] = None):
return decorator(view)
def plugin_data(view: Optional[Callable[P, R]] = None, *, payload_type: type[BaseModel]):
def plugin_data(view: Callable[P, R] | None = None, *, payload_type: type[BaseModel]):
def decorator(view_func: Callable[P, R]):
def decorated_view(*args: P.args, **kwargs: P.kwargs):
try:

View File

@ -1,4 +1,4 @@
from typing import Optional, Union
from typing import Union
from flask import Response
from flask_restx import Resource, reqparse
@ -73,7 +73,7 @@ class MCPAppApi(Resource):
ValidationError: Invalid request format or parameters
"""
args = mcp_request_parser.parse_args()
request_id: Optional[Union[int, str]] = args.get("id")
request_id: Union[int, str] | None = args.get("id")
mcp_request = self._parse_mcp_request(args)
with Session(db.engine, expire_on_commit=False) as session:
@ -107,7 +107,7 @@ class MCPAppApi(Resource):
def _process_mcp_message(
self,
mcp_request: mcp_types.ClientRequest | mcp_types.ClientNotification,
request_id: Optional[Union[int, str]],
request_id: Union[int, str] | None,
app: App,
mcp_server: AppMCPServer,
user_input_form: list[VariableEntity],
@ -130,7 +130,7 @@ class MCPAppApi(Resource):
def _handle_request(
self,
mcp_request: mcp_types.ClientRequest,
request_id: Optional[Union[int, str]],
request_id: Union[int, str] | None,
app: App,
mcp_server: AppMCPServer,
user_input_form: list[VariableEntity],

View File

@ -3,7 +3,7 @@ from collections.abc import Callable
from datetime import timedelta
from enum import StrEnum, auto
from functools import wraps
from typing import Concatenate, Optional, ParamSpec, TypeVar
from typing import Concatenate, ParamSpec, TypeVar
from flask import current_app, request
from flask_login import user_logged_in
@ -42,7 +42,7 @@ class FetchUserArg(BaseModel):
required: bool = False
def validate_app_token(view: Optional[Callable[P, R]] = None, *, fetch_user_arg: Optional[FetchUserArg] = None):
def validate_app_token(view: Callable[P, R] | None = None, *, fetch_user_arg: FetchUserArg | None = None):
def decorator(view_func: Callable[P, R]):
@wraps(view_func)
def decorated_view(*args: P.args, **kwargs: P.kwargs):
@ -189,7 +189,7 @@ def cloud_edition_billing_rate_limit_check(resource: str, api_token_type: str):
return interceptor
def validate_dataset_token(view: Optional[Callable[Concatenate[T, P], R]] = None):
def validate_dataset_token(view: Callable[Concatenate[T, P], R] | None = None):
def decorator(view: Callable[Concatenate[T, P], R]):
@wraps(view)
def decorated(*args: P.args, **kwargs: P.kwargs):
@ -267,7 +267,7 @@ def validate_and_get_api_token(scope: str | None = None):
return api_token
def create_or_update_end_user_for_user_id(app_model: App, user_id: Optional[str] = None) -> EndUser:
def create_or_update_end_user_for_user_id(app_model: App, user_id: str | None = None) -> EndUser:
"""
Create or update session terminal based on user ID.
"""

View File

@ -1,7 +1,7 @@
from collections.abc import Callable
from datetime import UTC, datetime
from functools import wraps
from typing import Concatenate, Optional, ParamSpec, TypeVar
from typing import Concatenate, ParamSpec, TypeVar
from flask import request
from flask_restx import Resource
@ -21,7 +21,7 @@ P = ParamSpec("P")
R = TypeVar("R")
def validate_jwt_token(view: Optional[Callable[Concatenate[App, EndUser, P], R]] = None):
def validate_jwt_token(view: Callable[Concatenate[App, EndUser, P], R] | None = None):
def decorator(view: Callable[Concatenate[App, EndUser, P], R]):
@wraps(view)
def decorated(*args: P.args, **kwargs: P.kwargs):