Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Otros entornos y lenguajes > Python
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 11-09-2012
Avatar de D-MO
D-MO D-MO is offline
Miembro
 
Registrado: ago 2005
Ubicación: root@debian:/#
Posts: 1.042
Poder: 21
D-MO Va por buen camino
Bibliotecas de terceros en hospedaje compartido

Aquí la segunda parte del uso de python en hospedaje compartido, la primera parte está aquí.

Ahora veremos algo con mas posibilidades que simplemente el "Hola Mundo" de la primera parte. Se trata de utilizar bibliotecas de terceros dentro de nuestro proyecto en un hospedaje compartido sin que estas bibliotecas hayan sido instaladas previamente por root, sino que utilizando un directorio local/privado de paquetes python. Esta no es la mejor*1 forma de hacerlo pero opté por ella porque para fines didácticos es la mas fácil y funcional, además de que será el punto de partida para una siguiente fase, un poquito mas avanzada.

El objetivo ahora es poder utilizar un framework web de python que sea el punto de partida para realizar una aplicación web cualquiera utilizando bibliotecas de terceros.

Una herramienta muy fácil de utilizar es web.py, un framework bastante sencillo como poderoso. De él conozco muy poco, pero lo poco que conozco es suficiente para lo que necesitamos.

La aplicación web que propongo no tendrá una funcionalidad muy útil que digamos y mucho menos será nada avanzado, puesto que, lo que nos interesa ahora es utilizar bibliotecas de terceros y empezar a hacer algo dinámico para partiendo de esto lleguemos a hacer algo mas útil donde utilicemos Bases de Datos, usuarios, servicios externos, etc...

Entonces, dejando claro esto, me parece conveniente hacer una utilidad que realice operaciones matemáticas según parámetros de url. Como dije arriba, nada complicado ni útil, pero si didáctico.

Partiendo de la primera parte de este tutorial, creamos un nuevo archivo .py que será el cgi de esta aplicación, llamémosle mate.py, quedándonos entonces una url como: http://midominio.com/cgi-bin/mate.py

Agreguemos a este archivo el mismo código del primer tutorial, con el fin de asegurarnos que nos funciona como el anterior y partamos de allí.

Código:
#!/usr/bin/env python
# -*- coding: UTF-8 -*-

# enable debugging
import cgitb
cgitb.enable()

print "Content-Type: text/plain;charset=utf-8"
print

print "Hello World!"
No olvidar asignarle permisos entre 755 y 777 con tal de que apache lo pueda ejecutar. Ahora a probarlo y si obtenemos el saludo esperado, entonces continuamos.

Prerequisitos
Antes que nada debemos saber que prerequisitos tienen los paquetes que vamos a utilizar porque debemos descargarlos manualmente*2 ya que de momento no contamos con un gestor de paquetes.

Como vamos a utilizar webpy, este sería el primer paquete, además, webpy tiene como prerequisito otro paquete llamado flup. Los links para las versiones estables en este momento son:
Webpy - http://webpy.org/static/web.py-0.37.tar.gz
Flup - http://pypi.python.org/pypi/flup/1.0.2

Estos paquetes vienen con la estructura estandar de paquetes python pero como ahora no tenemos un gestor de paquetes debemos fijarnos bien sobre que es lo que vamos a subir al servidor para que funcione como esperamos (pues de lo contrario no funcioanrá nada). En este caso, estos paquetes tienen en su interior un directorio llamado web y flup respectivamente, estos son los directorios que nos interesan.

Extraigamos el contenido de estos paquetes y copiemos los directorios web y flup dentro del cgi-bin (se que no es lo mas indicado, pero como dije antes, es solo para fines didácticos) quedándonos ahora una estructura de directorios parecida a esta:
Código:
/cgi-bin/
 |...web/
      |...***
      |...application.py
      |...browser.py
      |...***
 |...flup/
      |...client/
      |...server/
      |...__init__.py
 |...mate.py
Ahora modifiquemos mate.py para incluir lo mínimo requerido para hacer funcionar webpy y dejémoslo de esta forma:

Código:
#!/usr/bin/env python
# -*- coding: UTF-8 -*-

# enable debugging
import cgitb; cgitb.enable()

# Third party libraries
import web

urls = (
    '/.*', 'index',
)

app = web.application(urls, globals())

class index:        
    def GET(self):
    	return 'Hola'

app.run()
Si todo va bien, de nuevo el navegador nos estará saludando.

URLs limpias
Como esta aplicación actuará dependiendo de la url que el usuario ingrese, no me gusta para nada que la url base sea "/cgi-bin/mate.py", en cambio, prefiero utilizar el prefijo "/mate/" de modo que me permita tener múltiples aplicaciones configuradas en un mismo dominio/ip. Para ello recurrimos al ModRewrite de apache y agregamos al .htaccess algo como esto:
Código:
RewriteEngine on
RewriteBase /
RewriteRule ^mate(.*)$ cgi-bin/mate.py [PT]
No soy ningún experto en apache y menos en reglas de reescritura, así que esto puede ser mejorado.

También debemos configurar las urls de nuestra aplicación para incluir el prefijo puesto que webpy hace un match sobre la url completa. Lo dejamos de la siguiente manera:

Código:
urls = (
    '/mate/', 'index',
)
De este modo, cuando entremos a http://midominio.com/mate/ no estará cargando la vista index de nuestra aplicación.

Ahora es tiempo de agregar las operaciones que realizará nuestra utilidad matemática, primero nos vamos por las urls.

Código:
urls = (
    '/mate/', 'index',
    '/mate/suma/(.*)/(.*)', 'suma',
    '/mate/resta/(.*)/(.*)', 'resta',
    '/mate/cuadrado/(.*)', 'cuadrado',
    '/mate/cubo/(.*)', 'cubo'
)
Cita:
Observaciones:
  • Todas las urls llevan el prefijo /mate/
  • (.*) es una expresión regular que será transformada en argumento para la función GET de la vista
  • Pueden existir tantos grupos de expresiones regulares como parámetros necesitemos
Ahora nos vamos a las vistas:
Código:
class suma:        
    def GET(self, x, y):
        ix, iy = int(x), int(y)
        r = ix + iy
        return r


class resta:        
    def GET(self, x, y):
        ix, iy = int(x), int(y)
        r = ix - iy
        return r


class cuadrado:        
    def GET(self, x):
        ix = int(x)
        r = ix * ix
        return r


class cubo:        
    def GET(self, x):
        ix = int(x)
        r = ix * ix * ix
        return r
Cita:
Observación:
El mismo número de expresiones regulares tenemos en urls como en parámetros del método GET de la vista adicional al self, ej: '/mate/suma/(.*)/(.*)' => def GET(self, x, y)
Eso sería mas que suficiente para mostrar el resultado, pero en este caso, quiero que la respuesta venga en formato "Resultado: [ <R> ]" así que defino un metodo que me servirá para empaquetar el resultado, manteniendo un código limpio.

Código:
def response(r):
    return 'Resultado: [ %s ]' % r
Este método lo dejo en la parte superior (por simple estética) y lo llamo desde cada vista de la siguiente manera:

Código:
class cubo:        
    def GET(self, x):
        ix = int(x)
        r = ix * ix * ix
        return response(r)
Además, quiero poner una ayuda en el index, así que defino la variable "help" al inicio y devuelvo su valor en la vista.

Código:
help = '''
Servicio Web de Mate
====================

Usa cualquiera de las siguientes urls:

  /suma/<X>/<Y>		Suma los valores X y Y
  /resta/<X>/<Y>	Resta el valor de Y a X
  /cuadrado/<X>		Devuelve el cuadrado de X
  /cubo/<X>		Devuelve el cubo de X
  
  Nota: Los valores de X y Y deben ser enteros
'''
El código final queda de la siguiente manera:

Código:
#!/usr/bin/env python
# -*- coding: UTF-8 -*-

# enable debugging
import cgitb; cgitb.enable()

# Third party libraries
import web

help = '''
Servicio Web de Mate
====================

Usa cualquiera de las siguientes urls:

  /suma/<X>/<Y>		Suma los valores X y Y
  /resta/<X>/<Y>	Resta el valor de Y a X
  /cuadrado/<X>		Devuelve el cuadrado de X
  /cubo/<X>		Devuelve el cubo de X
  
  Nota: Los valores de X y Y deben ser enteros
'''

def response(r):
    return 'Resultado: [ %s ]' % r


urls = (
    '/', 'index',
    '/suma/(.*)/(.*)', 'suma',
    '/resta/(.*)/(.*)', 'resta',
    '/cuadrado/(.*)', 'cuadrado',
    '/cubo/(.*)', 'cubo'
)


app = web.application(urls, globals())


class index:        
    def GET(self):
    	return help


class suma:        
    def GET(self, x, y):
        ix, iy = int(x), int(y)
        r = ix + iy
        return response(r)


class resta:        
    def GET(self, x, y):
        ix, iy = int(x), int(y)
        r = ix - iy
        return response(r)


class cuadrado:        
    def GET(self, x):
        ix = int(x)
        r = ix * ix
        return response(r)


class cubo:        
    def GET(self, x):
        ix = int(x)
        r = ix * ix * ix
        return response(r)


app.run()
¿Quién se anima ahora a hacer este wiki.

Notas
  • *1.- Digo que no es la mejor forma no porque no funcione bien, sino porque al trabajar aplicaciones grandes que requieran de múltiples bibliotecas de terceros será muy difícil de mantener al día todo, sin embargo, de que funciona, funciona... ¡Y lo hace muy bien!.
  • Para no complicar el tema, los valores a procesar se convierten a enteros. Fallará (intencionalmente) si se usan decimales.
Responder Con Cita
  #2  
Antiguo 11-09-2012
Avatar de mamcx
mamcx mamcx is offline
Moderador
 
Registrado: sep 2004
Ubicación: Medellín - Colombia
Posts: 3.927
Poder: 26
mamcx Tiene un aura espectacularmamcx Tiene un aura espectacularmamcx Tiene un aura espectacular
Unas notas:

1) Porque no usas las funciones matematicas de python?

2) Una definicion tipo
Código PHP:
Nombre class: 
esta reemplazada por
Código PHP:
Nombre class:(object) 
.

3) La expresion regular se puede mejor cambiando a "\d+". "\d" solo capura numeros, "+" se asegura que haya al menos 1 numero que capturar, en cambio "*" dice, captura tenga o algo que capturar.

4) Si encierras con etiqueta [php] masomenos te da un coloreado parecido para python

Por lo demas, gracias por el aporte!
__________________
El malabarista.
Responder Con Cita
  #3  
Antiguo 11-09-2012
Avatar de D-MO
D-MO D-MO is offline
Miembro
 
Registrado: ago 2005
Ubicación: root@debian:/#
Posts: 1.042
Poder: 21
D-MO Va por buen camino
Cita:
Empezado por mamcx Ver Mensaje
1) Porque no usas las funciones matematicas de python?
Digamos que quise hacerlo lo mas simple posible para no meter funciones extras y que se entienda a simple vista sin explicar lo que hace cada función. creo que se entiende mas fácil x * x que math.pow(x, 2), además de que debería importar math y explicar sus funciones. Ya en un escenario real porsupuesto que las usaría... perdón, uso .

Cita:
Empezado por mamcx Ver Mensaje
2) Una definicion tipo
Código PHP:
Nombre class: 
esta reemplazada por
Código PHP:
Nombre class:(object) 
.
Con webpy no he hecho nada mas grande que lo que hice ahora y lo elegí para esta tutorial por su simplicidad, solo hice un copy & paste del ejemplo de la web del proyecto y no me preocupé tanto por ser pythonic... pero viendo tu ejemplo, no sería:
Código PHP:
Nombre class(object): 
Cita:
Empezado por mamcx Ver Mensaje
3) La expresion regular se puede mejor cambiando a "\d+". "\d" solo capura numeros, "+" se asegura que haya al menos 1 numero que capturar, en cambio "*" dice, captura tenga o algo que capturar.
Claro, pero por lo mismo de la nota 1, no quería extender el texto tratando de explicar el porqué un patrón u otro... además de que no soy un experto en ello.

Cita:
Empezado por mamcx Ver Mensaje
4) Si encierras con etiqueta [php] masomenos te da un coloreado parecido para python
Gracias, no había pensado en ello.

Cita:
Empezado por mamcx Ver Mensaje
Por lo demas, gracias por el aporte!
A ti gracias por las observaciones .

Saludos
Responder Con Cita
  #4  
Antiguo 11-09-2012
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Muchas gracias D-MO, mañana lo leeré con calma.

// Saludos
Responder Con Cita
  #5  
Antiguo 11-09-2012
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.264
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
ufff... un curso acelerado, habrá que ponerse con ello
Gracias.
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Python en hospedaje compartido (shared hosting) D-MO Python 6 25-07-2012 17:40:24
Bibliotecas Dinamicas Magui Varios 1 11-04-2005 18:55:33
Bibliotecas de Tipos. jplj OOP 0 05-10-2004 13:17:07
hospedaje CGI Onti Internet 1 17-06-2004 03:38:45


La franja horaria es GMT +2. Ahora son las 20:06:34.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi