注意 :html
一、定义__call__的意义git
class App():
def __init__(self):
pass
def method(self):
pass
app=App()
app() #错误,由于app,即对象的实例,没有括号运算符 github
class App2():
def __init__(self):
pass
def method(self):
pass
def __call__(self):
print 'call'
app2=App2()
app2() #print call 回去调用__call__里面的内容redis
二、WSGI的Request和Response讲解:app
三、自定义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 appui
完成基本框架url
四、 继续完善spa
在__init__ 里面 渲染模板并链接到redis .net
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页面下载