Skip to content

Commit

Permalink
added upload logic
Browse files Browse the repository at this point in the history
Signed-off-by: Prati28 <[email protected]>
  • Loading branch information
psankhe28 committed Oct 25, 2024
1 parent 0b08ba9 commit f8100c8
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 2 deletions.
71 changes: 70 additions & 1 deletion cloud_storage_handler/api/elixircloud/csh/controllers.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,84 @@
"""ELIXIR's Cloud Storage Handler controllers."""

import logging
import os
import uuid
from http import HTTPStatus

from flask import jsonify
from flask import current_app, jsonify, request
from minio.error import S3Error

logger = logging.getLogger(__name__)

UPLOAD_DIRECTORY = "/tmp/upload"
CHUNK_SIZE = 5 * 1024 * 1024


def home():
"""Endpoint to return a welcome message."""
return jsonify(
{"message": "Welcome to the Cloud Storage Handler server!"}
), HTTPStatus.OK


def upload_object():
"""Handles file uploads to cloud storage.
Retrieves files from the request, processes each file into chunks,
and uploads them to the specified storage bucket. Returns a response
with a success message and details about the uploaded file(s).
"""
files = request.files.getlist("files")
responses = []
minio_config = current_app.config.foca.custom.minio
bucket_name = minio_config.bucket_name
minio_client = current_app.config.foca.custom.minio.client.client

for file in files:
if not file:
return jsonify({"error": "No file provided"}), 400

file_id = str(uuid.uuid4())
file_path = os.path.join(UPLOAD_DIRECTORY, f"{file_id}.temp")

file.save(file_path)

total_size = os.path.getsize(file_path)
total_chunks = (total_size // CHUNK_SIZE) + (
1 if total_size % CHUNK_SIZE > 0 else 0
)

file_dir = os.path.join(UPLOAD_DIRECTORY, file_id)
os.makedirs(file_dir, exist_ok=True)

with open(file_path, "rb") as f:
for i in range(total_chunks):
chunk_data = f.read(CHUNK_SIZE)
chunk_filename = os.path.join(file_dir, f"chunk_{i}")
with open(chunk_filename, "wb") as chunk_file:
chunk_file.write(chunk_data)

try:
minio_client.fput_object(
bucket_name,
f"{file_id}/chunk_{i}",
chunk_filename,
metadata={
"description": "Chunk upload via Flask",
},
)
except S3Error as e:
return jsonify({"error": str(e)}), 500

os.remove(file_path)
os.rmdir(file_dir)

responses.append(
{
"message": "File uploaded successfully",
"file_id": file_id,
"total_chunks": total_chunks,
}
)

return jsonify(responses), 200
34 changes: 33 additions & 1 deletion cloud_storage_handler/api/specs/specs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,36 @@ paths:
description: The request is malformed.
'500':
description: An unexpected error occurred.
...
/object:
post:
description: |
Create a new object upload using the TUS protocol. The request creates an empty object and returns an upload URL.

Check failure on line 41 in cloud_storage_handler/api/specs/specs.yaml

View workflow job for this annotation

GitHub Actions / Pre-commit checks

41:81 [line-length] line too long (121 > 80 characters)

Check failure on line 41 in cloud_storage_handler/api/specs/specs.yaml

View workflow job for this annotation

GitHub Actions / Pre-commit checks

41:81 [line-length] line too long (121 > 80 characters)
operationId: upload_object
requestBody:
required: true
content:
multipart/form-data:
schema:
type: object
properties:
file:
type: string
format: binary
description: The file to be uploaded (supports .bib, .txt, .docx, and other file types).

Check failure on line 53 in cloud_storage_handler/api/specs/specs.yaml

View workflow job for this annotation

GitHub Actions / Pre-commit checks

53:81 [line-length] line too long (106 > 80 characters)

Check failure on line 53 in cloud_storage_handler/api/specs/specs.yaml

View workflow job for this annotation

GitHub Actions / Pre-commit checks

53:81 [line-length] line too long (106 > 80 characters)
responses:
'201':
description: Object upload created successfully.
headers:
Location:
schema:
type: string
description: URL to upload object chunks using PATCH requests.
Tus-Resumable:
schema:
type: string
description: Version of the TUS protocol used.
'400':
description: Bad request or malformed request body.
'500':
description: An unexpected error occurred.
...

0 comments on commit f8100c8

Please sign in to comment.