It probably has nothing to do with your code. I’ve spent a few hours now getting video upload (“copy”) to work from a python script because I need to migrate a lot of videos, which I can’t do by hand and don’t want to do with a shell script.
The API endpoints expects very unconventional way of formatting the data. Basically, the data needs to be sent as Content-Type
: application/x-www-form-urlencoded
for some reason. Then, the actual data needs to be a JSON dictionary key… Embedded in a string, like so: key = f'{{"url":"{video_url}","meta":{{"name":"{video_title}"}},"thumbnailTimestampPct":{thumbnail_percent}}}' data = {key: ""}
If anyone struggles with requests
, here is the function I ended up coding to automatically upload/copy videos from python:
def upload_video_to_cstream(video_url, video_title, thumbnail_percent=0.5):
url = f"{BASE_URL}/copy"
key = f’{{“url”:"{video_url}",“meta”:{{“name”:"{video_title}"}},“thumbnailTimestampPct”:{thumbnail_percent}}}’
data = {key: “”}
headers = {
"X-Auth-Key": CLOUDFLARE_API_KEY,
"X-Auth-Email": CLOUDFLARE_AUTH_EMAIL,
"content-type": "application/x-www-form-urlencoded",
"user-agent": "curl/7.74.0",
"accept": "*/*",
"content-length": f"{len(key)}",
}
r = requests.Request("POST", url, headers, data=data)
prepped = r.prepare()
prepped.headers["content-length"] = f"{len(key)}"
prepped.body = {key.encode("ASCII"): ""}
response = session.send(prepped)
json = response.json()
success = json["success"]
errors = json["errors"]
if not success:
print("Error while uploading video. Errors:", errors)
print("Full response:", json)
sys.exit(1)
result = json["result"]
uid = result["uid"]
thumbnail_url = result["thumbnail"]
preview_url = result["preview"]
playback_url = result["playback"]["dash"]
return (uid, thumbnail_url, preview_url, playback_url)
It’s very ugly but does the work. Note that it’s currently as of 16/01/2022, they might update the endpoint to accept application/json
content at some point.