Асинхронные представления Django, AsyncIO

#python #django #django-rest-framework #python-asyncio

#питон #джанго #django-rest-фреймворк #python-асинхронный

Вопрос:

Можно ли вызвать асинхронную функцию внутри функции основного представления django и вернуть main до того, как вторая продолжит свое выполнение? Поскольку конвертация видео занимает слишком много времени, мне нужно вернуть пути к мультимедиа до завершения конвертации.

views.py

 async def optimize(request):
    
    serializer_data = FileUploadSerializer(data=request.FILES).custom_validation()
    media_paths = {}
    
    for data in serializer_data.validated_data:
        #converting video
        if data == 'video':
            media_paths['video'] = []            
            for file in serializer_data.validated_data['video']:
 
                file_path = file.file.name
                file_name = generate_file_name()
                new_path = os.path.join(settings.BASE_DIR, 'media')
                extension = file.name.rsplit('.', 1)[-1]
                
                loop = asyncio.get_event_loop()
                loop.create_task(video_converter.start_convert(file_path, file_name, new_path))
                # loop.run_until_complete(video_converter.start_convert(file_path, file_name, new_path))
                
                media_paths['video'].append(request.build_absolute_uri()   "media/video/"   file_name   "."   extension)
        

    
    return JsonResponse(media_paths)
 

video_converter.py

     clip = VideoFileClip(f"{file_path}")
    if round(clip.w/clip.h, 2) == 1.78:
        if clip.h < 720:     
            clip.write_videofile(f"{new_path}\video{file_name}.mp4", fps=24)
            clip.close()
        else:
            clip_resized = clip.resize(height=720)
            clip_resized.write_videofile(f"{new_path}\video{file_name}.mp4", fps=24)
            clip.close()
        return new_path   file_name   '.mp4'
    else:
        clip.close()
        raise Exception("Uploaded video resolution is not supported")
 

Ответ №1:

Найдено решение проблемы, которую я описал выше. Я использовал модуль потоковой обработки python и передавал переменные во вновь созданный tread следующим образом. И когда основная функция завершает свое выполнение и возвращается, потоки начинают свое выполнение с параметрами, переданными ей основной функцией.

 import threading

def my_func(a):
    time.sleep(5)
    print(f"my number is {a}") 

def main(a, b):
    task = threading.Thread(target=my_func, args=(a,))
    task.daemon = True
    task.start()
    return a   b