Quantcast
Channel: Active questions tagged python - Stack Overflow
Viewing all articles
Browse latest Browse all 13951

422 Unprocessible Entity error when sending List of Form data through Swagger UI docs using FastAPI

$
0
0

I created an API for transcoding video files like adaptive bit rate of youtube. I used FastAPI. Currently, I am trying to set resolution values for each file. But whenever I am adding multiple resolutions, I am recieving 422 unprocessible entity error in the Swagger.

Here is my code:

async def transcode_video(input_path, output_folder, res, unique_id, total_files, pbar): # Use asyncio for command execution with progress bar output_path = os.path.join(output_folder, f"{res}p.m3u8") # Calculate the target size target_size = calculate_target_size(input_path) cmd_duration = f"ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 {input_path}" total_duration = float(subprocess.check_output(cmd_duration, shell=True, text=True).strip()) cmd = (     f"ffmpeg -i {input_path} -vf scale=-2:{res} -c:a aac -b:a 128k "     f"-g 50 -hls_time 1 -hls_list_size 0 "     f"-crf 23 -b:v 100k -fs {target_size} "     f"-hls_segment_filename \"{output_path.replace('.m3u8', '_%03d.ts')}\" "     f"{output_path}" ) process = await asyncio.create_subprocess_shell(     cmd,     stdout=asyncio.subprocess.PIPE,     stderr=asyncio.subprocess.PIPE ) while True:     line = await process.stderr.readline()     if not line:         break     line = line.decode().strip()     if "time=" in line:         # Extracting the time progress from FFmpeg output         time_str = line.split("time=")[1].split()[0]         current_time = sum(x * float(t) for x, t in zip([3600, 60, 1], time_str.split(":")))         progress = (current_time / total_duration) * 100         pbar.update(progress - pbar.n) # Wait for the transcoding process to complete await process.wait() if process.returncode != 0:     raise HTTPException(status_code=500, detail="Video transcoding failed.") pbar.close() # Increment the total number of transcoded files total_files[0] += 1@app.post("/transcode/")async def transcode_video_endpoint(files: List[UploadFile] = File(...), resolutions: List[int] = None): # Counters for transcoded videos total_files = [0] # Iterate over each file for file in files:     # Check if the file is a valid video file based on its extension     valid_video_extensions = {".mp4", ".avi", ".mkv", ".mov", ".wmv", ".flv"}     if not any(file.filename.lower().endswith(ext) for ext in valid_video_extensions):         print(f"Skipping non-video file: {file.filename}")         continue     # Assign a unique ID for each file     unique_id = str(uuid.uuid4())     # Log the filename and unique ID     print(f"Processing file: {file.filename} with unique ID: {unique_id}")     # Create a folder for the unique ID     unique_id_folder = os.path.join(OUTPUT_FOLDER, unique_id)     Path(unique_id_folder).mkdir(parents=True, exist_ok=True)     # Save the uploaded file     input_path = os.path.join(UPLOAD_FOLDER, file.filename)     with open(input_path, "wb") as video_file:         video_file.write(file.file.read())     # Check if the file is a valid video file using ffprobe     try:         subprocess.run(             ["ffprobe", "-v", "error", "-select_streams", "v:0", "-show_entries", "stream=codec_type", "-of", "csv=p=0", input_path],             check=True, capture_output=True         )     except subprocess.CalledProcessError:         print(f"Skipping non-video file: {file.filename}")         continue     # Determine the resolutions to transcode based on the provided or default resolution     resolutions_to_transcode = [res for res in [240, 360, 480, 720] if resolutions is None or res in resolutions]     # If resolutions is not exactly 360, 480, 720, or 1080, transcode to the nearest lower resolution     if resolutions is not None:         resolutions_to_transcode = [get_closest_lower_resolution(res) for res in resolutions]     # Transcode the video into the specified resolutions     for res in resolutions_to_transcode:         output_folder = os.path.join(unique_id_folder, f"{res}p")         Path(output_folder).mkdir(parents=True, exist_ok=True)         # Call the transcode_video function with tqdm progress bar         with tqdm(total=100, desc=f"Transcoding {res}p", position=0, leave=True) as pbar:             await transcode_video(input_path, output_folder, res, unique_id, total_files, pbar)     # Create index.m3u8 file after transcoding all resolutions     create_index_m3u8(unique_id, resolutions_to_transcode) return JSONResponse(content={"message": f"{total_files[0]} videos transcoded."})

If I provide one resolution it works fine. But if I provide a list of resolutions for all the uploaded videos I am getting error 422.

Code    Details422 Error: Unprocessable EntityResponse bodyDownload{"detail": [    {"loc": ["body","resolutions",        0      ],"msg": "value is not a valid integer","type": "type_error.integer"    }  ]}

I used python 3.8.18. Can you help me please? I tried with list, object but always getting the error. My input format is shown below:

enter image description here


Viewing all articles
Browse latest Browse all 13951

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>