如果您对Python的Web应用程序的开发感兴趣,那么这些首字母缩写词甚至可能从概念上讲是什么,甚至可能更清楚。
WSGI ,适合这位赞助人。该定义在PEP 3333中被重新训练。好吧,实际上,这适用于python的 3.x 版本( 2.x 版本的初始定义是PEP 333。
在Python中包含的软件包中,我们可以找到一个参考WSGI Web服务器( wsiref.simple_server )和一个演示应用程序。
进行演示后,我们将开始工作并实施我们的第一个版本。
from wsgiref.simple_server import make_server, demo_app
IP = "0.0.0.0"
PUERTO = 8080
APP = demo_app
print(f"Iniciando aplicación APP en servidor WSGI en { IP }: { PUERTO }")
with make_server(IP, PUERTO, APP) as servidor_wsgi:
print("Puedes finalizar con CTRL+C")
servidor_wsgi.serve_forever()
如果我们执行刚刚编写的代码,我们将筹集 wsgi Web服务器,等待请愿 http 到端口 8080 。>
现在我们可以打开喜欢的浏览器并请求以下URL(http://localhost:8080)。而且,âh惊喜! variable ='value'。
到达了这一点,并实现了标题中指示的目标,因此我们已经可以得出结论。但是不要担心,尽管不多,但我们将在这个主题上加深一点。
总结到极端,应用程序wsgi ,它必须是一定的 (一个函数或实现不利>的对象),它将接收到它 2参数。第一个是执行环境,第二个是回调,必须称呼它才能构建答案。
我们的演示应用程序向我们展示了执行环境的内容。具有环境变量值的字典,我们的Web服务器包含了一些其他值(例如 path_info ='/',其中包含我们上面要求的资源路由服务器)。另一方面,我们的申请将返回以交付给申请人的响应。
我们去创建我们的第一个WSGI应用程序,留下我们的代码,并具有类似的内容:
from wsgiref.simple_server import make_server
#=============================================================================
# Esta función es nuestra aplicación WSGI y, como tal, al ser llamada
# recibirá los 2 parámetros esperados:
# * diccionario con el entorno de ejecución.
# * callback para crear respuesta.
#=============================================================================
def mi_app_wsgi(entorno, responder):
# Configuramos opciones de respuesta por defecto
cabeceras = [('Content-type', 'text/plain; charset=utf-8')]
# Iniciamos respuesta
responder('200 OK', cabeceras)
respuesta = "Contenido devuelto por mi_app_wsgi."
# El cuerpo de la respuesta no puede ser un string.
# Debe ser una lista de bytes.
return [respuesta.encode("utf-8")]
IP = "0.0.0.0"
PUERTO = 8080
APP = mi_app_wsgi
print(f"Iniciando aplicación APP en servidor WSGI en { IP }: { PUERTO }")
with make_server(IP, PUERTO, APP) as servidor_wsgi:
print("Puedes finalizar con CTRL+C")
servidor_wsgi.serve_forever()
新版本没有太大变化。我们已经解决了 mi_app_wsgi函数,它将接收2个预期参数,重要的是,它将返回一个字节 (如果我们返回,因为它与预期的不符)。
也有必要称为 calback 函数(在我们的具体情况下,我们称其为答案)。因此,我认为代码足够解释,不需要任何其他解释。
如果我们执行了新版本,并且再次请求http://localhost:8080 URL,我认为这是可以预见的,我们将获得的结果是什么。
我们也可以在这里留在这里,但是由于我们被放置,我们会做一些更精心的事情。
from wsgiref.simple_server import make_server
from base64 import b64decode
#=============================================================================
# Esta función es una aplicación WSGI y, como tal, al ser llamada
# recibirá los 2 parámetros esperados:
# * diccionario con el entorno de ejecución.
# * callback para crear respuesta.
#=============================================================================
def mi_app_wsgi(entorno, responder):
# Configuramos opciones de respuesta por defecto
cabeceras = [('Content-type', 'text/plain; charset=utf-8')]
# Iniciamos respuesta
responder('200 OK', cabeceras)
respuesta = "Contenido devuelto por mi_app_wsgi."
# El cuerpo de la respuesta no puede ser un string.
# Debe ser una lista de bytes.
return [respuesta.encode("utf-8")]
#=============================================================================
# Esta clase es nuestra aplicación WSGI y, como tal, al ser llamada
# recibirá los 2 parámetros esperados:
# * diccionario con el entorno de ejecución.
# * callback para crear respuesta.
#=============================================================================
class AutenticacionBasica():
USUARIO = "mi_usuario"
PASSWORD = "mi contraseña"
def __init__(self, app):
self._app = app
def __call__(self, entorno, responder):
# Comprobamos si la solicitud tiene una cabecera de autenticación válida.
# Si esto es así, llamamos a nuestra otra aplicación WSGI y devolveremos
# lo que ésta nos devuelva.
if self._autenticado(entorno.get('HTTP_AUTHORIZATION')):
return self._app(entorno, responder)
# Solicitamos autenticación para peticiones no autenticadas-
return self._no_autenticado(entorno, responder)
def _autenticado(self, cabecera_autenticacion):
# Comprobamos si hemos recibido cabedera de autenticación
if not cabecera_autenticacion:
return False
# Si hemos recibido cabedera de autenticación, decodificamos contenido y
_, valor_codificado = cabecera_autenticacion.split(None, 1)
valor_decodificado = b64decode(valor_codificado).decode('utf-8')
username, password = valor_decodificado.split(':', 1)
# comprobamos si usuario y contraseña se corresponden con valores aceptados
# como válidos.
return username == self.USUARIO and password == self.PASSWORD
def _no_autenticado(self, entorno, responder):
# Configuramos cabecras por defecto de respuesta
cabeceras = [
('Content-type', 'text/plain; charset=utf-8'),
('WWW-Authenticate', 'Basic realm="Login"')
]
# Iniicamos respuesta indicando que se requiere autenticación previa.
responder('401 Authentication Required', cabeceras)
respuesta = "Autenticación de usuario es requerida."
return [respuesta.encode("utf-8")]
IP = "0.0.0.0"
PUERTO = 8080
APP = AutenticacionBasica(mi_app_wsgi)
print(f"Iniciando aplicación APP en servidor WSGI en { IP }: { PUERTO }")
with make_server(IP, PUERTO, APP) as servidor_wsgi:
print("Puedes finalizar con CTRL+C")
servidor_wsgi.serve_forever()
在这种情况下,我们将 类作为WSGI应用程序。他的所有 在此示例中,我们看到了如何提交 Midleware ,在我们的情况下,将迫使用户先前的身份验证,然后再启动我们的初始应用程序(不必在此进行修改)。由于代码的简单性,我们将所有内容都保存在唯一的来源中,但是, mi_app_wsgi ,而不是简单的功能,它可能是一个复杂的应用程序 flask flask p。 EJ。和身份验证-boba类可以实施令牌JWT 的精心验证。
我认为,现在是结论这篇文章的好时机。我希望我贡献了对您有用的东西。