update: ruff check --fix

This commit is contained in:
tao.chen
2026-08-14 19:51:58 +08:00
parent d855912791
commit 25e563dcaa
50 changed files with 251 additions and 293 deletions
+3 -4
View File
@@ -2,21 +2,20 @@ from __future__ import annotations
from typing import Any, Literal
from common.auth.passwords import hash_password
from common.db.models import Roles, Users, WorkspaceMembers
from common.ids import new_ulid
from fastapi import APIRouter, Depends, HTTPException, status
from pydantic import BaseModel, ConfigDict, Field
from sqlalchemy import delete, func, or_, select
from sqlalchemy.ext.asyncio import AsyncSession
from common.db.models import Roles, Users, WorkspaceMembers
from common.ids import new_ulid
from common.auth.passwords import hash_password
from backend.dependencies import (
RequestContext,
database_session,
request_context,
)
router = APIRouter(prefix="/api/v1/admin", tags=["admin"])
+4 -5
View File
@@ -16,18 +16,17 @@ from __future__ import annotations
from typing import Any
from fastapi import APIRouter, Depends, HTTPException, Request, Response, status
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from backend.dependencies import database_session, load_user_permissions
from common.auth.jwt import JwtError, issue_jwt, verify_jwt_token
from common.auth.membership import resolve_is_system_admin
from common.auth.passwords import verify_password
from common.config import settings
from common.db.models import Roles, Users, WorkspaceMembers, Workspaces
from common.ids import new_ulid
from fastapi import APIRouter, Depends, HTTPException, Request, Response, status
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from backend.dependencies import database_session, load_user_permissions
router = APIRouter(tags=["auth"])
+4 -6
View File
@@ -27,12 +27,8 @@ for.
from __future__ import annotations
from collections.abc import AsyncIterator
from dataclasses import dataclass
from typing import AsyncIterator
from fastapi import Depends, HTTPException, Query, Request, status
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from common.auth.jwt import JwtError, verify_jwt_token
from common.auth.membership import (
@@ -43,7 +39,9 @@ from common.auth.membership import (
from common.db import session_scope
from common.db.models import Permissions, RolePermissions, Roles, Users, Workspaces
from common.ids import new_ulid
from fastapi import Depends, HTTPException, Query, Request, status
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
ACCESS_TOKEN_COOKIE = "access_token"
+2 -3
View File
@@ -1,5 +1,4 @@
import re
from typing import Optional
from common.auth.jwt import JwtError, verify_jwt_token
from common.auth.membership import MembershipError, load_active_membership
@@ -19,7 +18,7 @@ security = HTTPBearer(auto_error=False)
def extract_notebook_path(
uri: str,
workspace_id: str,
) -> Optional[str]:
) -> str | None:
"""Pull the relative notebook path out of the original request URI.
Only ``/jupyter/{workspace_id}/notebooks/*.ipynb`` requests are
@@ -83,7 +82,7 @@ async def load_active_membership_or_403(
async def verify_jupyter_access(
request: Request,
response: Response,
auth: Optional[HTTPAuthorizationCredentials] = Depends(security),
auth: HTTPAuthorizationCredentials | None = Depends(security),
session: AsyncSession = Depends(database_session),
) -> dict:
"""Nginx auth_request subrequest handler.
+6 -7
View File
@@ -65,12 +65,6 @@ import re
from dataclasses import dataclass
from typing import Any, Literal
from fastapi import APIRouter, Depends, HTTPException, Request, status
from pydantic import BaseModel, ConfigDict, Field
from sqlalchemy import func, insert, or_, select, update
from sqlalchemy.ext.asyncio import AsyncSession
from backend.dependencies import current_user, database_session
from common.auth.passwords import hash_password
from common.db.models import (
Permissions,
@@ -81,7 +75,12 @@ from common.db.models import (
Workspaces,
)
from common.ids import new_ulid
from fastapi import APIRouter, Depends, HTTPException, Request, status
from pydantic import BaseModel, ConfigDict, Field
from sqlalchemy import func, insert, or_, select, update
from sqlalchemy.ext.asyncio import AsyncSession
from backend.dependencies import current_user, database_session
router = APIRouter(prefix="/api/v1/platform", tags=["platform"])
@@ -1240,7 +1239,7 @@ async def patch_role_permissions(
__all__ = [
"router",
"SystemAdminContext",
"router",
"system_admin_context",
]
+5 -8
View File
@@ -1,23 +1,21 @@
from __future__ import annotations
import base64
import os
from datetime import UTC, datetime
from pathlib import Path, PurePosixPath
from typing import Any
from fastapi import APIRouter, Depends, Header, HTTPException, Query, Request, status
from sqlalchemy import or_, select
from sqlalchemy.ext.asyncio import AsyncSession
from common.db.models import DataResources, StorageObjects
from common.ids import new_ulid
from common.storage import workspaces_root
from common.storage.schemas import (
CreateUploadRequest,
DownloadUrlRequest,
ServerObjectRequest,
)
from fastapi import APIRouter, Depends, Header, HTTPException, Query, Request, status
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from backend.dependencies import (
RequestContext,
database_session,
@@ -27,11 +25,10 @@ from backend.schemas import (
CompleteResourceUploadRequest,
CreateResourceUploadRequest,
DownloadUrlRequest,
ResourceRelativePathRequest,
)
from backend.schemas import ResourceRelativePathRequest
from backend.services.storage import (
create_download_url_payload,
create_server_object_payload,
create_upload_record,
soft_delete_object,
upload_bytes_to_session,
+1
View File
@@ -6,6 +6,7 @@ from typing import Any
import httpx
from loguru import logger
@dataclass(frozen=True)
class RuntimeClientError(Exception):
status_code: int
+16 -18
View File
@@ -4,6 +4,22 @@ from datetime import UTC, datetime
from typing import Any, Literal
from urllib.parse import quote
from common.config import settings
from common.db.models import (
ScheduleNodeRuns,
ScheduleRuns,
StorageObjects,
)
from common.scheduler import (
DagTooLarge,
InvalidDag,
InvalidNodeArguments,
ScheduleNotFound,
TriggerError,
create_scheduled_run,
normalize_idempotency_key,
)
from common.schemas import StrictModel
from fastapi import (
APIRouter,
Depends,
@@ -18,29 +34,11 @@ from pydantic import Field
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from common.config import settings
from common.db.models import (
ScheduleNodeRuns,
ScheduleRuns,
StorageObjects,
)
from backend.dependencies import (
RequestContext,
database_session,
request_context,
)
from common.schemas import StrictModel
from common.scheduler import (
DagTooLarge,
InvalidDag,
InvalidNodeArguments,
ScheduleNotFound,
TriggerError,
create_scheduled_run,
normalize_idempotency_key,
)
from common.ids import new_ulid
router = APIRouter(tags=["schedule-runs"])
RunStatus = Literal[
+7 -8
View File
@@ -3,10 +3,9 @@ from __future__ import annotations
from datetime import datetime
from typing import Any
from pydantic import Field, field_validator, model_validator
from common.db.models.schedules import FailurePolicy, PythonVersion, TriggerType
from common.schemas import StrictModel
from pydantic import Field, field_validator, model_validator
def _required_text(value: str) -> str:
@@ -40,7 +39,7 @@ class CreateScheduleRequest(StrictModel):
return normalized or None
@model_validator(mode="after")
def validate_trigger(self) -> "CreateScheduleRequest":
def validate_trigger(self) -> CreateScheduleRequest:
if self.trigger_type == "cron" and not self.cron_expression:
raise ValueError("cron_expression is required for cron schedules")
if self.trigger_type != "cron" and self.cron_expression:
@@ -78,17 +77,17 @@ class UpdateScheduleRequest(StrictModel):
return normalized or None
@model_validator(mode="after")
def require_change(self) -> "UpdateScheduleRequest":
def require_change(self) -> UpdateScheduleRequest:
if self.model_fields_set == {"workflow_version"}:
raise ValueError("at least one schedule field must be updated")
for field in {
for field in (
"schedule_name",
"trigger_type",
"timezone",
"enabled",
"max_concurrency",
"failure_policy",
}:
):
if field in self.model_fields_set and getattr(self, field) is None:
raise ValueError(f"{field} cannot be null")
return self
@@ -158,7 +157,7 @@ class UpdateScheduleNodeRequest(StrictModel):
return _required_text(value) if value is not None else None
@model_validator(mode="after")
def require_change(self) -> "UpdateScheduleNodeRequest":
def require_change(self) -> UpdateScheduleNodeRequest:
if self.model_fields_set == {"workflow_version"}:
raise ValueError("at least one node field must be updated")
for field in self.model_fields_set - {"workflow_version"}:
@@ -182,7 +181,7 @@ class CreateScheduleEdgeRequest(StrictModel):
return normalized or None
@model_validator(mode="after")
def reject_self_edge(self) -> "CreateScheduleEdgeRequest":
def reject_self_edge(self) -> CreateScheduleEdgeRequest:
if self.source_node_id == self.target_node_id:
raise ValueError("an edge cannot connect a node to itself")
return self
+5 -6
View File
@@ -6,11 +6,6 @@ from decimal import Decimal
from typing import Any
from zoneinfo import ZoneInfo, ZoneInfoNotFoundError
from croniter import CroniterBadCronError, croniter
from fastapi import APIRouter, Depends, HTTPException, Query, status
from sqlalchemy import delete, func, or_, select
from sqlalchemy.ext.asyncio import AsyncSession
from common.db.models import (
ScheduleEdges,
ScheduleNodeRuns,
@@ -20,6 +15,11 @@ from common.db.models import (
Versions,
)
from common.ids import new_ulid
from croniter import CroniterBadCronError, croniter
from fastapi import APIRouter, Depends, HTTPException, Query, status
from sqlalchemy import delete, func, or_, select
from sqlalchemy.ext.asyncio import AsyncSession
from backend.dependencies import (
RequestContext,
database_session,
@@ -36,7 +36,6 @@ from backend.schedule_schemas import (
WorkflowVersionRequest,
)
router = APIRouter(tags=["schedules"])
+3 -7
View File
@@ -1,4 +1,3 @@
import asyncio
import base64
import hashlib
import json
@@ -15,13 +14,12 @@ from common.db.models import (
Versions,
)
from common.ids import new_ulid
from common.storage.schemas import ServerObjectRequest
from common.storage import actual_bucket_name, build_storage_uri
from common.storage.schemas import ServerObjectRequest
from fastapi import (
APIRouter,
BackgroundTasks,
Depends,
Header,
HTTPException,
Query,
Request,
@@ -46,10 +44,10 @@ from backend.schemas import (
UpdateScriptRequest,
)
from backend.services.storage import (
_resolve_unique_object_key,
create_download_url_payload,
create_server_object_payload,
soft_delete_object,
_resolve_unique_object_key,
)
router = APIRouter(tags=["scripts"])
@@ -202,9 +200,7 @@ def script_payload(
workspace_prefix = f"{script.workspace_id}/"
if object_key:
jupyter_path = (
object_key[len(workspace_prefix) :]
if object_key.startswith(workspace_prefix)
else object_key
object_key.removeprefix(workspace_prefix)
)
else:
jupyter_path = _jupyter_path(script.script_type, script.script_id)
+8 -10
View File
@@ -35,21 +35,19 @@ from datetime import timedelta
from pathlib import PurePosixPath
from typing import Any
from fastapi import HTTPException, Request, status
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.exc import IntegrityError
from common.config import settings
from common.db.models import StorageObjects, UploadSessions
from common.ids import new_ulid
from common.storage import USAGE_TYPE_TO_PURPOSE, actual_bucket_name, build_storage_uri
from common.storage.schemas import (
CreateUploadRequest,
DownloadUrlRequest,
ServerObjectRequest,
)
from common.storage import USAGE_TYPE_TO_PURPOSE, actual_bucket_name, build_storage_uri
from fastapi import HTTPException, Request, status
from sqlalchemy import select
from sqlalchemy.exc import IntegrityError
from sqlalchemy.ext.asyncio import AsyncSession
# ── shared low-level helpers (module-private) ────────────────────────────
@@ -91,7 +89,7 @@ def _safe_path_segment(segment: str) -> str:
def _utcnow_naive() -> Any:
from datetime import datetime, UTC
from datetime import UTC, datetime
return datetime.now(UTC).replace(tzinfo=None)
@@ -207,9 +205,8 @@ async def create_upload_record(
when the idempotency key hits an already-completed upload.
"""
from backend.storage_api import (
require_workspace_member,
normalized_idempotency_key,
BUCKET_FOR_USAGE,
require_workspace_member,
)
workspace = await require_workspace_member(
@@ -236,6 +233,7 @@ async def create_upload_record(
upload = existing
else:
from datetime import timedelta
from backend.storage_api import utcnow
bucket_name = _resolve_bucket_for_usage(
+7 -6
View File
@@ -1,13 +1,10 @@
from __future__ import annotations
import hashlib
from collections.abc import AsyncIterator
from datetime import UTC, datetime, timedelta
from pathlib import PurePosixPath
from typing import Any, AsyncIterator
from fastapi import APIRouter, Depends, HTTPException, Request, status
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from typing import Any
from common.config import settings
from common.db import session_scope
@@ -25,6 +22,10 @@ from common.storage.schemas import (
DownloadUrlRequest,
ServerObjectRequest,
)
from fastapi import APIRouter, Depends, HTTPException, Request, status
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from backend.services.storage import (
create_download_url_payload,
create_server_object_payload,
@@ -44,7 +45,7 @@ def hash_bytes(value: str) -> bytes:
def normalized_idempotency_key(workspace_id: str, user_id: str, value: str) -> str:
digest = hashlib.sha256(
f"{workspace_id}:{user_id}:{value}".encode("utf-8")
f"{workspace_id}:{user_id}:{value}".encode()
).hexdigest()
return f"v1:{digest}"