El mes pasado (Noviembre 2012) presenté mi trabajo con PythonSharp en PyCon 2012 Argentina (ver post), un intérprete Python 3.x que estoy escribiendo en C#. Como en otras de mis implementaciones, éste puede acceder a tipos nativos, para poder aprovechar lo que brinda una librería de clases ya implementada. Como prueba de concepto, escribí un ejemplo de servidor web mínimo:
from System import Array, Byte
from System.Net import HttpListener
from System.IO import Path, FileStream, FileMode, File
root = "c:/apache-tomcat-6.0.18/webapps/docs"
bytes = Array.CreateInstance(Byte,1024)
listener = HttpListener()
listener.Prefixes.Add("http://*:8000/")
def process(context):
filename = context.Request.Url.AbsolutePath
if not filename or filename == '/':
filename = "index.html"
if filename[0] == '/':
filename = filename[1:]
print(filename)
filename = Path.Combine(root, filename)
print(filename)
if not File.Exists(filename):
context.Response.Abort()
return
input = FileStream(filename, FileMode.Open)
bytes = Array.CreateInstance(Byte, 1024 * 16)
nbytes = input.Read(bytes, 0, bytes.Length)
while nbytes>0:
context.Response.OutputStream.Write(bytes, 0, nbytes)
nbytes = input.Read(bytes, 0, bytes.Length)
input.Close()
context.Response.OutputStream.Close()
listener.Start()
while True:
context = listener.GetContext()
print("new request")
process(context)
Vean el archivo en el repo:
https://github.com/ajlopez/PythonSharp/blob/master/Src/PythonSharp.Console/examples/httpserver.py
Para ejecutar el ejemplo, hay que compilar la solución, y el proyecto PythonSharp.Console produce entonces un programa de consola pysh.exe. Pueden cambiar el valor de la variable root, que apunta en el ejemplo de arriba a mi disco local, donde tengo unos archivos estáticos con la documentación de un servidor Tomcat ;-) . Ejecutando pysh Programs\httpserver.py, se levanta el servidor, al que pueden como http://localhost:8080

El código de este servidor mínimo se basa en mis anteriores ejemplos:
A Minimal Http Server In C#
A Minimal Http Server in Java
Como ven en el código, puedo importar namespaces .NET y manejarlos como si fueran módulos de Python. Estoy trabajando con .NET 3.5 (me gusta mantener al mínimo los requerimientos) así que no pude aprovechar otros métodos para copiar un archivo a la corriente de salida de la respuesta web, vean:
Best way to copy between two Stream instances
Ahora, pasé a trabajar en tener la misma implementación para mi AjTalk, una Smalltalk Virtual Machine en C#. Ya lo tengo andando, pero eso es tema para otro post.
Nos leemos!
Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez