zoukankan      html  css  js  c++  java
  • 如何使用werkzeug创建WSGI APP

    注意 :

    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

    def on_new_url(self, request): 
    error = None 
    url = ‘’ 
    if request.method = ‘POST’: 
    url = request.form[‘url’] 
    if not is_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.
    """
    import os
    import redis
    import urlparse
    from werkzeug.wrappers import Request, Response
    from werkzeug.routing import Map, Rule
    from werkzeug.exceptions import HTTPException, NotFound
    from werkzeug.wsgi import SharedDataMiddleware
    from werkzeug.utils import redirect
    
    from jinja2 import Environment, FileSystemLoader
    
    
    def base36_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))
    
    
    def is_valid_url(url):
        parts = urlparse.urlparse(url)
        return parts.scheme in ('http', 'https')
    
    
    def get_hostname(url):
        return urlparse.urlparse(url).netloc
    
    
    class Shortly(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')
            ])
    
        def on_new_url(self, request):
            error = None
            url = ''
            if request.method == 'POST':
                url = request.form['url']
                if not is_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)
    
        def on_follow_short_link(self, request, short_id):
            link_target = self.redis.get('url-target:' + short_id)
            if link_target is None:
                raise NotFound()
            self.redis.incr('click-count:' + short_id)
            return redirect(link_target)
    
        def on_short_link_details(self, request, short_id):
            link_target = self.redis.get('url-target:' + short_id)
            if link_target is None:
                raise NotFound()
            click_count = int(self.redis.get('click-count:' + short_id) or 0)
            return self.render_template('short_link_details.html',
                link_target=link_target,
                short_id=short_id,
                click_count=click_count
            )
    
        def error_404(self):
            response = self.render_template('404.html')
            response.status_code = 404
            return response
    
        def insert_url(self, url):
            short_id = self.redis.get('reverse-url:' + url)
            if short_id is not None:
                return short_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)
            return short_id
    
        def render_template(self, template_name, **context):
            t = self.jinja_env.get_template(template_name)
            return Response(t.render(context), mimetype='text/html')
    
        def dispatch_request(self, request):
            adapter = self.url_map.bind_to_environ(request.environ)
            try:
                endpoint, values = adapter.match()
                return getattr(self, 'on_' + endpoint)(request, **values)
            except NotFound, e:
                return self.error_404()
            except HTTPException, e:
                return e
    
        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
    
    
    if __name__ == '__main__':
        from werkzeug.serving import run_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页面下载

  • 相关阅读:
    Django REST framework解析器、渲染器、分页
    微前端qiankun从搭建到部署的实践
    前端开发常用免费资源,显著提升工作效率
    Vue切换页面时碰见过中断axios请求的场景吗?如何中断?
    JavaScript与ES的25个重要知识点!
    电脑端支付宝支付 -前端获取支付宝返回的form 以及submit 调用支付扫码页面
    element ui 分页记忆checked
    通过css改变svg img的颜色
    Howler.js Web音频播放终极解决方案
    5、Redis中对Set类型的操作命令
  • 原文地址:https://www.cnblogs.com/bayueman/p/6609912.html
Copyright © 2011-2022 走看看