fix: script not found
This commit is contained in:
@@ -21,6 +21,7 @@ from fastapi import (
|
|||||||
from sqlalchemy import func, select
|
from sqlalchemy import func, select
|
||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
|
|
||||||
|
from common.config import settings
|
||||||
from common.db.models import (
|
from common.db.models import (
|
||||||
Scripts,
|
Scripts,
|
||||||
StorageObjects,
|
StorageObjects,
|
||||||
@@ -356,19 +357,40 @@ async def create_script_record(
|
|||||||
detail=exc.detail,
|
detail=exc.detail,
|
||||||
) from exc
|
) from exc
|
||||||
|
|
||||||
# Synthesise a storage_data-shaped dict from the Jupyter response
|
# Build a real StorageObjects row so the file participates in
|
||||||
# so the existing script_payload + response shape keep working.
|
# workspace-tree / list / get queries that JOIN this table. The
|
||||||
# The storage_object_id is a fresh ULID — there is no real
|
# bytes live in the Jupyter mount; rclone replicates them to
|
||||||
# StorageObject row for this file; downstream list/get operations
|
# RustFS asynchronously. We mark the row "available" because the
|
||||||
# that JOIN StorageObjects will skip jupyter-only scripts.
|
# file is queryable as a workspace file from the user's POV; the
|
||||||
|
# storage_uri points at where the replicated bytes will land.
|
||||||
object_id = new_ulid()
|
object_id = new_ulid()
|
||||||
storage_data = {
|
object_key = f"{workspace_id}/{jupyter_name}"
|
||||||
"storage_object_id": object_id,
|
bucket_name = settings.rustfs_workspace_bucket
|
||||||
"relative_path": jupyter_name,
|
relative_path = user_relative_path(context, jupyter_name)
|
||||||
"object_key": f"{workspace_id}/{jupyter_name}",
|
mime_type = mimetypes.guess_type(jupyter_name)[0]
|
||||||
"content_hash": content_hash,
|
storage_object = StorageObjects(
|
||||||
"size_bytes": size_bytes,
|
storage_object_id=object_id,
|
||||||
}
|
workspace_id=context.workspace.workspace_id,
|
||||||
|
owner_user_id=context.user.user_id,
|
||||||
|
object_type="file",
|
||||||
|
usage_type="working_copy",
|
||||||
|
storage_backend="rustfs",
|
||||||
|
bucket_name=bucket_name,
|
||||||
|
object_key=object_key,
|
||||||
|
object_key_hash=hashlib.sha256(object_key.encode("utf-8")).digest(),
|
||||||
|
storage_uri=f"s3://{bucket_name}/{object_key}",
|
||||||
|
file_name=name,
|
||||||
|
file_extension=PurePosixPath(jupyter_name).suffix.lower() or None,
|
||||||
|
mime_type=mime_type,
|
||||||
|
size_bytes=size_bytes,
|
||||||
|
content_hash=content_hash,
|
||||||
|
visibility=visibility,
|
||||||
|
is_immutable=0,
|
||||||
|
object_status="available",
|
||||||
|
created_by=context.user.user_id,
|
||||||
|
relative_path=relative_path,
|
||||||
|
path_hash=hashlib.sha256(relative_path.encode("utf-8")).digest(),
|
||||||
|
)
|
||||||
script = Scripts(
|
script = Scripts(
|
||||||
script_id=script_id,
|
script_id=script_id,
|
||||||
workspace_id=context.workspace.workspace_id,
|
workspace_id=context.workspace.workspace_id,
|
||||||
@@ -379,10 +401,12 @@ async def create_script_record(
|
|||||||
visibility=visibility,
|
visibility=visibility,
|
||||||
status="active",
|
status="active",
|
||||||
)
|
)
|
||||||
|
session.add(storage_object)
|
||||||
session.add(script)
|
session.add(script)
|
||||||
await session.flush()
|
await session.flush()
|
||||||
|
await session.refresh(storage_object)
|
||||||
await session.refresh(script)
|
await session.refresh(script)
|
||||||
return script, storage_data
|
return script, storage_object
|
||||||
|
|
||||||
|
|
||||||
@router.post("/api/v1/scripts", status_code=status.HTTP_201_CREATED)
|
@router.post("/api/v1/scripts", status_code=status.HTTP_201_CREATED)
|
||||||
|
|||||||
@@ -222,7 +222,6 @@ export function useApi(): WorkspaceBoundApi {
|
|||||||
rawApi.createJupyterAccessTicket(workspaceId, session),
|
rawApi.createJupyterAccessTicket(workspaceId, session),
|
||||||
getLatestScriptVersion: (scriptId) =>
|
getLatestScriptVersion: (scriptId) =>
|
||||||
rawApi.getLatestScriptVersion(workspaceId, scriptId),
|
rawApi.getLatestScriptVersion(workspaceId, scriptId),
|
||||||
listScriptVersions: (scriptId) => rawApi.listScriptVersions(workspaceId, scriptId),
|
|
||||||
publishScriptVersion: (input) => rawApi.publishScriptVersion(workspaceId, input),
|
publishScriptVersion: (input) => rawApi.publishScriptVersion(workspaceId, input),
|
||||||
listSchedules: () => rawApi.listSchedules(workspaceId),
|
listSchedules: () => rawApi.listSchedules(workspaceId),
|
||||||
getSchedule: (scheduleId) => rawApi.getSchedule(workspaceId, scheduleId),
|
getSchedule: (scheduleId) => rawApi.getSchedule(workspaceId, scheduleId),
|
||||||
|
|||||||
@@ -162,8 +162,6 @@ function AuthenticatedModelPlatformApp() {
|
|||||||
scriptId: string;
|
scriptId: string;
|
||||||
message: string;
|
message: string;
|
||||||
} | null>(null);
|
} | null>(null);
|
||||||
const [versions, setVersions] = useState<StableVersion[]>([]);
|
|
||||||
const [versionsLoading, setVersionsLoading] = useState(false);
|
|
||||||
const [latestVersion, setLatestVersion] = useState<LatestVersion | null>(
|
const [latestVersion, setLatestVersion] = useState<LatestVersion | null>(
|
||||||
null,
|
null,
|
||||||
);
|
);
|
||||||
@@ -248,12 +246,10 @@ function AuthenticatedModelPlatformApp() {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!selectedId) {
|
if (!selectedId) {
|
||||||
setVersions([]);
|
|
||||||
setLatestVersion(null);
|
setLatestVersion(null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let ignore = false;
|
let ignore = false;
|
||||||
setVersionsLoading(true);
|
|
||||||
setLatestVersionLoading(true);
|
setLatestVersionLoading(true);
|
||||||
void api.getLatestScriptVersion(selectedId)
|
void api.getLatestScriptVersion(selectedId)
|
||||||
.then((item) => {
|
.then((item) => {
|
||||||
@@ -273,21 +269,6 @@ function AuthenticatedModelPlatformApp() {
|
|||||||
.finally(() => {
|
.finally(() => {
|
||||||
if (!ignore) setLatestVersionLoading(false);
|
if (!ignore) setLatestVersionLoading(false);
|
||||||
});
|
});
|
||||||
void api.listScriptVersions(selectedId)
|
|
||||||
.then((items) => {
|
|
||||||
if (!ignore) setVersions(items);
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
if (!ignore) {
|
|
||||||
setToast({
|
|
||||||
tone: "error",
|
|
||||||
message: error instanceof Error ? error.message : "版本列表加载失败",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
if (!ignore) setVersionsLoading(false);
|
|
||||||
});
|
|
||||||
return () => {
|
return () => {
|
||||||
ignore = true;
|
ignore = true;
|
||||||
};
|
};
|
||||||
@@ -595,10 +576,6 @@ function AuthenticatedModelPlatformApp() {
|
|||||||
releaseNote,
|
releaseNote,
|
||||||
visibility: publishVisibility,
|
visibility: publishVisibility,
|
||||||
});
|
});
|
||||||
setVersions((items) => [
|
|
||||||
version,
|
|
||||||
...items.filter((item) => item.versions_id !== version.versions_id),
|
|
||||||
]);
|
|
||||||
setPublishTarget(null);
|
setPublishTarget(null);
|
||||||
setPublishedVersion(version);
|
setPublishedVersion(version);
|
||||||
setToast({
|
setToast({
|
||||||
|
|||||||
@@ -574,17 +574,6 @@ export async function getLatestScriptVersion(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function listScriptVersions(
|
|
||||||
workspaceId: string,
|
|
||||||
scriptId: string,
|
|
||||||
): Promise<StableVersion[]> {
|
|
||||||
return apiRequest<StableVersion[]>(
|
|
||||||
`/api/v1/scripts/${scriptId}/versions`,
|
|
||||||
{},
|
|
||||||
workspaceId,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function publishScriptVersion(
|
export async function publishScriptVersion(
|
||||||
workspaceId: string,
|
workspaceId: string,
|
||||||
input: {
|
input: {
|
||||||
@@ -1119,7 +1108,6 @@ export type WorkspaceBoundApi = {
|
|||||||
session: ActiveEditSession,
|
session: ActiveEditSession,
|
||||||
) => Promise<JupyterAccessTicket>;
|
) => Promise<JupyterAccessTicket>;
|
||||||
getLatestScriptVersion: (scriptId: string) => Promise<LatestVersion | null>;
|
getLatestScriptVersion: (scriptId: string) => Promise<LatestVersion | null>;
|
||||||
listScriptVersions: (scriptId: string) => Promise<StableVersion[]>;
|
|
||||||
publishScriptVersion: (
|
publishScriptVersion: (
|
||||||
input: Parameters<typeof publishScriptVersion>[1],
|
input: Parameters<typeof publishScriptVersion>[1],
|
||||||
) => Promise<StableVersion>;
|
) => Promise<StableVersion>;
|
||||||
|
|||||||
Reference in New Issue
Block a user