Python: Aceder a un servidor FTP

Forma fácil de acceder a un servidor FTP.

Para hacer la pruebas, usaremos el servidor dlptest.com este nos permita probar el programa que realicemos. Hay que tener en cuenta,:

  • No sirve para almacenar datos, ya que se borran cada cierto tiempo.
  • No se pueden subir ni descargar archivos muy grandes, ya que no puede banear nuestra IP.
  • La contraseña varia cada cierto tiempo
  • Recomendable leer las condiciones de uso, ya que pueden variar.

Desarrollo del programa:

Utilizaremos el modelo ftplib

Utilizaremos el fichero «ejemplo.txt» para poder hacer las operaciones, este fichero debe estar en el mismo directorio donde se ejecute el programa.

Definir los parámetros de acceso.

HOSTNAME = "ftp.dlptest.com"
USERNAME = "dlpuser"
PASSWORD = "rNrKYTX9g7z3RgJRmxWuGHbeu"

Nos conectamos al servidor:

ftp_server = ftplib.FTP(HOSTNAME, USERNAME, PASSWORD)

En las siguientes subrutinas, definiremos los comandos mas importantes.

Subir un fichero (Upload):

def subir_fichero():
    filename = "ejemplo.txt"
    # Leemos el fichero en modo binario
    with open(filename, "rb") as file:
        # Comando para UPloading el fichero "STOR filename"
        ftp_server.storbinary(f"STOR {filename}", file)

Bajar un fichero (Download):

def descargar_fichero():
    filename = "ejemplo.txt"
    # Escribimos el fichero en modo binario
    with open(filename, "wb") as file:
        # Comand para Downloading el fichero "RETR filename"
        ftp_server.retrbinary(f"RETR {filename}", file.write)

Crear un directorio:

def crear_directorio(directorio):
    try:
        ftp_server.mkd(directorio)
        print(f"Directorio '{directorio}' creado exitosamente.")
        ftp_server.quit()
    except ftplib.all_errors as e: 
      print(f"Error al crear el directorio: {e}")

Comprobar si existe un directorio:

def comprobar_directorio(directorio):
    """
     Comprueba si un directorio existe en un servidor FTP.
    Argumentos:
        ftp: Objeto FTP conectado al servidor.
        directorio: Nombre del directorio a comprobar.
    Avisos:
        True si el directorio existe
        ,False en caso contrario.
    """
    try:
        # Intenta cambiar al directorio
        ftp_server.cwd(directorio)
        # Si se pudo cambiar, vuelve al directorio anterior
        ftp_server.cwd('..')
        return True
    except ftplib.error_perm:
        # Si lanza error_perm, el directorio no existe
        return False

Progama completo:

# -*- coding: utf-8 -*-
"""
Created on Thu Jul 17 14:06:51 2025

@author: EA7TB
"""
# Import Module
import ftplib

# Fill Required Information
HOSTNAME = "ftp.dlptest.com"
USERNAME = "dlpuser"
PASSWORD = "rNrKYTX9g7z3RgJRmxWuGHbeu"

# Connect FTP Server
ftp_server = ftplib.FTP(HOSTNAME, USERNAME, PASSWORD)

# force UTF-8 encoding
ftp_server.encoding = "utf-8"

def listado():
    # Get list of files
    ftp_server.dir()


#Subir un fichero
def subir_fichero():
    filename = "ejemplo.txt"
    # Leemos el fichero en modo binario
    with open(filename, "rb") as file:
        # Comando para UPloading el fichero "STOR filename"
        ftp_server.storbinary(f"STOR {filename}", file)
        
def descargar_fichero():
    filename = "ejemplo.txt"
    # Escribimos el fichero en modo binario
    with open(filename, "wb") as file:
        # Comand para Downloading el fichero "RETR filename"
        ftp_server.retrbinary(f"RETR {filename}", file.write)
    
def crear_directorio():
    try:
        directorio = "ejemplo"
        ftp_server.mkd(directorio)
        print(f"Directorio '{directorio}' creado exitosamente.")
        ftp_server.quit()
    except ftplib.all_errors as e: 
      print(f"Error al crear el directorio: {e}")


def comprobar_directorio(directorio):
    """
     Comprueba si un directorio existe en un servidor FTP.
    Argumentos:
        ftp: Objeto FTP conectado al servidor.
        directorio: Nombre del directorio a comprobar.
    Avisos:
        True si el directorio existe
        ,False en caso contrario.
    """
    try:
        # Intenta cambiar al directorio
        ftp_server.cwd(directorio)
        # Si se pudo cambiar, vuelve al directorio anterior
        ftp_server.cwd('..')
        return True
    except ftplib.error_perm:
        # Si lanza error_perm, el directorio no existe
        return False


subir_fichero()
listado()
descargar_fichero()
print(comprobar_directorio("ejemplo"))
crear_directorio("ejemplo")
ftp_server.close()

Existen mas comandos, se pueden ver en la documentación de Python

FICHEROS DE CONFIGURACION

Para no modificar el fichero de configuración, podemos generar un fichero INI, donde estén todas las variables del programa.

La librería de Python que usaremos es ConfigParser ( https://pypi.org/project/configparser/ ). Para instalarla,

pip install configparse

FICHERO INI:

Esta estructurado en secciones, indicando en corchetes, y entradas. El nombre dentro del corchete indica la sección de la configuración.

Los valores se muestran especificando primero el nombre y luego el valor. Por ejemplo:

[GESTION]
nombre=“Gesstion de archivos"
versión = 1.0
autor="EA7TB"
locator= “IM76SR”
[ACTIVIDAD]
indicativo = “EH7SCB”
dme = “29078”
referencia = “MVMA-0234”
nombre = “Iglesia Santuario del Pilar”
nombre=“Gesstion de archivos"
version=1.0
autor="EA7TB"
locator= “IM76SR”
[ACTIVIDAD]
indicativo = “EH7SCB”
dme = “29078”
referencia = “MVMA-0234”
nombre = “Iglesia Santuario del Pilar”


Para leer los datos , se pueden ver en el ejemplo siguiente:

#!/usr/bin/env python
#!/usr/bin/env python3 
"""
Created on Tue Jul 15 17:24:34 2025
@author: EA7TB
"""
from configparser import ConfigParser
configfile_name = "config.ini" 
# leemos el fichero de configuración
config = ConfigParser()
config.read("config.ini")
# Imprime el numero de secciones
sections = config.sections()
print("%d secciones:" % len(sections))  # Cantidad de secciones
# imprime todos los valores de todas las secciones del archivo
for section in config.sections():
  print("\n[%s]" % section)
  for item in config.items(section):
      print(item[0], ":", item[1])
#asigna el valor de "indicativo" a call, después se imprime
call = config.get("ACTIVIDAD", "indicativo")
print("\n")
print(call)

Dependiendo del tipo de datos, para leerlos se usara:

  • Texto: config.get(section, option)
  • Boolean: config.getboolean(section, option)
  • Float: config. getfloat(section, option)
  • Integer: config.getint(section, option)