注意 :

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 ''
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页面下载

如何使用werkzeug创建WSGI APP的更多相关文章

  1. 使用 wsgiref 创建WSGI APP

    wsgify装饰器将一个普通函数转变成WSGI应用程序. class webob.dec.wsgify(func=None, RequestClass=None, args=(), kwargs=No ...

  2. 第三百七十三节,Django+Xadmin打造上线标准的在线教育平台—创建用户app,在models.py文件生成3张表,用户表、验证码表、轮播图表

    第三百七十三节,Django+Xadmin打造上线标准的在线教育平台—创建用户app,在models.py文件生成3张表,用户表.验证码表.轮播图表 创建Django项目 项目 settings.py ...

  3. 利用spring boot创建java app

    利用spring boot创建java app 背景 在使用spring框架开发的过程中,随着功能以及业务逻辑的日益复杂,应用伴随着大量的XML配置和复杂的bean依赖关系,特别是在使用mvc的时候各 ...

  4. WeX5学习笔记-创建本地APP相关问题

    1.在Native新建[创建本地APP]时, "服务地址”为本地IP和端口号,例如本地IP为192.168.253.1,端口号为8080,则设置为http://192.168.253.1:8 ...

  5. 用PhpStorm IDE创建GG App Engine PHP应用教程

    在上一篇教程里我们已经介绍了如何为PhpStorm搭建软件环境,那么今天就该是正式的开始创建App了: 3.创建首个Google App Engine PHP Application 现在我们就可以开 ...

  6. iOS 10 创建iMessage App

    原文作者 澳大利亚19岁少年--Davis Allie ----原文地址 时值中秋佳节, 送给出门在外的程序猿们 ! 骚年们, 自己写个表情包斗图可否 ! 斗-seal.svg.png 第一. 介绍 ...

  7. 根据iOS 10 的新特性,创建iMessage App,可用于自定义表情

    第一. 介绍(原文作者 澳大利亚19岁少年--Davis Allie ----原文地址) 随着iOS10的发布,苹果对开发者开放了Messages应用程序,开发人员现在可以创建他们自己的各种类型 并且 ...

  8. react系列笔记1 用npx npm命令创建react app

    react系列笔记1 用npx npm命令创建react app create-react-app my-app是开始构建新的 React 单页应用程序的最佳方式.它已经为你设置好了开发环境,以便您可 ...

  9. 第三百七十四节,Django+Xadmin打造上线标准的在线教育平台—创建课程app,在models.py文件生成4张表,课程表、课程章节表、课程视频表、课程资源表

    第三百七十四节,Django+Xadmin打造上线标准的在线教育平台—创建课程app,在models.py文件生成4张表,课程表.课程章节表.课程视频表.课程资源表 创建名称为app_courses的 ...

随机推荐

  1. LookupError: unknown encoding: idna 的处理方法

    写了一个脚本,想把它打包成exe文件,在python编译器中运行正常,但是打包成.exe文件运行报错 LookupError: unknown encoding: idna 找遍资料终于找到了解决方法 ...

  2. 为localhost添加https

    1.按照https://stackoverflow.com/a/7184031/4619958来做 其中,CommonName填写localhost 2.在ssl.conf里头加上 <Direc ...

  3. Ionic开发-如何在ion-content形成上下结构 上面固定下层可滚动

    在一个系统设计中,一般有些需要固定位置,便利操作.现在我要做一个上下两层,需要固定上方,下方拉刷新数据. 页面: <ion-content scroll="false"> ...

  4. P2676 超级书架

    题目描述 Farmer John最近为奶牛们的图书馆添置了一个巨大的书架,尽管它是如此的大,但它还是几乎瞬间就被各种各样的书塞满了.现在,只有书架的顶上还留有一点空间. 所有N(1 <= N & ...

  5. Asp.net 字符(三)

    using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using ...

  6. markdown快捷键(转)

    markdown快捷键 GLYPH NAME COMMAND Command, Cmd, Clover, (formerly) Apple ALT Option, Opt, (Windows) Alt ...

  7. 【经验总结】关于使用某些第三方插件库元素设置display:none后重新show不显示的问题;(display、opacity、宽高0的使用场景)

    display:none 直接取消元素所占用的位置(但是元素还是存在的),后面元素看他就相当于不存在了: opacity:0  隐藏,但是其依旧占用位置: height.width:0 和displa ...

  8. Kotlin学习的一些心得

    1.工程manifest中的application节点有冲突时,添加 xmlns:tools="http://schemas.android.com/tools" tools:re ...

  9. apache配置多域名

    环境:mac,其他环境也可做参考 hosts配置 eg:sudo vim /etc/hosts 127.0.0.1 www.testphalcon.com apache配置 找到apache对应安装目 ...

  10. centos启用socks5服务

    直接在终端用 root 安装 *** 官方客户端 apt-get install python-pip -ypip install shadowsocks 然后编辑 /etc/shadowsocks. ...