Develop #16
@@ -371,7 +371,7 @@ async def upload_script(
|
||||
context: RequestContext = Depends(request_context),
|
||||
session: AsyncSession = Depends(database_session),
|
||||
) -> dict[str, Any]:
|
||||
suffix = Path(file_name).suffix.lower()
|
||||
suffix = PurePosixPath(file_name).suffix.lower()
|
||||
if suffix not in {".py", ".ipynb"}:
|
||||
raise HTTPException(
|
||||
status.HTTP_422_UNPROCESSABLE_ENTITY,
|
||||
@@ -637,6 +637,7 @@ async def update_script(
|
||||
status.HTTP_409_CONFLICT,
|
||||
"script has no workspace path",
|
||||
)
|
||||
old_object_id = script.current_object_id
|
||||
storage_data = await request.app.state.storage_client.create_server_object(
|
||||
workspace_id=context.workspace.workspace_id,
|
||||
user_id=script.owner_user_id,
|
||||
@@ -653,12 +654,16 @@ async def update_script(
|
||||
f"{hashlib.sha256(content).hexdigest()}"
|
||||
),
|
||||
)
|
||||
storage_object.content_hash = storage_data["content_hash"]
|
||||
storage_object.size_bytes = storage_data["size_bytes"]
|
||||
script.current_object_id = storage_data["storage_object_id"]
|
||||
script.updated_at = datetime.now(UTC).replace(tzinfo=None)
|
||||
if old_object_id != script.current_object_id:
|
||||
try:
|
||||
await request.app.state.storage_client.delete_object(old_object_id)
|
||||
except Exception:
|
||||
pass
|
||||
return {
|
||||
"request_id": context.request_id,
|
||||
"data": script_payload(script, storage_object),
|
||||
"data": script_payload(script, storage_data),
|
||||
"meta": {},
|
||||
}
|
||||
|
||||
@@ -738,18 +743,11 @@ async def publish_version(
|
||||
"script working copy is not stored in object storage",
|
||||
)
|
||||
|
||||
def read_object_bytes() -> bytes:
|
||||
response = request.app.state.object_store.get_object(
|
||||
Bucket=source_object.bucket_name,
|
||||
Key=source_object.object_key,
|
||||
)
|
||||
body = response["Body"]
|
||||
try:
|
||||
return body.read()
|
||||
finally:
|
||||
body.close()
|
||||
|
||||
content = await asyncio.to_thread(read_object_bytes)
|
||||
content = await asyncio.to_thread(
|
||||
request.app.state.object_store.get_bytes,
|
||||
bucket_name=source_object.bucket_name,
|
||||
object_key=source_object.object_key,
|
||||
)
|
||||
content_hash = hashlib.sha256(content).hexdigest()
|
||||
existing = await session.scalar(
|
||||
select(Versions).where(
|
||||
|
||||
@@ -366,7 +366,7 @@ async def complete_upload_record(
|
||||
object_key_hash=upload.object_key_hash,
|
||||
storage_uri=f"s3://{upload.bucket_name}/{upload.object_key}",
|
||||
file_name=file_name,
|
||||
file_extension=Path(file_name).suffix.lower() or None,
|
||||
file_extension=PurePosixPath(file_name).suffix.lower() or None,
|
||||
mime_type=actual_content_type,
|
||||
size_bytes=actual_size,
|
||||
content_hash=actual_hash,
|
||||
|
||||
@@ -137,6 +137,14 @@ class RustFSObjectStore:
|
||||
def head(self, *, bucket_name: str, object_key: str) -> dict[str, Any]:
|
||||
return self.internal.head_object(Bucket=bucket_name, Key=object_key)
|
||||
|
||||
def get_bytes(self, *, bucket_name: str, object_key: str) -> bytes:
|
||||
response = self.internal.get_object(Bucket=bucket_name, Key=object_key)
|
||||
body: BinaryIO = response["Body"]
|
||||
try:
|
||||
return body.read()
|
||||
finally:
|
||||
body.close()
|
||||
|
||||
def sha256(self, *, bucket_name: str, object_key: str) -> str:
|
||||
response = self.internal.get_object(Bucket=bucket_name, Key=object_key)
|
||||
body: BinaryIO = response["Body"]
|
||||
|
||||
Reference in New Issue
Block a user