Entrega de archivos con el m贸dulo SimpleHTTPServer de Python

    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 鈥嬧媋l 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.

    Etiquetas:

    Deja una respuesta

    Tu direcci贸n de correo electr贸nico no ser谩 publicada. Los campos obligatorios est谩n marcados con *