Files
galaxy/scripts/resumable_upload.py
T
mvdbeek 9f463b6f82 Adapt scripts/resumable_upload.py to fetch API
Finding out that the `files` parameter is required took way more time
than I want to admit ... .
2021-10-13 18:05:42 +02:00

66 lines
2.3 KiB
Python

import json
import os
import click
import requests
from tusclient import client
from tusclient.storage import filestorage
UPLOAD_ENDPOINT = '/api/upload/resumable_upload'
SUBMISSION_ENDPOINT = '/api/tools/fetch'
CHUNK_SIZE = 10 ** 7
@click.command()
@click.option("--url", default='http://localhost:8080', help="URL of Galaxy instance")
@click.option("--api_key", envvar="GALAXY_API_KEY", required=True, help="API key for Galaxy instance")
@click.option('--history_id', type=str, required=True, help="Target History ID")
@click.option('--file_type', default="auto", type=str, help="Galaxy file type to use")
@click.option('--dbkey', default="?", type=str, help="Genome Build for dataset")
@click.option('--filename', type=str, help="Filename to use in Galaxy history, if different from path")
@click.option('--storage', type=click.Path(), required=False, help="Store URLs to resume here")
@click.argument('path', type=click.Path())
def upload_file(url, path, api_key, history_id, file_type='auto', dbkey='?', filename=None, storage=None):
headers = {'x-api-key': api_key}
my_client = client.TusClient(f"{url}{UPLOAD_ENDPOINT}", headers=headers)
filename = filename or os.path.basename(path)
metadata = {
'filename': filename,
'history_id': history_id,
'file_type': file_type,
'dbkey': dbkey,
}
# Upload a file to a tus server.
if storage:
storage = filestorage.FileStorage(storage)
uploader = my_client.uploader(path, metadata=metadata, url_storage=storage)
uploader.chunk_size = CHUNK_SIZE
uploader.upload()
# Extract session from created upload URL
session_id = uploader.url.rsplit('/', 1)[1]
payload = {
'history_id': history_id,
'targets': json.dumps([
{
"destination": {"type": "hdas"},
"elements": [
{
"src": "files",
"ext": file_type,
"dbkey": dbkey,
"name": filename
}
]
}
]),
}
response = requests.post(f"{url}{SUBMISSION_ENDPOINT}", data=payload, files={'files_0|file_data': json.dumps({"session_id": session_id})}, headers=headers)
response.raise_for_status()
if __name__ == '__main__':
upload_file()