Entrega de archivos con el módulo SimpleHTTPServer de Python

E

Introducción

Los servidores son software o hardware de computadora que procesa solicitudes y entrega datos a un cliente a través de una red. Existen varios tipos de servidores, siendo los más comunes servidores web, servidores de bases de datos, servidores de aplicaciones y servidores de transacciones.

Servidores web ampliamente utilizados como apache, Monoy Rompecabezas son bastante laboriosos de configurar cuando se prueban proyectos simples y el enfoque del desarrollador se desplaza de producir lógica de aplicación a configurar un servidor.

Python SimpleHTTPServer El módulo es una herramienta útil y sencilla que los desarrolladores pueden usar para una serie de casos de uso, siendo el principal que es una forma rápida de entregar archivos desde un directorio.

Elimina el laborioso proceso asociado con la instalación e implementación de los servidores web multiplataforma disponibles.

Nota: Mientras SimpleHTTPServer es una excelente manera de servir archivos fácilmente desde un directorio, no debe usarse en un entorno de producción. Según los documentos oficiales de Python, “solo implementa controles de seguridad básicos”.

¿Qué es un servidor HTTP?

HTTP significa Protocolo de transferencia de hipertexto. Pensemos en un protocolo como un idioma hablado como el inglés. El inglés tiene un conjunto de reglas y vocabulario. Por lo tanto, si ambos comprendemos las reglas y el vocabulario que definen el idioma inglés, entonces podemos comunicarnos en el idioma de manera efectiva.

Al igual que los seres humanos, los dispositivos electrónicos también se comunican entre sí. Por lo tanto, necesitan un ‘conjunto de reglas y vocabulario’ para pasar y recibir información de forma activa entre ellos.

Un protocolo es un conjunto estándar de reglas que facilita la comunicación exitosa entre dispositivos electrónicos. Estos conjuntos de reglas implementadas y aceptadas mutuamente incluyen los comandos utilizados para iniciar el envío y la recepción de datos, los tipos de datos que se transmitirán entre dispositivos, cómo detectar errores en los datos, cómo se confirman las transferencias de datos exitosas y mucho más.

Por ejemplo, cuando realiza una búsqueda simple utilizando un navegador, hay dos sistemas esenciales involucrados: el cliente HTTP y el servidor HTTP.

El cliente, comúnmente conocido como navegador, puede ser un programa elaborado como Google Chrome o Firefox, pero también puede ser tan simple como una aplicación CLI. El cliente envía su solicitud al servidor, que procesa las solicitudes HTTP y proporciona una respuesta al cliente. En el caso de los navegadores, la respuesta suele ser una página HTML.

Módulo SimpleHTTPServer de Python

Cuando necesita un servidor web rápido en funcionamiento, configurar un servidor de nivel de producción es una exageración enorme.

Python SimpleHTTPServer El módulo es una herramienta que ahorra trabajo y que puede aprovechar para convertir cualquier directorio de su sistema en un servidor web sin complicaciones. Viene empaquetado con un servidor HTTP simple que ofrece estándares GET y HEAD manipuladores de solicitudes.

Con un servidor HTTP integrado, no es necesario que instale o configure nada para tener su servidor web en funcionamiento.

Nota: El Python SimpleHTTPServer módulo se fusionó en el http.server en Python 3. A lo largo de este artículo usaremos la versión de Python 3, pero si está usando Python 2, puede cambiar http.server para SimpleHTTPServer y debería funcionar en la mayoría de los casos.

Uso de la línea de comandos

La forma más sencilla de iniciar un servidor web que sirve al directorio en el que se ejecuta el comando es simplemente navegar al directorio de su proyecto usando la terminal y ejecutar:

Python 2

$ python -m SimpleHTTPServer 8000

Python 3

$ python3 -m http.server 8000

Al ejecutar este comando, podrá acceder a los archivos en su directorio a través de su navegador en localhost:8000:

Como puede ver, el servidor proporciona una interfaz de usuario de directorio simple en la que puede acceder a cualquiera de los archivos. Esta es la forma más sencilla de servir archivos directamente de forma local a través de HTTP.

Uso de Python predeterminado

Por una razón u otra, ejecutar este servidor a través de la línea de comandos podría no adaptarse a nuestro caso de uso. En momentos como este, podemos usar el servidor directamente en nuestro código usando el SimpleHTTPRequestHandler objeto. Pero primero, necesitamos configurarlo con un servidor de socket.

Debajo del protocolo HTTP se encuentran UDP (Protocolo de datagramas de usuario) o TCP (Protocolo de control de transmisión), que son protocolos de transporte que manejan el transporte de datos de una ubicación de red a otra. Dado que estamos ejecutando un servidor HTTP, nuestra aplicación utilizará el protocolo TCP, a través de una dirección de socket TCP que contiene una dirección IP y un número de puerto. Esto se puede configurar con Python socketserver.TCPServer, que implementamos a continuación:

import http.server
import socketserver

PORT = 8000

handler = http.server.SimpleHTTPRequestHandler

with socketserver.TCPServer(("", PORT), handler) as httpd:
    print("Server started at localhost:" + str(PORT))
    httpd.serve_forever()

Nota: El código fallará con el error AttributeError: __exit__ para las versiones de Python <3.6. Esto se debe a que en versiones anteriores socketserver.TCPServer no admite el uso con administradores de contexto (el with palabra clave). En estos casos necesita llamar server_close() para detener el servidor.

Por defecto, el SimpleHTTPRequestHandler sirve archivos del directorio actual y subdirectorios relacionados. Como sugiere el nombre, es un sencillo controlador de solicitudes HTTP. Siendo el servidor simple que es, solo le permite recuperar datos y no publicarlos en el servidor. Y debido a esto, solo implementa HTTP GET y HEAD métodos a través de do_GET() y do_HEAD().

Los parámetros pasados ​​al TCPServer representan la dirección IP y el número de puerto. Al dejar la dirección IP vacía, el servidor escucha todas las direcciones IP disponibles, mientras que configuramos el puerto en 8000. Esto significa que entonces sería accesible en localhost:8000.

Finalmente, httpd.server_forever() inicia el servidor, escucha y responde a las solicitudes entrantes del cliente.

El servidor se puede iniciar simplemente ejecutando el archivo:

$ python3 simple-server.py

Y al igual que con el uso de la línea de comandos, ahora podemos acceder al directorio a través de nuestro navegador web:

Personalización de rutas

Otro enfoque que podemos adoptar es crear una clase personalizada que se extienda SimpleHTTPRequestHandler y maneja nuestras solicitudes con algunas funciones personalizadas. Para hacer esto, implementamos nuestro propio do_GET() función.

Pero antes de llegar a eso, digamos que tenemos un archivo HTML que queremos servir, mywebpage.html:

<!DOCTYPE html>
<html>
<head>
  <title>Using Python's SimpleHTTPServer Module</title>
  <style>
    #rectangle {
      height: 50px;
      width: 100px;
      background-color: #00f28f;
    }
  </style>
</head>
<body>
  <h2>Rectangle served by SimpleHTTPServer</h2>
  <div id="rectangle"></div>
</body>
</html>

Para servir este HTML desde una ruta que no es /mywebpage.html, podemos usar nuestro controlador personalizado para publicarlo en cualquier ruta que queramos. En este ejemplo, lo serviremos en la ruta raíz, /:

import http.server
import socketserver

class MyHttpRequestHandler(http.server.SimpleHTTPRequestHandler):
    def do_GET(self):
        if self.path == "https://Pharos.sh.com/":
            self.path="mywebpage.html"
        return http.server.SimpleHTTPRequestHandler.do_GET(self)

# Create an object of the above class
handler_object = MyHttpRequestHandler

PORT = 8000
my_server = socketserver.TCPServer(("", PORT), handler_object)

# Star the server
my_server.serve_forever()

Nuevamente, ejecutar este script nos permitirá acceder a él a través del navegador:

Sin embargo, hay muchas más personalizaciones que podemos hacer con la respuesta a través del self referencia, que veremos en la siguiente sección.

Devolución de HTML dinámico

Un uso común de los servidores web es servir HTML generado dinámicamente. Aunque este es solo un servidor muy simple, también puede realizar esta tarea. Además de enviar HTML dinámico, también podemos establecer diferentes códigos de estado, encabezados, etc. En el siguiente ejemplo establecemos algunos encabezados y devolvemos HTML dinámico que se genera usando el parámetro de consulta name:

import http.server
import socketserver
from urllib.parse import urlparse
from urllib.parse import parse_qs

class MyHttpRequestHandler(http.server.SimpleHTTPRequestHandler):
    def do_GET(self):
        # Sending an '200 OK' response
        self.send_response(200)

        # Setting the header
        self.send_header("Content-type", "text/html")

        # Whenever using 'send_header', you also have to call 'end_headers'
        self.end_headers()

        # Extract query param
        name="World"
        query_components = parse_qs(urlparse(self.path).query)
        if 'name' in query_components:
            name = query_components["name"][0]

        # Some custom HTML code, possibly generated by another function
        html = f"<html><head></head><body><h1>Hello {name}!</h1></body></html>"

        # Writing the HTML contents with UTF-8
        self.wfile.write(bytes(html, "utf8"))

        return

# Create an object of the above class
handler_object = MyHttpRequestHandler

PORT = 8000
my_server = socketserver.TCPServer(("", PORT), handler_object)

# Star the server
my_server.serve_forever()

Y ejecutando este código con la URL http://localhost:8000?name=Billy rendirá:

Cualquier valor que establezca para name El parámetro de consulta aparecerá en la pantalla. Incluso puede omitir el name parámetro de consulta y ver qué sucede.

Como puede ver, la creación de un controlador de solicitud personalizado nos permite manipular las respuestas tanto como queramos cambiando la implementación de la do_GET método y no tenemos tal control sobre nuestras respuestas con la implementación predeterminada.

Lo mismo se puede hacer con el método HTTP HEAD (a través del do_HEAD() function), pero como es muy similar al método GET, lo dejamos como ejercicio para el lector.

Conclusión

Python nos proporciona la SimpleHTTPServer módulo (o http.server en Python 3) que se puede utilizar para servir archivos de forma rápida y sencilla desde un directorio local a través de HTTP. Esto se puede utilizar para muchas tareas de desarrollo u otras tareas internas, pero no está destinado a la producción.

Esta es una gran solución para uso local, ya que servidores web como apache, Monoy Rompecabezas son mucho más difíciles de configurar y suelen ser excesivos para las actividades de desarrollo.

About the author

Ramiro de la Vega

Bienvenido a Pharos.sh

Soy Ramiro de la Vega, Estadounidense con raíces Españolas. Empecé a programar hace casi 20 años cuando era muy jovencito.

Espero que en mi web encuentres la inspiración y ayuda que necesitas para adentrarte en el fantástico mundo de la programación y conseguir tus objetivos por difíciles que sean.

Add comment

Sobre mi

Últimos Post

Etiquetas

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con tus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, aceptas el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Más información
Privacidad