Instantly share code, notes, and snippets.
Last active
March 29, 2021 14:12
-
Star
(0)
0
You must be signed in to star a gist -
Fork
(0)
0
You must be signed in to fork a gist
-
Save oeway/0f19fe2508656bc56a24909e5f9bfc46 to your computer and use it in GitHub Desktop.
Python script for uploading files to figshare
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
''' | |
Uploading files to figshare | |
https://docs.figshare.com/#upload_files_example_upload_on_figshare | |
''' | |
import hashlib | |
import json | |
import os | |
import requests | |
from requests.exceptions import HTTPError | |
BASE_URL = 'https://api.figshare.com/v2/{endpoint}' | |
TOKEN = '' # paste your personal token here | |
CHUNK_SIZE = 1048576 | |
TITLE = 'My Data' | |
FILE_PATH = '/path/to/my/file' | |
def raw_issue_request(method, url, data=None, binary=False): | |
headers = {'Authorization': 'token ' + TOKEN } | |
if data is not None and not binary: | |
data = json.dumps(data) | |
response = requests.request(method, url, headers=headers, data=data) | |
try: | |
response.raise_for_status() | |
try: | |
data = json.loads(response.content) | |
except ValueError: | |
data = response.content | |
except HTTPError as error: | |
print('Caught an HTTPError: {}'.format(error)) | |
print('Body:\n', response.content) | |
raise | |
return data | |
def issue_request(method, endpoint, *args, **kwargs): | |
return raw_issue_request(method, BASE_URL.format(endpoint=endpoint), *args, **kwargs) | |
def list_articles(): | |
result = issue_request('GET', 'account/articles') | |
print('Listing current articles:') | |
if result: | |
for item in result: | |
print(u'{}'.format(item)) | |
else: | |
print(' No articles.') | |
print() | |
def create_article(title): | |
data = { | |
'title': title # You may add any other information about the article here as you wish. | |
} | |
result = issue_request('POST', 'account/articles', data=data) | |
print('Created article:', result['location'], '\n') | |
result = raw_issue_request('GET', result['location']) | |
return result['id'] | |
def list_files_of_article(article_id): | |
result = issue_request('GET', 'account/articles/{}/files'.format(article_id)) | |
print('Listing files for article {}:'.format(article_id)) | |
if result: | |
for item in result: | |
print(' {id} - {name}'.format(**item)) | |
else: | |
print(' No files.') | |
print() | |
def get_file_check_data(file_name): | |
with open(file_name, 'rb') as fin: | |
md5 = hashlib.md5() | |
size = 0 | |
data = fin.read(CHUNK_SIZE) | |
while data: | |
size += len(data) | |
md5.update(data) | |
data = fin.read(CHUNK_SIZE) | |
return md5.hexdigest(), size | |
def initiate_new_upload(article_id, file_name): | |
endpoint = 'account/articles/{}/files' | |
endpoint = endpoint.format(article_id) | |
md5, size = get_file_check_data(file_name) | |
data = {'name': os.path.basename(file_name), | |
'md5': md5, | |
'size': size} | |
result = issue_request('POST', endpoint, data=data) | |
print('Initiated file upload:', result['location'], '\n') | |
result = raw_issue_request('GET', result['location']) | |
return result | |
def complete_upload(article_id, file_id): | |
issue_request('POST', 'account/articles/{}/files/{}'.format(article_id, file_id)) | |
def upload_parts(file_info, file_path): | |
url = '{upload_url}'.format(**file_info) | |
result = raw_issue_request('GET', url) | |
print('Uploading parts:') | |
with open(file_path, 'rb') as fin: | |
for part in result['parts']: | |
upload_part(file_info, fin, part) | |
print() | |
def upload_part(file_info, stream, part): | |
udata = file_info.copy() | |
udata.update(part) | |
url = '{upload_url}/{partNo}'.format(**udata) | |
stream.seek(part['startOffset']) | |
data = stream.read(part['endOffset'] - part['startOffset'] + 1) | |
raw_issue_request('PUT', url, data=data, binary=True) | |
print(' Uploaded part {partNo} from {startOffset} to {endOffset}'.format(**part)) | |
def main(): | |
# We first create the article | |
list_articles() | |
article_id = create_article(TITLE) | |
# article_id = '14308046' | |
list_articles() | |
list_files_of_article(article_id) | |
# Then we upload the file. | |
file_info = initiate_new_upload(article_id, FILE_PATH) | |
# Until here we used the figshare API; following lines use the figshare upload service API. | |
upload_parts(file_info, FILE_PATH) | |
# We return to the figshare API to complete the file upload process. | |
complete_upload(article_id, file_info['id']) | |
list_files_of_article(article_id) | |
if __name__ == '__main__': | |
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<docs> | |
[TODO: write documentation for this plugin.] | |
</docs> | |
<config lang="json"> | |
{ | |
"name": "VizarrFigshare", | |
"type": "web-worker", | |
"tags": [], | |
"ui": "", | |
"version": "0.1.0", | |
"cover": "", | |
"description": "Reading Vizarr using reference store", | |
"icon": "extension", | |
"inputs": null, | |
"outputs": null, | |
"api_version": "0.1.8", | |
"env": "", | |
"permissions": [], | |
"requirements": ["https://unpkg.com/zarr@0.4.0/zarr.umd.js"], | |
"dependencies": [] | |
} | |
</config> | |
<script lang="javascript"> | |
// Using the FileReferenceStore made by Trevor Manz | |
// https://observablehq.com/d/a417a770860fbb64 | |
class FileReferenceStore { | |
constructor(ref, target) { | |
this.ref = ref; | |
this.target = target; | |
} | |
_url(urlPath) { | |
if(!urlPath){ | |
return this.target | |
} | |
const [protocol, path] = urlPath.split('://'); | |
if (protocol === 'https' || protocol === 'http') { | |
return urlPath; | |
} | |
if (protocol === 'gc') { | |
return 'https://storage.googleapis.com/' + path; | |
} | |
throw Error("Protocol not supported, got: " + JSON.stringify(protocol)); | |
} | |
async getItem(key) { | |
const res = this.ref[key]; | |
if (!res) { | |
// Key not in store | |
throw new zarr.KeyError(key); | |
} | |
if (res?.length !== 3) { | |
// JSON data entry in reference | |
const meta = typeof res === 'string' ? res : JSON.stringify(res) | |
const enc = new TextEncoder().encode(meta); | |
return enc.buffer; | |
} | |
const [urlPath, offset, size] = res; | |
const url = this._url(urlPath); | |
const headers = { | |
Range: `bytes=${offset}-${offset + size - 1}` | |
}; | |
const value = await fetch(url, { headers}).then(res => res.arrayBuffer()); | |
return value; | |
} | |
containsItem(key) { | |
return key in this.ref; | |
} | |
static async fromUrl(url, targetUrl) { | |
const ref = await fetch(url).then(res => res.json()); | |
return new FileReferenceStore(ref, targetUrl); | |
} | |
} | |
class ImJoyPlugin { | |
async setup() { | |
api.log('initialized') | |
} | |
async run(ctx) { | |
const refUrl = 'https://ndownloader.figshare.com/files/27246875?private_link=5a9d8e9e59dab21e4b85' | |
const targetUrl = 'https://ndownloader.figshare.com/files/27246878?private_link=5a9d8e9e59dab21e4b85' | |
const store = await FileReferenceStore.fromUrl(refUrl, targetUrl); | |
const viewer = await api.createWindow({src: 'https://hms-dbmi.github.io/vizarr'}) | |
const img = { | |
"source": store, | |
"name": "Image", | |
"channel_axis": 1, | |
"colors": ["#0000FF", "#FF0000", "#00FFFF", "#00FF00"], // optional | |
"names": ["DAPI", "red", "cyan", "green"], // optional, default channel_X | |
"visibilities": [true, true, true, true], // optional, default True | |
"contrast_limits": [[60, 500], [70, 300], [70, 5000], [70, 1500]], // optional, but recommended | |
} | |
viewer.add_image(img) | |
} | |
} | |
api.export(new ImJoyPlugin()) | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment