如何使用werkzeug创建WSGI APP

摘要:
每个规则包含一个用来尝试针对一个endpoint匹配URL的模式模板。endpoint通常是一个字符串,可以用来唯一识别这个URL##另一个带有同样的规则,只是在短链接之后增加了一个加号(+),将其连接到短链接的细节信息。

注意 :

1、定义__call__的意义

class App():
def __init__(self):
pass
def method(self):
pass
app=App()
app() #错误,因为app,即对象的实例,没有括号运算符

class App2():
def __init__(self):
pass
def method(self):
pass
def __call__(self):
print 'call'
app2=App2()
app2() #print call 回去调用__call__里面的内容

2、WSGI的Request和Response讲解:

3、自定义wsgi 程序

class Shortly(object):
def __init__(self, config):
self.redis = redis.Redis(config[‘redis_host’], config[‘redis_port’])
def dispatch_request(self, request):
return Response(‘Hello World!’)
def wsgi_app(self, environ, start_response):
request = Request(environ)
response = self.dispatch_request(request)
return response(environ, start_response)
def __call__(self, environ, start_response):
return self.wsgi_app(environ, start_response)
def create_app(redis_host=‘localhost’, redis_port=6379, with_static=True):
app = Shortly({
‘redis_host’: redis_host,
‘redis_port’: redis_port
})
if with_static:
app.wsgi_app = SharedDataMiddleware(app.wsgi_app, {
‘/static’: os.path.join(os.path.dirname(__file__), ‘static’)
})
return app

完成基本框架

4、 继续完善

在__init__ 里面 渲染模板并连接到redis

def __init__(self, config):
self.redis = redis.Redis(config[‘redis_host’], config[‘redis_port’])
template_path = os.path.join(os.path.dirname(__file__), ‘templates’)
self.jinja_env = Environment(loader=FileSystemLoader(template_path),
autoescape=True)

##创建一个Map实例,并增加一些Rule对象。每个规则包含一个用来尝试针对一个endpoint匹配URL的模式模板。endpoint通常是一个字符串,可以用来唯一识别这个URL

##另一个带有同样的规则,只是在短链接之后增加了一个加号(+),将其连接到短链接的细节信息。

self.url_map = Map([
Rule(‘/’, endpoint=‘new_url’),
Rule(‘/<short_id>’, endpoint=‘follow_short_link’),
Rule(‘/<short_id>+’, endpoint=’short_link_details’)
])

def render_template(self, template_name, **context):
t = self.jinja_env.get_template(template_name)
return Response(t.render(context), mimetype=’text/html’)

## 添加视图 view

defon_new_url(self, request): 
error =None 
url =‘’ 
if request.method =‘POST’: 
url =request.form[‘url’] 
if notis_valid_url(url): 
error =‘Please enter a valid URL’ 
else: 
short_id =self.insert_url(url) 
return redirect(‘/%s+’ %short_id) 
return self.render_template(‘new_url.html’, error=error, url=url)

完整代码下载:

#-*- coding: utf-8 -*-
"""shortly
    ~~~~~~~
    A simple URL shortener using Werkzeug and redis.
    :copyright: (c) 2014 by the Werkzeug Team, see AUTHORS for more details.
    :license: BSD, see LICENSE for more details.
"""
importos
importredis
importurlparse
from werkzeug.wrappers importRequest, Response
from werkzeug.routing importMap, Rule
from werkzeug.exceptions importHTTPException, NotFound
from werkzeug.wsgi importSharedDataMiddleware
from werkzeug.utils importredirect

from jinja2 importEnvironment, FileSystemLoader


defbase36_encode(number):
    assert number >= 0, 'positive integer required'
    if number ==0:
        return '0'base36 =[]
    while number !=0:
        number, i = divmod(number, 36)
        base36.append('0123456789abcdefghijklmnopqrstuvwxyz'[i])
    return ''.join(reversed(base36))


defis_valid_url(url):
    parts =urlparse.urlparse(url)
    return parts.scheme in ('http', 'https')


defget_hostname(url):
    returnurlparse.urlparse(url).netloc


classShortly(object):

    def __init__(self, config):
        self.redis = redis.Redis(config['redis_host'], config['redis_port'])
        template_path = os.path.join(os.path.dirname(__file__), 'templates')
        self.jinja_env = Environment(loader=FileSystemLoader(template_path),
                                     autoescape=True)
        self.jinja_env.filters['hostname'] =get_hostname

        self.url_map =Map([
            Rule('/', endpoint='new_url'),
            Rule('/<short_id>', endpoint='follow_short_link'),
            Rule('/<short_id>+', endpoint='short_link_details')
        ])

    defon_new_url(self, request):
        error =None
        url = ''
        if request.method == 'POST':
            url = request.form['url']
            if notis_valid_url(url):
                error = 'Please enter a valid URL'
            else:
                short_id =self.insert_url(url)
                return redirect('/%s+' %short_id)
        return self.render_template('new_url.html', error=error, url=url)

    defon_follow_short_link(self, request, short_id):
        link_target = self.redis.get('url-target:' +short_id)
        if link_target isNone:
            raiseNotFound()
        self.redis.incr('click-count:' +short_id)
        returnredirect(link_target)

    defon_short_link_details(self, request, short_id):
        link_target = self.redis.get('url-target:' +short_id)
        if link_target isNone:
            raiseNotFound()
        click_count = int(self.redis.get('click-count:' + short_id) or0)
        return self.render_template('short_link_details.html',
            link_target=link_target,
            short_id=short_id,
            click_count=click_count
        )

    deferror_404(self):
        response = self.render_template('404.html')
        response.status_code = 404
        returnresponse

    definsert_url(self, url):
        short_id = self.redis.get('reverse-url:' +url)
        if short_id is notNone:
            returnshort_id
        url_num = self.redis.incr('last-url-id')
        short_id =base36_encode(url_num)
        self.redis.set('url-target:' +short_id, url)
        self.redis.set('reverse-url:' +url, short_id)
        returnshort_id

    def render_template(self, template_name, **context):
        t =self.jinja_env.get_template(template_name)
        return Response(t.render(context), mimetype='text/html')

    defdispatch_request(self, request):
        adapter =self.url_map.bind_to_environ(request.environ)
        try:
            endpoint, values =adapter.match()
            return getattr(self, 'on_' + endpoint)(request, **values)
        exceptNotFound, e:
            returnself.error_404()
        exceptHTTPException, e:
            returne

    defwsgi_app(self, environ, start_response):
        request =Request(environ)
        response =self.dispatch_request(request)
        returnresponse(environ, start_response)

    def __call__(self, environ, start_response):
        returnself.wsgi_app(environ, start_response)


def create_app(redis_host='localhost', redis_port=6379, with_static=True):
    app =Shortly({
        'redis_host':       redis_host,
        'redis_port':       redis_port
    })
    ifwith_static:
        app.wsgi_app =SharedDataMiddleware(app.wsgi_app, {
            '/static':  os.path.join(os.path.dirname(__file__), 'static')
        })
    returnapp


if __name__ == '__main__':
    from werkzeug.serving importrun_simple
    app =create_app()
    run_simple('127.0.0.1', 5000, app, use_debugger=True, use_reloader=True)

https://github.com/pallets/werkzeug/tree/master/examples/shortly 含html页面下载

免责声明:文章转载自《如何使用werkzeug创建WSGI APP》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇科学知识图谱绘制方法、步骤及工具mysql_【MySQL】常见的mysql 进程state下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

12.1 flask基础之简单实用

一、Flask介绍(轻量级的框架,非常快速的就能把程序搭建起来) Flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架,对于Werkzeug本质是Socket服务端,其用于接收http请求并对请求进行预处理,然后触发Flask框架,开发人员基于Flask框架提供的功能对请求进行相应的处理,并返回给用户,...

Python+Apache环境搭建

Python+Apache环境搭建 Python+apache搭建时需要apache拓展mod_wsgi模块,apache启动时自动加载mod_wsgi模块,通过mod_wsgi与python通信,实现python部署在apache上。 安装 1.下载源码包mod_wsgi 2.解压缩mod_wsgi包 tar zxvf mod_wsgi-4.6.8.t...

OpenStack 中的neutron-server启动过程

neutron-server是neutron的核心组件之中的一个。负责直接接收外部请求,然后调用后端对应plugin进行处理。 其核心启动过程代码主要在neutron.server包中。 __init__.py文件里包含一个main()函数,是WSGIserver開始的模块,而且通过调用serve_wsgi来创建一个NeutronApiService的...

Django用Apache和mod_wsgi部署

背景 最近写了一个Django在windows上运行,但是用的vbs命令,导致在后台运行的时候,必须用户登录才可以运行,还有就是登录之后,有其他进程可能被干掉。 Set ws = CreateObject("Wscript.Shell") ws.run "cmd /c D:\xxd\run.bat",vbhide ` bat 内容 C:\Python3...

gunicorn的作用

gunicorn是什么: gunicorn是一种unix上被广泛使用的Python WSGI UNIX HTTP Server WSGI是什么: 先说下 WSGI 的表面意思,Web Server Gateway Interface 的缩写,即 Web 服务器网关接口。 WSGI是一种规范,定义了 Web服务器 如何与 Python应用程序 进行交互 如何...

windows+django3.1+ASGI+nginx部署

# 了解CGI CGI(通用网关接口, Common Gateway Interface/CGI),定义客户端与Web服务器的交流方式的一个程序。 #  什么是WSGI PythonWeb服务器网关接口(Python Web Server Gateway Interface,缩写为WSGI)是Python应用程序或框架和Web服务器之间的一种接口,已经被广...