cvat-ai / cvat

Annotate better with CVAT, the industry-leading data engine for machine learning. Used and trusted by teams at any scale, for data of any scale.
https://cvat.ai
MIT License
12.38k stars 2.97k forks source link

getting the issue in api/tasks/{}/annotations/{} api #7218

Open hemanth1225 opened 10 months ago

hemanth1225 commented 10 months ago

Actions before raising this issue

Steps to Reproduce

steps:

  1. login to CVAT.
  2. create new task.
  3. finish the job.
  4. click on 3 dotted menu by jobs section, click on export annotations.
  5. select cvat for images 1.1
  6. click ok. now in the logs i'm getting the error like

ERROR: Exception in ASGI application Traceback (most recent call last): File "/opt/venv/lib/python3.10/site-packages/uvicorn/protocols/http/httptools_impl.py", line 435, in run_asgi result = await app( # type: ignore[func-returns-value] File "/opt/venv/lib/python3.10/site-packages/uvicorn/middleware/proxy_headers.py", line 78, in call return await self.app(scope, receive, send) File "/opt/venv/lib/python3.10/site-packages/django/core/handlers/asgi.py", line 160, in call await self.handle(scope, receive, send) File "/opt/venv/lib/python3.10/site-packages/django/core/handlers/asgi.py", line 190, in handle await self.send_response(response, send) File "/opt/venv/lib/python3.10/site-packages/django/core/handlers/asgi.py", line 289, in send_response await send( File "/opt/venv/lib/python3.10/site-packages/uvicorn/protocols/http/httptools_impl.py", line 577, in send raise RuntimeError("Response content shorter than Content-Length") RuntimeError: Response content shorter than Content-Length
MicrosoftTeams-image (1) MicrosoftTeams-image (1)

7217

signal.py:

try: _export_annotations(db_instance=db_task, rq_id="/api/v1/tasks/{}/annotations/{}".format(db_task.id,"CVAT for images 1.1"), request="Get", action='', callback=dm.views.export_task_annotations, format_name="CVAT for images 1.1", filename="annotation.zip", location_conf=location_conf1 ) except Exception as e: print("Error in download api cvat server") print("Error: " ,e) time.sleep(5) print("after export annotation") annotation_export_path="/home/django/data/tasks/{}/export_cache/annotations_cvat-for-images-11.ZIP".format(db_task.id) data= {"file_id":db_task.name,"status" : "completed"} annotated_files={"annotation_xml":open(annotation_export_path,"rb")} url= BASE_url+"annotation/update/status/" r = requests.post(url, data=data,files=annotated_files) pass except Exception as e: print("error in sandbox backend api") print(e)

_export_annotation():

def _export_annotations(db_instance, rq_id, request, format_name, action, callback, filename, location_conf): if action not in {"", "download"}: raise serializers.ValidationError( "Unexpected action specified for the request")

format_desc = {f.DISPLAY_NAME: f
    for f in dm.views.get_export_formats()}.get(format_name)
if format_desc is None:
    raise serializers.ValidationError(
        "Unknown format specified for the request")
elif not format_desc.ENABLED:
    return Response(status=status.HTTP_405_METHOD_NOT_ALLOWED)
print("at the time of queue")
queue = django_rq.get_queue(settings.CVAT_QUEUES.EXPORT_DATA.value)
rq_job = queue.fetch_job(rq_id)
print("after getting  queue  : " , rq_job)
if rq_job:
    print("inside rq_job")
    last_instance_update_time = timezone.localtime(db_instance.updated_date)
    if isinstance(db_instance, Project):
        tasks_update = list(map(lambda db_task: timezone.localtime(db_task.updated_date), db_instance.tasks.all()))
        last_instance_update_time = max(tasks_update + [last_instance_update_time])
    rq_request = rq_job.meta.get('request', None)
    request_time = rq_request.get('timestamp', None) if rq_request else None
    if request_time is None or request_time < last_instance_update_time:
        rq_job.cancel()
        rq_job.delete()
    else:
        if rq_job.is_finished:
            print("inside job finished")
            file_path = rq_job.return_value()
            if action == "download" and osp.exists(file_path):
                rq_job.delete()

                timestamp = datetime.strftime(last_instance_update_time,
                    "%Y_%m_%d_%H_%M_%S")
                filename = filename or \
                    "{}_{}-{}-{}{}".format(
                        db_instance.__class__.__name__.lower(),
                        db_instance.name if isinstance(db_instance, (Task, Project)) else db_instance.id,
                        timestamp, format_name, osp.splitext(file_path)[1]
                    ).lower()

                # save annotation to specified location
                print("before get location")
                location = location_conf.get('location')
                if location == Location.LOCAL:
                    return sendfile(request, file_path, attachment=True,
                        attachment_filename=filename)
                elif location == Location.CLOUD_STORAGE:
                    try:
                        storage_id = location_conf['storage_id']
                    except KeyError:
                        print("key Error")
                        return HttpResponseBadRequest(
                            'Cloud storage location was selected as the destination,'
                            ' but cloud storage id was not specified')
                    db_storage = get_cloud_storage_for_import_or_export(
                        storage_id=storage_id, request=request,
                        is_default=location_conf['is_default'])
                    storage = db_storage_to_storage_instance(db_storage)

                    try:
                        print("upload to storage")
                        storage.upload_file(file_path, filename)
                    except (ValidationError, PermissionDenied, NotFound) as ex:
                        msg = str(ex) if not isinstance(ex, ValidationError) else \
                            '\n'.join([str(d) for d in ex.detail])
                        return Response(data=msg, status=ex.status_code)
                    return Response(status=status.HTTP_200_OK)
                else:
                    raise NotImplementedError()
            else:
                if osp.exists(file_path):
                    print("succes with 201")
                    return Response(status=status.HTTP_201_CREATED)
        elif rq_job.is_failed:
            exc_info = rq_job.meta.get('formatted_exception', str(rq_job.exc_info))
            rq_job.delete()
            return Response(exc_info,
                status=status.HTTP_500_INTERNAL_SERVER_ERROR)
        else:
            print("success with 202")
            return Response(status=status.HTTP_202_ACCEPTED)

try:
    if request.scheme:
        server_address = request.scheme + '://'
    server_address += request.get_host()
except Exception:
    print("after rq_job : " ,Exception)
    server_address = None

TTL_CONSTS = {
    'project': dm.views.PROJECT_CACHE_TTL,
    'task': dm.views.TASK_CACHE_TTL,
    'job': dm.views.JOB_CACHE_TTL,
}
ttl = TTL_CONSTS[db_instance.__class__.__name__.lower()].total_seconds()
user_id = request.user.id
print(queue, " : queue", user_id, " : user_id")
with get_rq_lock_by_user(queue, user_id):
    queue.enqueue_call(
        func=callback,
        args=(db_instance.id, format_name, server_address),
        job_id=rq_id,
        meta=get_rq_job_meta(request=request, db_obj=db_instance),
        depends_on=define_dependent_job(queue, user_id),
        result_ttl=ttl,
        failure_ttl=ttl,
    )
print("return succes with 202")
return Response(status=status.HTTP_202_ACCEPTED)
bsekachev commented 10 months ago

Hello @hemanth1225

Does it affect your experience?

hemanth1225 commented 10 months ago

later in the functions i added some code snippet, but due to exception it is exiting from here. it is required to resolve this.

thank you in advance

matt-d commented 9 months ago

I'm seeing this issue randomly in 2.9.2 also. Some projects I can export all of the tasks without issue, others seem to choke after the first few tasks have been exported via the API.

INFO:     192.168.5.227:0 - "POST /api/auth/login HTTP/1.0" 200 OK

2023-12-27 14:40:40,389 DEBG 'uvicorn-0' stdout output:
INFO:     192.168.5.227:0 - "GET /api/labels?project_id=12&page_size=100000 HTTP/1.0" 200 OK

2023-12-27 14:40:40,499 DEBG 'uvicorn-0' stdout output:
INFO:     192.168.5.227:0 - "GET /api/tasks?project_id=12&page_size=100000 HTTP/1.0" 200 OK

2023-12-27 14:40:40,535 DEBG 'uvicorn-1' stdout output:
INFO:     192.168.5.227:0 - "GET /api/tasks/937/dataset?format=COCO%201.0&filename=5420-142252_1646048460_tray_142252 HTTP/1.0" 202 Accepted

2023-12-27 14:40:40,566 DEBG 'uvicorn-1' stdout output:
INFO:     192.168.5.227:0 - "GET /api/tasks/937/dataset?format=COCO%201.0&filename=5420-142252_1646048460_tray_142252 HTTP/1.0" 201 Created

2023-12-27 14:40:40,599 DEBG 'uvicorn-1' stdout output:
INFO:     192.168.5.227:0 - "GET /api/tasks/937/dataset?format=COCO%201.0&filename=5420-142252_1646048460_tray_142252&action=download HTTP/1.0" 200 OK

2023-12-27 14:40:40,599 DEBG 'uvicorn-1' stderr output:
ERROR:    Exception in ASGI application
Traceback (most recent call last):
  File "/opt/venv/lib/python3.10/site-packages/uvicorn/protocols/http/httptools_impl.py", line 435, in run_asgi
    result = await app(  # type: ignore[func-returns-value]
  File "/opt/venv/lib/python3.10/site-packages/uvicorn/middleware/proxy_headers.py", line 78, in __call__
    return await self.app(scope, receive, send)
  File "/opt/venv/lib/python3.10/site-packages/django/core/handlers/asgi.py", line 160, in __call__
    await self.handle(scope, receive, send)
  File "/opt/venv/lib/python3.10/site-packages/django/core/handlers/asgi.py", line 190, in handle
    await self.send_response(response, send)
  File "/opt/venv/lib/python3.10/site-packages/django/core/handlers/asgi.py", line 289, in send_response
    await send(
  File "/opt/venv/lib/python3.10/site-packages/uvicorn/protocols/http/httptools_impl.py", line 577, in send
    raise RuntimeError("Response content shorter than Content-Length")
RuntimeError: Response content shorter than Content-Length

2023-12-27 14:40:40,845 DEBG 'uvicorn-1' stdout output:
INFO:     192.168.5.227:0 - "GET /api/jobs?task_id=937&page_size=100000 HTTP/1.0" 200 OK

2023-12-27 14:40:40,887 DEBG 'uvicorn-0' stdout output:
INFO:     192.168.5.227:0 - "GET /api/jobs?task_id=937&page_size=100000 HTTP/1.0" 200 OK

2023-12-27 14:40:40,926 DEBG 'uvicorn-0' stdout output:
INFO:     192.168.5.227:0 - "GET /api/jobs/28257/data/meta HTTP/1.0" 200 OK

2023-12-27 14:40:41,083 DEBG 'uvicorn-0' stderr output:
[2023-12-27 14:40:41,082] ERROR django.request: Internal Server Error: /api/tasks/936/dataset
Traceback (most recent call last):
  File "/opt/venv/lib/python3.10/site-packages/asgiref/sync.py", line 534, in thread_handler
    raise exc_info[1]
  File "/opt/venv/lib/python3.10/site-packages/django/core/handlers/exception.py", line 42, in inner
    response = await get_response(request)
  File "/opt/venv/lib/python3.10/site-packages/django/core/handlers/base.py", line 253, in _get_response_async
    response = await wrapped_callback(
  File "/opt/venv/lib/python3.10/site-packages/asgiref/sync.py", line 479, in __call__
    ret: _R = await loop.run_in_executor(
  File "/opt/venv/lib/python3.10/site-packages/asgiref/current_thread_executor.py", line 40, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/opt/venv/lib/python3.10/site-packages/asgiref/sync.py", line 538, in thread_handler
    return func(*args, **kwargs)
  File "/opt/venv/lib/python3.10/site-packages/django/views/decorators/csrf.py", line 56, in wrapper_view
    return view_func(*args, **kwargs)
  File "/opt/venv/lib/python3.10/site-packages/rest_framework/viewsets.py", line 125, in view
    return self.dispatch(request, *args, **kwargs)
  File "/opt/venv/lib/python3.10/site-packages/rest_framework/views.py", line 509, in dispatch
    response = self.handle_exception(exc)
  File "/opt/venv/lib/python3.10/site-packages/rest_framework/views.py", line 469, in handle_exception
    self.raise_uncaught_exception(exc)
  File "/opt/venv/lib/python3.10/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
    raise exc
  File "/opt/venv/lib/python3.10/site-packages/rest_framework/views.py", line 506, in dispatch
    response = handler(request, *args, **kwargs)
  File "/home/django/cvat/apps/engine/views.py", line 1511, in dataset_export
    return self.export_annotations(
  File "/home/django/cvat/apps/engine/mixins.py", line 405, in export_annotations
    return export_func(db_instance=self._object,
  File "/home/django/cvat/apps/engine/views.py", line 3010, in _export_annotations
    if osp.exists(file_path):
  File "/usr/lib/python3.10/genericpath.py", line 19, in exists
    os.stat(path)
TypeError: stat: path should be string, bytes, os.PathLike or integer, not NoneType

2023-12-27 14:40:41,084 DEBG 'uvicorn-0' stdout output:
INFO:     192.168.5.227:0 - "GET /api/tasks/936/dataset?format=COCO%201.0&filename=5420-142253_1646050452_tray_142253 HTTP/1.0" 500 Internal Server Error

2023-12-27 14:40:43,622 DEBG 'uvicorn-1' stdout output:
INFO:     10.201.6.6:0 - "GET /api/auth/rules HTTP/1.0" 304 Not Modified
matt-d commented 9 months ago

The same tasks also throws an error 500 exporting through the web UI - exporting a different format does not throw an error and works as expected.

matt-d commented 9 months ago

switching from v2.9.2 to dev seems to have fixed the issue.

PMazarovich commented 9 months ago

I see the same in logs (2.9.2). Hope this will be resolved

josiahls commented 5 months ago

I see the logs in 2.13.0 also. Currently try-catching, but this isn't a great solution on my end.

PMazarovich commented 3 months ago

I see the same in logs 2.15.0

UangSC commented 2 weeks ago

I encountered this situation in v2.19 as well. I was able to export normally in the afternoon, but when I tried to export the configuration file in the evening, it showed that the file did not exist. Checking the logs revealed the following error: cvat_server | 2024-09-24 15:53:17,017 DEBG 'uvicorn-1' stdout output: cvat_server | INFO: 172.18.0.4:0 - "GET /api/auth/rules HTTP/1.0" 200 OK cvat_server | cvat_server | 2024-09-24 15:53:26,262 DEBG 'uvicorn-1' stdout output: cvat_server | INFO: 172.16.200.34:0 - "GET /api/tasks/5/annotations?org=Annotation&filename=9.zip&format=CVAT+for+images+1.1&save_images=false&action=download HTTP/1.0" 200 OK cvat_server | cvat_server | 2024-09-24 15:53:26,262 DEBG 'uvicorn-1' stderr output: cvat_server | ERROR: Exception in ASGI application cvat_server | Traceback (most recent call last): cvat_server | File "/opt/venv/lib/python3.10/site-packages/uvicorn/protocols/http/httptools_impl.py", line 435, in run_asgi cvat_server | result = await app( # type: ignore[func-returns-value] cvat_server | File "/opt/venv/lib/python3.10/site-packages/uvicorn/middleware/proxy_headers.py", line 78, in __call__ cvat_server | return await self.app(scope, receive, send) cvat_server | File "/opt/venv/lib/python3.10/site-packages/django/core/handlers/asgi.py", line 160, in __call__ cvat_server | await self.handle(scope, receive, send) cvat_server | File "/opt/venv/lib/python3.10/site-packages/django/core/handlers/asgi.py", line 190, in handle cvat_server | await self.send_response(response, send) cvat_server | File "/opt/venv/lib/python3.10/site-packages/django/core/handlers/asgi.py", line 289, in send_response cvat_server | await send( cvat_server | File "/opt/venv/lib/python3.10/site-packages/uvicorn/protocols/http/httptools_impl.py", line 577, in send cvat_server | raise RuntimeError("Response content shorter than Content-Length") cvat_server | RuntimeError: Response content shorter than Content-Length cvat_server | cvat_server | 2024-09-24 15:53:26,635 DEBG 'uvicorn-0' stderr output: cvat_server | [2024-09-24 15:53:26,635] WARNING django.request: Bad Request: /api/tasks/5/annotations cvat_server | cvat_server | 2024-09-24 15:53:26,635 DEBG 'uvicorn-0' stdout output: cvat_server | INFO: 172.16.200.34:0 - "GET /api/tasks/5/annotations?org=Annotation&filename=9.zip&format=CVAT+for+images+1.1&save_images=false&action=download HTTP/1.0" 400 Bad Request