twelvelabs-io / twelvelabs-python

Official TwelveLabs SDK for Python
https://pypi.org/project/twelvelabs
Apache License 2.0
27 stars 4 forks source link

Error thrown when uploading video from a url source, but video is still uploaded #50

Open ashleyxue529 opened 4 months ago

ashleyxue529 commented 4 months ago

Expected Behavior

Uploading a file and waiting for the task id and the task to finish shouldn't throw an error

Actual Behavior

Uploading a file and waiting for the task to finish throws this error, BUT the file upload succeeds...

Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/code.py", line 90, in runcode
    exec(code, self.locals)
  File "<console>", line 1, in <module>
  File "/Users/ashleyxue/work/www/backend/ads/helpers.py", line 133, in upload_test
    upload_task = upload_video(source=source)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/ashleyxue/work/www/backend/ads/helpers.py", line 114, in upload_video
    task = tl_client.task.create(
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/ashleyxue/work/www/venv/lib/python3.11/site-packages/twelvelabs/resources/task.py", line 139, in create
    res = self._post(
          ^^^^^^^^^^^
  File "/Users/ashleyxue/work/www/venv/lib/python3.11/site-packages/twelvelabs/base_client.py", line 97, in post
    return self._request("POST", url, data=data, json=json, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/ashleyxue/work/www/venv/lib/python3.11/site-packages/twelvelabs/base_client.py", line 38, in _request
    raise self._make_status_error(e.response)
twelvelabs.exceptions.InternalServerError: Error code: 500 - runtime error: invalid memory address or nil pointer dereference

Steps to Reproduce

Running this, with source being some video url source. I was using "https://video-iad3-1.xx.fbcdn.net/v/t42.1790-2/370851398_210657385060503_7699108706487054458_n.mp4?_nc_cat=108&ccb=1-7&_nc_sid=c53f8f&_nc_ohc=9RHMZG_n6l4Q7kNvgFGlAMH&_nc_ht=video-iad3-1.xx&oh=00_AYDv1bdSjwF8832d6cznwr-SWyOtG2csaQz73F5y4CUepQ&oe=664C6CA3" to test.

twelvelabs==0.1.23

task = tl_client.task.create(
      index_id=<INDEX_ID>,
      url=source,
  )

print(f"Task id={upload_task.id}")

def on_task_update(task: Task):
      print(f"  Status={upload_task.status}")

upload_task.wait_for_done(sleep_interval=5, callback=on_task_update)

if upload_task.status != "ready":
      raise RuntimeError(f"Indexing failed with status {upload_task.status}")
print(f"The unique identifer of your video is {upload_task.video_id}.")

Detailed Description

N/A

Possible Solution

I'm not really sure what's happening, but seems like something with the tasks endpoint? Unsure if I'm just missing something when initializing or calling the method.

ashleyxue529 commented 4 months ago

I also tried using the endpoint directly, copy pasted: https://docs.twelvelabs.io/reference/create-video-indexing-task

And am getting this error even though it seems to be within the resolution range?

'{"code":"video_resolution_too_high","message":"The resolution of the video is too high. Please use a video with resolution between 360p(480x360) and 2160p(3840x2160). Current resolution is 360p."}\n'
metadaddy commented 1 month ago

I get a different error when I call task.create. The URL that @ashleyxue529 used as a source has expired, but https://metadaddy-public.s3.us-west-004.backblazeb2.com/minnie01.mov has no expiry.

Source:

url = 'https://metadaddy-public.s3.us-west-004.backblazeb2.com/minnie01.mov'
task = tl_client.task.create(
    TWELVE_LABS_INDEX_ID,
    url=url
)

Error:

% python quick_test.py               
Traceback (most recent call last):
  File "/Users/ppatterson/src/b2-twelvelabs-example/.venv/lib/python3.11/site-packages/twelvelabs/base_client.py", line 31, in _request
    response.raise_for_status()
  File "/Users/ppatterson/src/b2-twelvelabs-example/.venv/lib/python3.11/site-packages/httpx/_models.py", line 758, in raise_for_status
    raise HTTPStatusError(message, request=request, response=self)
httpx.HTTPStatusError: Client error '400 Bad Request' for url 'https://api.twelvelabs.io/v1.2/tasks'
For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/ppatterson/src/b2-twelvelabs-example/quick_test.py", line 39, in <module>
    task = TWELVE_LABS_CLIENT.task.create(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/ppatterson/src/b2-twelvelabs-example/.venv/lib/python3.11/site-packages/twelvelabs/resources/task.py", line 143, in create
    res = self._post(
          ^^^^^^^^^^^
  File "/Users/ppatterson/src/b2-twelvelabs-example/.venv/lib/python3.11/site-packages/twelvelabs/base_client.py", line 107, in post
    return self._request("POST", url, data=data, json=json, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/ppatterson/src/b2-twelvelabs-example/.venv/lib/python3.11/site-packages/twelvelabs/base_client.py", line 35, in _request
    raise self._make_status_error(e.response)
twelvelabs.exceptions.BadRequestError: Error code: 400 - {'code': 'parameter_unknown', 'message': 'The following parameters are unknown: dummy. Remove these parameters and try again.'}

The problem is in this code in Task.create():

        else:
            # Request should be sent as multipart-form even file not exists
            files["dummy"] = ("", "")

If file is None, then files["dummy"] is set to ("", ""), which prompts the error from the service.

However, since url is set, there is no need to send files in the request, so I tried modifying Task.create() to remove the else clause with its assignment to files["dummy"]. I received a different error:

Traceback (most recent call last):
  File "/Users/ppatterson/src/b2-twelvelabs-example/.venv/lib/python3.11/site-packages/twelvelabs/base_client.py", line 31, in _request
    response.raise_for_status()
  File "/Users/ppatterson/src/b2-twelvelabs-example/.venv/lib/python3.11/site-packages/httpx/_models.py", line 758, in raise_for_status
    raise HTTPStatusError(message, request=request, response=self)
httpx.HTTPStatusError: Client error '400 Bad Request' for url 'https://api.twelvelabs.io/v1.2/tasks'
For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/ppatterson/src/b2-twelvelabs-example/quick_test.py", line 40, in <module>
    task = tl_client.task.create(
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/ppatterson/src/b2-twelvelabs-example/.venv/lib/python3.11/site-packages/twelvelabs/resources/task.py", line 147, in create
    res = self._post(
          ^^^^^^^^^^^
  File "/Users/ppatterson/src/b2-twelvelabs-example/.venv/lib/python3.11/site-packages/twelvelabs/base_client.py", line 107, in post
    return self._request("POST", url, data=data, json=json, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/ppatterson/src/b2-twelvelabs-example/.venv/lib/python3.11/site-packages/twelvelabs/base_client.py", line 35, in _request
    raise self._make_status_error(e.response)
twelvelabs.exceptions.BadRequestError: Error code: 400 - {'code': 'parameter_unknown', 'message': 'The index_id parameter is unknown. Remove these parameters and try again.'}

So, it looks like there's a bug in the service - it seems to be assuming that there will always be file data in the request.

I was able to work around the bug by sending the URLs as if they were files:

        # Remove assignment to files["dummy"]
        ...
        if url is not None:
            files['video_url'] = io.BytesIO(url.encode())
        if transcription_url is not None:
            files['transcription_url'] = io.BytesIO(transcription_url.encode())

        try:
            res = self._post(
                "tasks", data=remove_none_values(data), files=files, **kwargs
            )
            ...

This fixes the immediate problem, but it seems like a hack. The service should be able to handle the case where there are no files in the request.