Use client-logic to run upload tool

It is pretty cool to use hooks and an alternative tool submission
endpoint, but this is less invasive. We'd have to do this anyway for
cases where the upload is already on the server and the pre-finish hook
doesn't fire.
This commit is contained in:
mvdbeek
2021-10-12 13:43:45 +02:00
parent 81f24c3456
commit 600f59b0ee
8 changed files with 105 additions and 90 deletions
+38 -14
View File
@@ -1,9 +1,15 @@
import json
import os
import aiotus
import asyncclick as click
import click
import requests
from tusclient import client
from tusclient.storage import filestorage
UPLOAD_ENDPOINT = '/api/upload/resumable_upload'
TOOLS_ENDPOINT = '/api/tools'
CHUNK_SIZE = 10 ** 7
@click.command()
@@ -13,25 +19,43 @@ UPLOAD_ENDPOINT = '/api/upload/resumable_upload'
@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())
async def upload_file(url, path, api_key, history_id, file_type='auto', dbkey='?', filename=None):
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.encode(),
'history_id': history_id.encode(),
'file_type': file_type.encode(),
'dbkey': dbkey.encode(),
'filename': filename,
'history_id': history_id,
'file_type': file_type,
'dbkey': dbkey,
}
headers = {'x-api-key': api_key}
# Upload a file to a tus server.
with open(path, "rb") as f:
location = await aiotus.upload(f"{url}{UPLOAD_ENDPOINT}", f, metadata, headers=headers)
# 'location' is the URL where the file was uploaded to.
if storage:
storage = filestorage.FileStorage(storage)
uploader = my_client.uploader(path, metadata=metadata, url_storage=storage)
uploader.chunk_size = CHUNK_SIZE
uploader.upload()
# Read back the metadata from the server.
metadata = await aiotus.metadata(location, headers=headers)
print(metadata)
# Extract session from created upload URL
session_id = uploader.url.rsplit('/', 1)[1]
# This feels a bit more user-friendly ?
tool_id = 'upload1'
inputs = {
"file_count": 1,
"dbkey": dbkey,
"file_type": "auto",
"files_0|type": "upload_dataset",
"files_0|NAME": filename,
"files_0|to_posix_lines": "Yes",
"files_0|dbkey": dbkey,
"files_0|file_type": file_type,
"files_0|file_data": {"session_id": session_id, "name": filename}}
tool_payload = {'tool_id': tool_id, 'inputs': inputs, 'history_id': history_id}
response = requests.post(f"{url}{TOOLS_ENDPOINT}", data=json.dumps(tool_payload), headers=headers)
response.raise_for_status()
if __name__ == '__main__':