-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapi.py
57 lines (46 loc) · 1.83 KB
/
api.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import hmac
import hashlib
import traceback
import itertools
import time
import os
from tqdm import tqdm
from filecrypt import key_id, token_b64encode
_retry_range = lambda retries: itertools.cycle([None]) if retries is None else range(retries)
def upload(path, file_id, size, base_url, api_key, chunk_size=int(10e6), progress=True, max_retries=None):
import requests
with tqdm(total=size, unit='B', unit_scale=True, disable=(not progress)) as pbar, open(path, 'rb') as f:
pos = 0
while True:
chunk = f.read(chunk_size)
if not chunk:
break
hash = hashlib.sha3_256()
hash.update(chunk)
hash = hash.digest()
content_range = f'bytes {pos}-{pos+len(chunk)-1}/{size}'
pos += len(chunk)
mac = hmac.new(api_key, digestmod='sha3_256')
mac.update(file_id.encode())
mac.update(hash)
mac.update(content_range.encode())
post_url = '/'.join([
base_url,
key_id(api_key),
file_id,
token_b64encode(mac.digest()),
token_b64encode(hash)])
for attempt in _retry_range(max_retries):
try:
res = requests.post(post_url, files={'chunk': chunk}, headers={'content-range': content_range})
break
except requests.exceptions.RequestException as e:
print(f'Upload error: {type(e).__name__}')
time.sleep(1)
print('Retrying.')
else:
print(f'Repeated errors uploading. Exiting.')
print(f'Leaving encrypted file under: {path}')
sys.exit(1)
pbar.update(len(chunk))
os.remove(path)