Cliente de FTP en Python

Conectarse a un servidor con un Cliente de FTP en Python es muy sencillo usando el paquete ftplib. Desde luego debes tener a la mano algunos datos para realizar la conexión, como la dirección del Servidor, contar con un usuario y una contraseña válidas, y finalmente el puerto, que suele ser el 21 para conexiones por FTP.

» Más ejemplos de Python

La conexión la puedes hacer en un solo paso:

# Conectarse en un solo paso
with FTP(host='ftp.servidor.com', user='usuario@servidor.com', passwd='password') as ftp:
    print(ftp.getwelcome())

Un detalle que puede ser importante es que el valor del usuario puede requerir ser completado con el detalle del servidor al cual te conectas como en:

«usuario -> usuario@servidor.com»

También puedes conectarte en dos pasos, enviando los datos del usuario y password en una línea aparte:

from ftplib import FTP

# Conectarse en pasos separados
ftp = FTP()
ftp.connect('ftp.servidor.com', 21)
ftp.login('usuario@servidor.com', 'password')
print(ftp.getwelcome())
ftp.close()
Cliente de FTP en Python
Ejemplo de Cliente FTP en Python

El bloque de código anterior mostrará algo como lo siguiente en consola, pero esto puede variar dependiendo de la configuración del servidor de FTP.

Cliente de FTP en Python
Ejemplo de Cliente FTP en Python, consola

Trabajar con directorios

Con la función ftp.pwd() puedes mostrar el directorio en el que te encuentras:

from ftplib import FTP

with FTP('ftp.servidor.com', 'usuario', 'password') as ftp:
    print(ftp.pwd())  # Muestra la carpeta default

Puedes crear un directorio o carpeta usando la función ftp.mkd(‘mi_directorio’) y enviando como argumento el nombre del directorio:

from ftplib import FTP

with FTP('ftp.servidor.com', 'usuario', 'password') as ftp:
    ftp.mkd('mi_directorio')

Puedes remover el directorio con la función ftp.rmd(‘mi_directorio’) usando como argumento el nombre del directorio :

from ftplib import FTP

with FTP('ftp.servidor.com', 'usuario', 'password') as ftp:
    ftp.rmd('mi_directorio')

Para cambiar el directorio activo en el que te encuentras debes usar ftp.cwd(‘otro_directorio’) :

from ftplib import FTP

with FTP('ftp.servidor.com', 'usuario', 'password') as ftp:
    print(ftp.cwd('otro_directorio'))

Puedes listar el contenido de un directorio obteniendo primero un arreglo de archivos con ftp.dir(files.append) :

from ftplib import FTP

with FTP('ftp.servidor.com', 'usuario', 'password') as ftp:
    # genera una lista de archivos
    files = []
    ftp.dir(files.append)
    for f in files:
        print(f)

Manejo de archivos o ficheros

Existen dos formas de enviar archivos dependiendo de si se trata de texto o de archivos binarios como imágenes, por ejemplo.

Para texto usarás la función storlines y para archivos binarios storbinary:

from ftplib import FTP

with FTP('ftp.servidor.com', 'usuario', 'password') as ftp:

    # For text or binary file, always use `rb`
    with open('archivo.txt', 'rb') as text_file:
        ftp.storlines('STOR archivo.txt', text_file)
    with open('imagen.png', 'rb') as image_file:
        ftp.storbinary('STOR imagen.png', image_file)

Para obtener el tamaño de un archivo o fichero usa la función size(), pero debes tener en cuenta el tipo de archivo del cual estás obteniendo esta información, por lo que debes preparar al cliente para recibir información de archivos de texto con el valor «TYPE A» o para archivos binarios con «TYPE I».

from ftplib import FTP, all_errors

with FTP('ftp.servidor.com', 'usuario', 'password') as ftp:
    try:
        ftp.sendcmd('TYPE I')  # Para archivos binarios
        print(ftp.size('imagen.png')) # obtiene el tamaño de la imagen en el server
    except all_errors as error:
        print(f"Error al obtener tamaño de imagen: {error}")

    try:
        ftp.sendcmd('TYPE A')  # Para texto
        print(ftp.size('texto.txt'))
    except all_errors as error:
        print(f"Error al obtener tamaño de archivo: {error}")

Para renombrar un archivo o fichero, usa la función rename(‘nombre_anterior.txt’, ‘ nombre_nuevo.txt’) :

from ftplib import FTP, all_errors

with FTP('ftp.servidor.com', 'usuario', 'password') as ftp:
    try:
        ftp.rename('texto_anterior.txt', 'texto_nuevo.txt')
    except all_errors as error:
        print(f'Error al renombrar archivo en el servidor: {error}')

Y no menos importante, una de las funciones que seguramente más usarás es la de descargar archivos o ficheros. Para ello usarás las funciones retrlines y retrbinary, para texto y archivos binarios respectivamente :

from ftplib import FTP, all_errors

with FTP('ftp.servidor.com', 'usuario', 'password') as ftp:

    # Para archivos de texto
    with open('nombre_texto_local.txt', 'w') as local_file:  # Abre un archivo de texto localmente para escritura
        response = ftp.retrlines('RETR texto.txt', local_file.write)

        # Revisa la respuesta
        # https://en.wikipedia.org/wiki/List_of_FTP_server_return_codes
        if response.startswith('226'):  # Transferencia completa
            print('Transferencia completa')
        else:
            print('Error de transferencia. El archivo puede estar incompleto o corrupto.')

    # Para archivos binarios
    with open('imagen_local.png', 'wb') as local_file:
        ftp.retrbinary('RETR imagen.png', local_file.write)

Por último, borrar un archivo, usando la función delete(»nombre_archivo_borrar.txt») :

from ftplib import FTP, all_errors

with FTP('ftp.servidor.com', 'usuario', 'password') as ftp:
    try:
        ftp.delete('texto.txt')
    except all_errors as error:
        print(f'Error al borrar archivo: {error}') 

Quizá sea útil saber cuando un comando de FTP no se ha ejecutado con éxito, para ello debes tomar en cuenta que el código puede lanzar alguna de los siguientes errores:

  • ftplib.error_reply – unexpected server reply
  • ftplib.error_temp – temporary error
  • ftplib.error_perm – permanent error
  • ftplib.error_proto – malformed server reply
  • ftplib.all_errors – catches all above errors that a server can return and OSError and EOFError.
from ftplib import FTP

with FTP('ftp.servidor.com', 'usuario', 'password') as ftp:
    try:
        print(ftp.pwd())
    except ftplib.all_errors as e:
        print(f'Error en FTP: {e}')

Hasta aquí la lista de funciones básicas del cliente de FTP en Python. Esperamos que te sirvan estos ejemplos de como crear un Cliente de FTP en Python.

Puedes ver más ejemplos de python en: https://decodigo.com/python

Y la documentación oficial para ftplib: https://docs.python.org/3/library/ftplib.html

Más información en inglés: https://geekole.com/ftp-client-in-python/