Python en la web
Recientemente se me están ocurriendo muchos micro-proyectos en red, y cada vez estoy más convencido que es interesante plantearse siempre la opción ReST , frente a otro tipo de middleware.
Podéis pensar: ¿Y me voy a crear todo un servidor web para esta tontería? Pues mi respuesta es que sí, ya que ReST ofrece muchas ventajas frente al resto:
- Multilenguaje. Al fin y al cabo, consiste en mensajes de texto plano.
- Sencillo. Se puede utilizar
ncat
para probarlo. - Versátil. Basta cambiar el
content-type
para soportar XML, JSON, YAML, JPG, Streaming, …
Vaaaaaale, en informática no existe una solución universal para todo y es muy probable que le encontremos problemas, como el tiempo de respuesta, que las operaciones no deberían tener estado, etc. pero, como he dicho, debe ser una opción a evaluar.
El caso es que vamos a crearnos una calculadora tremendamente potente en 30 líneas de código. Y el cliente tendrá la friolera de… 8 líneas. ¿Qué me decís ahora? ¿Merece la pena tenerlo en cuenta?
El servidor
Primero el código y luego lo vemos:
|
|
Vamos con la parte principal: selecciono un puerto (el 2349) y me creo un SocketServer, indicándole que use como backend mi clase principal. Por razones estéticas, me imprimo el puerto y me pongo a escuchar (lo que se conoce como un “bucle de eventos”).
Mi clase principal hereda de SimpleHTTPRequestHandler, lo que me da resueltos casi todos mis problemas. Como soy muy indeciso, decido implementar tanto el método GET como el POST, llamando ambos a “process”.
Vamos a fijarnos en la parte más importante: mi método process. Sólo tiene 3 líneas pero son muy matonas. Copiémoslo de nuevo:
|
|
En estas 3 líneas estamos construyendo la respuesta. Primero indico el código de respuesta (200 viene a ser un “todo va bien”).
Después indico que se han acabado las cabeceras. Las cabeceras se separan del cuerpo por un salto de línea, así que esta línea está imprimiendo un ‘\n’ nada más, pero es indispensable.
Finalmente, escribo en el buffer de salida la respuesta que quiero dar.
También es importante la lectura del cuerpo del mensaje. Lo copio de nuevo:
|
|
Primero tengo que obtener la longitud del stream y luego leerla. Al ser un stream abierto, si tratamos de leerlo entero nunca terminará, ya que el socket sigue abierto.
El resto es la implementación de mi “calculadora”, que veréis que no es más que una llamada a “eval”. No tiene mayor misterio.
El cliente
Y ahora vamos con el cliente. Primero el código:
|
|
Sí, como habéis observado estoy probando mi servidor :D
Lo más importante de este código es la función send_operation
, donde
conecto con mi servidor, le envío una solicitud y devuelvo el body. No hace
nada más.
El resto son comprobaciones varias demostrando la potencia de mi “calculadora”, ya que suma hasta cadenas XD
Más información
En esta ocasión sólo he utilizado la biblioteca estándar de python. No hay dependencias externas ni cosas raras. Así que lo mejor es ir a la propia documentación de python .