AxiosError: Request failed with status code 413

Question:
I am working with Streamlit to upload a ZIP file that can weigh less than 200 MB, but when trying to upload a 30 MB ZIP, I get the following error: AxiosError: Request failed with status code 413. I do not know how I can modify the client_max_body_size

Repl link/Link to where the bug appears:

Screenshots, links, or other helpful context:

if uploaded_file is not None:

  # Elimina los directorios de imágenes y de imágenes transformadas si existen
  if os.path.exists('images'):
    shutil.rmtree('images')
  if os.path.exists('transformed_images'):
    shutil.rmtree('transformed_images')
  if os.path.exists('excel'):
    shutil.rmtree('excel')

  # Recrea los directorios de imágenes y de imágenes transformadas
  os.makedirs('images', exist_ok=True)
  os.makedirs('transformed_images', exist_ok=True)
  os.makedirs('excel', exist_ok=True)

  with zipfile.ZipFile(uploaded_file, 'r') as zip_ref:
    zip_ref.extractall("images")
    st.success('Descompresión exitosa!')

Hello @AndresEsquivel6!

Could you please make the repl public, or give all the code here?

1 Like

Hi this is teh code:

import streamlit as st
import cloudinary
import cloudinary.uploader
import requests
import zipfile
import os
import shutil
import pandas as pd
import io

st.title("Cargador y Transformador de Imágenes")

st.sidebar.header("Configuración de Cloudinary")
cloud_name = st.sidebar.text_input("Nombre del Cloud:", value="", max_chars=50)
api_key = st.sidebar.text_input("API Key:", value="", max_chars=50)
api_secret = st.sidebar.text_input("API Secret:",
                                   value="",
                                   type="password",
                                   max_chars=50)
supcarpeta = ""

cloudinary.config(cloud_name=cloud_name,
                  api_key=api_key,
                  api_secret=api_secret)

carpeta_seleccion = st.radio("Seleccione la carpeta",
                             ["App Propia", "Delivery", "Promos"],
                             index=0)

uploaded_file = st.file_uploader("Cargar archivo ZIP con imágenes",
                                 type=["zip"])

if uploaded_file is not None:

  # Elimina los directorios de imágenes y de imágenes transformadas si existen
  if os.path.exists('images'):
    shutil.rmtree('images')
  if os.path.exists('transformed_images'):
    shutil.rmtree('transformed_images')
  if os.path.exists('excel'):
    shutil.rmtree('excel')

  # Recrea los directorios de imágenes y de imágenes transformadas
  os.makedirs('images', exist_ok=True)
  os.makedirs('transformed_images', exist_ok=True)
  os.makedirs('excel', exist_ok=True)

  with zipfile.ZipFile(uploaded_file, 'r') as zip_ref:
    zip_ref.extractall("images")
    st.success('Descompresión exitosa!')

    # Ruta de la carpeta que contiene las imágenes
    carpeta_imagenes = 'images'

    # Nombre de la carpeta en Cloudinary donde deseas almacenar las imágenes
    nombre_carpeta_cloudinary = 'cambiar-tamano-fotos'
    if carpeta_seleccion == 'App Propia':
      supcarpeta = "app_propia"
      nombre_carpeta_cloudinary = nombre_carpeta_cloudinary + "/app_propia"
    elif (carpeta_seleccion == 'Delivery'):
      supcarpeta = "delivery"
      nombre_carpeta_cloudinary = nombre_carpeta_cloudinary + "/delivery"
    else:
      supcarpeta = "promos"
      nombre_carpeta_cloudinary = nombre_carpeta_cloudinary + "/promos"
    # Iterar sobre cada archivo en la carpeta y subir las imágenes a Cloudinary
    lista_public_ids = []
    for archivo in os.listdir(carpeta_imagenes):
      ruta_archivo = os.path.join(carpeta_imagenes, archivo)
      if os.path.isfile(ruta_archivo) and archivo.lower().endswith(
        ('.png', '.jpg', '.jpeg')):
        # Subir la imagen a Cloudinary
        respuesta = cloudinary.uploader.upload(
          ruta_archivo,
          folder=
          nombre_carpeta_cloudinary,  # Especificar la carpeta en Cloudinary
          use_filename=True,  # Utilizar el nombre original del archivo
          unique_filename=
          False  # No agregar un sufijo aleatorio en caso de conflicto de nombres
        )
        st.write(
          f'Imagen {archivo} subida con éxito con public_id {respuesta["public_id"]}'
        )
        lista_public_ids.append(respuesta["public_id"])

    image_data = []
    # Iterar sobre cada public_id, transformar y descargar la imagen
    for public_id in lista_public_ids:
      url_transformada, opciones = cloudinary.utils.cloudinary_url(
        public_id, width=550, height=440, crop="lpad", quality="auto:low")
      st.write(f'URL de la imagen transformada: {url_transformada}')

      # Descargar la imagen transformada
      respuesta = requests.get(url_transformada)
      if respuesta.status_code == 200:

        # Obtener el peso de la imagen a través de una solicitud HEAD para no descargar el contenido completo
        respuesta_head = requests.head(url_transformada)
        peso_imagen_bytes = int(respuesta_head.headers['Content-Length'])
        peso_imagen_megas = peso_imagen_bytes / (1024**2)  # Bytes to megabytes

        # Nombre de archivo para la imagen transformada
        nombre_archivo = f'{public_id}.jpg'
        nombre_archivo = nombre_archivo.replace(
          "cambiar-tamano-fotos/" + supcarpeta + "/", "")

        # Añadir la información al listado
        image_data.append({
          'archivo':
          str(
            nombre_archivo.replace('.png',
                                   '').replace('.jpg',
                                               '').replace('.jpeg', '')),
          'url':
          str(url_transformada),
          'peso':
          peso_imagen_megas  # El peso se indica en bytes
        })

        ruta_destino = os.path.join("transformed_images", nombre_archivo)
        os.makedirs("transformed_images", exist_ok=True)

        with open(ruta_destino, 'wb') as archivo:
          archivo.write(respuesta.content)
          st.write(
            f'Imagen {nombre_archivo} descargada con éxito en {ruta_destino}')
      else:
        st.write(f'Error: no se pudo descargar la imagen {public_id}')

    zip_filename = 'transformed_images.zip'
    with zipfile.ZipFile(zip_filename, 'w') as zipf:
      for root, dirs, files in os.walk('transformed_images'):
        for file in files:
          zipf.write(os.path.join(root, file),
                     arcname=os.path.relpath(os.path.join(root, file),
                                             'transformed_images'))

    # Suponiendo que `df_images` es tu DataFrame con los datos de las imágenes:
    df_images = pd.DataFrame(image_data)

    # Crear un buffer de texto en memoria para el archivo de texto.
    output = io.StringIO()

    # Usar el método to_csv de Pandas DataFrame con un delimitador de pipe
    df_images.to_csv(output, sep='|', index=False)

    # Convertir el contenido de StringIO a bytes (necesario para st.download_button)
    text_to_download = output.getvalue().encode('utf-8')

    # Ofrecer el botón de descarga en Streamlit
    st.sidebar.download_button(
      label='Descargar datos como TXT',
      data=text_to_download,  # Datos en formato de bytes
      file_name='datos_imagenes.txt',
      mime='text/plain')

    # Luego proporciona un enlace de descarga para el archivo ZIP en la interfaz de Streamlit:
    if os.path.exists(zip_filename):
      with open(zip_filename, "rb") as f:
        st.sidebar.download_button(label="Descargar imágenes transformadas",
                                   data=f,
                                   file_name='transformed_images.zip',
                                   mime="application/zip")
1 Like

Could you try running streamlit run main.py in the shell?

image

If I run Replit and try to upload the file from the webview, it works correctly and I have no problems with the 30MB file. But if I access the site using the deployment tool, it stops working.

1 Like

Based on the logs, it looks like the server is running.

1 Like

What are you deploying the repl as? Reserved VM? Autoscale?

I need a colleague to always be able to access the website.

You could invite your colleague to the repl.

1 Like

Would he need a paid account?

They shouldn’t need to as they can’t purchase anything for the Repl since they aren’t the owner of the Repl. They should be fine with a free account to access the necessary items you are wanting.

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.