如何使用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 ''
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的更多相关文章
- 使用 wsgiref 创建WSGI APP
wsgify装饰器将一个普通函数转变成WSGI应用程序. class webob.dec.wsgify(func=None, RequestClass=None, args=(), kwargs=No ...
- 第三百七十三节,Django+Xadmin打造上线标准的在线教育平台—创建用户app,在models.py文件生成3张表,用户表、验证码表、轮播图表
第三百七十三节,Django+Xadmin打造上线标准的在线教育平台—创建用户app,在models.py文件生成3张表,用户表.验证码表.轮播图表 创建Django项目 项目 settings.py ...
- 利用spring boot创建java app
利用spring boot创建java app 背景 在使用spring框架开发的过程中,随着功能以及业务逻辑的日益复杂,应用伴随着大量的XML配置和复杂的bean依赖关系,特别是在使用mvc的时候各 ...
- WeX5学习笔记-创建本地APP相关问题
1.在Native新建[创建本地APP]时, "服务地址”为本地IP和端口号,例如本地IP为192.168.253.1,端口号为8080,则设置为http://192.168.253.1:8 ...
- 用PhpStorm IDE创建GG App Engine PHP应用教程
在上一篇教程里我们已经介绍了如何为PhpStorm搭建软件环境,那么今天就该是正式的开始创建App了: 3.创建首个Google App Engine PHP Application 现在我们就可以开 ...
- iOS 10 创建iMessage App
原文作者 澳大利亚19岁少年--Davis Allie ----原文地址 时值中秋佳节, 送给出门在外的程序猿们 ! 骚年们, 自己写个表情包斗图可否 ! 斗-seal.svg.png 第一. 介绍 ...
- 根据iOS 10 的新特性,创建iMessage App,可用于自定义表情
第一. 介绍(原文作者 澳大利亚19岁少年--Davis Allie ----原文地址) 随着iOS10的发布,苹果对开发者开放了Messages应用程序,开发人员现在可以创建他们自己的各种类型 并且 ...
- react系列笔记1 用npx npm命令创建react app
react系列笔记1 用npx npm命令创建react app create-react-app my-app是开始构建新的 React 单页应用程序的最佳方式.它已经为你设置好了开发环境,以便您可 ...
- 第三百七十四节,Django+Xadmin打造上线标准的在线教育平台—创建课程app,在models.py文件生成4张表,课程表、课程章节表、课程视频表、课程资源表
第三百七十四节,Django+Xadmin打造上线标准的在线教育平台—创建课程app,在models.py文件生成4张表,课程表.课程章节表.课程视频表.课程资源表 创建名称为app_courses的 ...
随机推荐
- mysql学习之通过文件创建数据库以及添加数据
转自:http://blog.163.com/wujicaiguai@126/blog/static/170171558201411311547655/ 1.# 创建数据库语句 create data ...
- RHEL 6.5----rsync+inotify数据同步服务
Rsync特性: 可以镜像保存整个目录树和文件系统: 可以保持原文件的权限.时间.软硬链接等: 安装简单. 传输特点: 速度快:rsync首次同步会复制同步全部内容,以后只传输修改过的文件: 压缩传输 ...
- Suricata的初始化脚本
见官网 https://suricata.readthedocs.io/en/latest/initscripts.html
- P1482 Cantor表(升级版)
题目描述 现代数学的著名证明之一是Georg Cantor证明了有理数是可枚举的.他是用下面这一张表来证明这一命题的: 1/1 1/2 1/3 1/4 1/5 … 2/1 2/2 2/3 2/4 … ...
- java的学习方向
在我身边有很多初学者,或者想入门的门外汉问我该如何的去学习一门新的技术,如果你是一窍不通的门外汉,我给你的建议是,报一个可靠的基础培训班.当然培训班的方向也分为很多,有前端的培训课程.有java的培训 ...
- JVM线程与Linux内核线程的映射[转]
Linux从内核2.6开始使用NPTL (Native POSIX Thread Library)支持,但这时线程本质上还轻量级进程. Java里的线程是由JVM来管理的,它如何对应到操作系统的线程是 ...
- CF962D Merge Equals
思路: 不必每次都找最小的值进行合并,从前往后扫一遍的过程中能合并就一直合并. 实现: #include <bits/stdc++.h> using namespace std; type ...
- JavaScript创建对象的七种方法
一. 工厂模式 创建: function createPerson(name,behavior){ var p=new Object(); p.name=name; p.behavior=behavi ...
- Java 利用FTP上传,下载文件,遍历文件目录
Java实现FTP上传下载文件的工具包有很多,这里我采用Java自带的API,实现FTP上传下载文件.另外JDK1.7以前的版本与其之后版本的API有了较大的改变了. 例如: JDK1.7之前 JDK ...
- git项目常用命令
git rm --cached 文件名 //移除不上传 git add . //添加所有文件 .gitignore //git忽略不想上传或者不需要上传的文件 REAMDE.md 文 ...