Skip to content
This repository was archived by the owner on Nov 22, 2024. It is now read-only.

Commit 4bd5e3f

Browse files
committed
example for /accounts/:id/images/v2/direct_upload
1 parent 0a9cc41 commit 4bd5e3f

1 file changed

Lines changed: 146 additions & 0 deletions

File tree

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
#!/usr/bin/env python
2+
"""Cloudflare API code - example"""
3+
4+
import os
5+
import sys
6+
import json
7+
import datetime
8+
import requests
9+
10+
sys.path.insert(0, os.path.abspath('.'))
11+
sys.path.insert(0, os.path.abspath('..'))
12+
import CloudFlare
13+
14+
#
15+
# Warning: You need to enable image storage on your account for this code to work.
16+
# You'll get 403 errors if you don't have it enabled (go pay for it)
17+
#
18+
# If you need to delete images after running this code you can do this:
19+
#
20+
# cli4 --delete /accounts/:"${ACCOUNT}"/images/v1/::${image_id}
21+
#
22+
# Or if you want to live dangerously - do this and delete every image you have
23+
# You should not run this unless you really really really know what you're doing! (like rm -rf /)
24+
#
25+
# cli4 /accounts/:"${ACCOUNT}"/images/v1 | jq -r '.images[]|.id' | while read image_id ; do cli4 --delete /accounts/:"${ACCOUNT}"/images/v1/::$image_id ; done
26+
#
27+
28+
def doit(account_name, image_filename):
29+
30+
# https://developers.cloudflare.com/stream/uploading-videos/direct-creator-uploads/
31+
# https://developers.cloudflare.com/api/operations/cloudflare-images-create-authenticated-direct-upload-url-v-2
32+
33+
with CloudFlare.CloudFlare(debug=False) as cf:
34+
try:
35+
params = {'name': account_name, 'per_page': 1}
36+
accounts = cf.accounts.get(params=params)
37+
except CloudFlare.exceptions.CloudFlareAPIError as e:
38+
exit('%s: %d %s - api call failed' % ('/accounts', e, e))
39+
try:
40+
account_id = accounts[0]['id']
41+
except IndexError:
42+
exit('%s: account name not found' % (account_name))
43+
44+
try:
45+
image_fp = open(image_filename, 'rb')
46+
except Exception as e:
47+
exit('%s: %s - file read failed' % (image_filename, e))
48+
49+
image_filesize = os.fstat(image_fp.fileno()).st_size
50+
if image_filesize > 1024*1024*1024:
51+
print('%s: filesize = %0.1f GBytes' % (image_filename, float(image_filesize)/1024*1024*1024))
52+
elif image_filesize > 1024*1024:
53+
print('%s: filesize = %0.1f MBytes' % (image_filename, float(image_filesize)/1024*1024))
54+
elif image_filesize > 1024:
55+
print('%s: filesize = %0.1f KBytes' % (image_filename, float(image_filesize)/1024))
56+
else:
57+
print('%s: filesize = %d Bytes' % (image_filename, image_filesize))
58+
59+
# format future time in RFC3339 format (and do it UTC time)
60+
time_plus_one_hour_in_iso = (datetime.datetime.utcnow().replace(microsecond=0) + datetime.timedelta(hours=1)).isoformat() + 'Z'
61+
62+
# direct_upload uses multipart/form-data and hence this info is passed as files (but None for filename)
63+
# these are the four form values
64+
# presently you need to upload at-least one of these until the library version is greater than 2.17.0
65+
# --form expiry= \
66+
# --form id= \
67+
# --form metadata= \
68+
# --form requireSignedURLs=
69+
70+
# here's examples using metadata and expiry.
71+
metadata_values = {
72+
'source': image_filename,
73+
'size': image_filesize,
74+
}
75+
files = {
76+
('metadata', (None, json.dumps(metadata_values))),
77+
('expiry', (None, time_plus_one_hour_in_iso))
78+
}
79+
80+
try:
81+
r = cf.accounts.images.v2.direct_upload.post(account_id, files=files)
82+
except CloudFlare.exceptions.CloudFlareAPIError as e:
83+
exit('%s: %d %s - api call failed' % ('/accounts/images/v2/direct_upload', e, e))
84+
print('v2 new image post results')
85+
print(json.dumps(r, indent=4))
86+
87+
image_id = r['id']
88+
image_url = r['uploadURL']
89+
90+
# https://developers.cloudflare.com/stream/uploading-videos/direct-creator-uploads/
91+
# curl -X POST \
92+
# -F file=@/Users/mickie/Downloads/example_video.mp4 \
93+
# https://upload.videodelivery.net/f65014bc6ff5419ea86e7972a047ba22
94+
95+
try:
96+
r = requests.post(image_url, files={('file', image_fp) })
97+
except Exception as e:
98+
exit('%s: %s - api call failed' % (image_url, e))
99+
100+
response_code = r.status_code
101+
if response_code != 200:
102+
exit('%s: HTTP Error %s' % (image_url, response_code))
103+
104+
j = r.json()
105+
if j['success'] == True:
106+
print('Image upload results')
107+
print(json.dumps(j['result'], indent=4))
108+
else:
109+
exit('Error:\n errors: %s\n messages: %s' % (image_url, j['errors'], j['messages']))
110+
111+
image_fp.close()
112+
113+
# list all images
114+
try:
115+
r = cf.accounts.images.v2(account_id)
116+
except CloudFlare.exceptions.CloudFlareAPIError as e:
117+
exit('%s: %d %s - api call failed' % ('/accounts/images/v1', e, e))
118+
119+
print('All account images:')
120+
for img in r['images']:
121+
print('%s %s: %s %s %s' % ('>' if img['id'] == image_id else ' ', img['id'], img['uploaded'], img['filename'], img['variants'][0]))
122+
for k,v in img['meta'].items():
123+
print(' %s = %s' % (k, v))
124+
125+
# delete the image - this was just a test (comment this out if you end up using this code for uploads)
126+
try:
127+
r = cf.accounts.images.v1.delete(account_id, image_id)
128+
except CloudFlare.exceptions.CloudFlareAPIError as e:
129+
exit('%s: %d %s - api call failed' % ('/accounts/images/v1', e, e))
130+
print('Image delete')
131+
print(json.dumps(r, indent=4))
132+
133+
def main():
134+
try:
135+
account_name = sys.argv[1]
136+
except IndexError:
137+
exit('usage: example_images_v2_direct_upload.py account_name image_filename')
138+
try:
139+
image_filename = sys.argv[2]
140+
except IndexError:
141+
exit('usage: example_images_v2_direct_upload.py account_name image_filename')
142+
doit(account_name, image_filename)
143+
exit(0)
144+
145+
if __name__ == '__main__':
146+
main()

0 commit comments

Comments
 (0)