<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DZone Snippets: wsgi code</title>
    <link>http://snippets.dzone.com/posts</link>
    <pubDate>Sun, 27 Jul 2008 03:40:12 GMT</pubDate>
    <description>DZone Snippets: wsgi code</description>
    <item>
      <title>Pattern Matching based WSGI-enabled URL routing tool.</title>
      <link>http://snippets.dzone.com/posts/show/5620</link>
      <description>Actual version on http://pypi.python.org/pypi/decoroute&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;easy_install decoroute&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Example:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;import decoroute&lt;br /&gt;    &lt;br /&gt;app = decoroute.App()&lt;br /&gt;    &lt;br /&gt;def render_response(status = '200 OK', **kw):&lt;br /&gt;    # try your favorite templating engine here&lt;br /&gt;    return status, [('Content-Type', 'text/plain')], [str(kw)]&lt;br /&gt;&lt;br /&gt;def redirect_to(env, endpoint, **kw):&lt;br /&gt;    return '302 FOUND', [('Content-Type', 'text/plain'), \&lt;br /&gt;    ('Location', '%s://%s%s' % (env['wsgi.url_scheme'], env['HTTP_HOST'], \&lt;br /&gt;    env['decoroute.app'].url_for(endpoint, **kw)))], ['']&lt;br /&gt;    &lt;br /&gt;@app.expose('/node', id = '1')&lt;br /&gt;@app.expose('/node/&lt;id:\d+&gt;')&lt;br /&gt;def node(env, id):&lt;br /&gt;    return render_response(id = id)&lt;br /&gt;    &lt;br /&gt;@app.expose('/url_for')&lt;br /&gt;def url_for(env):&lt;br /&gt;    return render_response( \&lt;br /&gt;        url = env['decoroute.app'].url_for(node, id = 666))&lt;br /&gt;    &lt;br /&gt;@app.expose('/302')&lt;br /&gt;def found(env):&lt;br /&gt;    return redirect_to(env, not_found)&lt;br /&gt;    &lt;br /&gt;@app.expose('/404')&lt;br /&gt;def not_found(env):&lt;br /&gt;    raise decoroute.NotFound()&lt;br /&gt;    &lt;br /&gt;@app.not_found()&lt;br /&gt;def not_found_handler(env):&lt;br /&gt;    return render_response('404 NF', url = env['PATH_INFO'])&lt;br /&gt;    &lt;br /&gt;from wsgiref.simple_server import make_server&lt;br /&gt;    &lt;br /&gt;make_server('', 5555, app).serve_forever()&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Complete source &lt; 100 lines of code:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;#!/usr/bin/env python&lt;br /&gt;# vim:ts=4:sw=4:et&lt;br /&gt;# -*- coding: utf-8 -*-&lt;br /&gt;# $Id: decoroute.py,v 6eb37aeee5cd 2008/06/09 07:38:26 vsevolod $&lt;br /&gt;#&lt;br /&gt;# Pattern Matching based WSGI-enabled URL routing tool.&lt;br /&gt;# Actual version on http://pypi.python.org/pypi/decoroute&lt;br /&gt;# (C) 2008 by Vsevolod S. Balashov &lt;vsevolod@balashov.name&gt;&lt;br /&gt;# under terms of GNU LGPL v2.1 http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt&lt;br /&gt;&lt;br /&gt;__author__ = "Vsevolod Balashov"&lt;br /&gt;__email__ = "vsevolod at balashov dot name"&lt;br /&gt;&lt;br /&gt;import re&lt;br /&gt;from sets import ImmutableSet&lt;br /&gt;import wsgistraw&lt;br /&gt;&lt;br /&gt;__all__ = ['NotFound', 'App']&lt;br /&gt;&lt;br /&gt;class NotFound(Exception):&lt;br /&gt;    pass&lt;br /&gt;&lt;br /&gt;_pattern_re = re.compile(r'''&lt;br /&gt;    ([^&lt;]+)                     # static rule data&lt;br /&gt;    (?:&lt;&lt;br /&gt;        ([a-zA-Z][a-zA-Z0-9_]*) # variable name&lt;br /&gt;        \:&lt;br /&gt;        ([^&gt;]+)                 # regexp constraint&lt;br /&gt;    &gt;)?&lt;br /&gt;''', re.VERBOSE)&lt;br /&gt;&lt;br /&gt;def pattern2regexp(pattern, f, s = lambda x: re.escape(x)):&lt;br /&gt;    def parser():&lt;br /&gt;        for t in _pattern_re.findall(pattern):&lt;br /&gt;            yield s(t[0])&lt;br /&gt;            if t[1] != '':&lt;br /&gt;                yield f(t[1], t[2])&lt;br /&gt;    return parser()&lt;br /&gt;&lt;br /&gt;make_url_for = lambda p: ''.join(pattern2regexp(p, lambda v, r: '%%(%s)s' % v, lambda s: s))&lt;br /&gt;make_variables = lambda p: filter(lambda x: x, pattern2regexp(p, lambda v, r: v, lambda s: None))&lt;br /&gt;make_pattern = lambda p: r''.join(pattern2regexp(p, lambda v, r: r'(?P&lt;%s&gt;%s)' % (v, r)))&lt;br /&gt;make_selector_fragment = lambda p: r''.join(pattern2regexp(p, lambda v, r: r'(?:%s)' % r))&lt;br /&gt;make_selector = lambda i: re.compile(r'(^%s$)' % r'$)|(^'.join(map(make_selector_fragment, i)))&lt;br /&gt;&lt;br /&gt;class UrlMap(object):&lt;br /&gt;    def __init__(self):&lt;br /&gt;        self._endpoints = {}&lt;br /&gt;        self._patterns = {}&lt;br /&gt;        self._pattern_selector = make_selector(self._patterns.iterkeys())&lt;br /&gt;    &lt;br /&gt;    def add(self, pattern, endpoint, **kw):&lt;br /&gt;        if self._patterns.has_key(pattern):&lt;br /&gt;            raise Exception('duplicate pattern', pattern)&lt;br /&gt;        self._endpoints[(endpoint, ImmutableSet(make_variables(pattern)))] = make_url_for(pattern)&lt;br /&gt;        self._patterns[pattern] = (re.compile(make_pattern(pattern)), endpoint, kw)&lt;br /&gt;        self._pattern_selector = make_selector(self._patterns.iterkeys())&lt;br /&gt;    &lt;br /&gt;    def route(self, url):&lt;br /&gt;        try:&lt;br /&gt;            p = self._patterns.values()[re.match(self._pattern_selector, url).lastindex - 1]&lt;br /&gt;            d = re.match(p[0], url).groupdict().copy()&lt;br /&gt;            d.update(p[2])&lt;br /&gt;            return p[1], d&lt;br /&gt;        except:&lt;br /&gt;            raise NotFound('route not found', url)&lt;br /&gt;    &lt;br /&gt;    def url_for(self, endpoint, **kw):&lt;br /&gt;        return self._endpoints[(endpoint, ImmutableSet(kw.keys()))] % kw&lt;br /&gt;&lt;br /&gt;class App(object):&lt;br /&gt;    def __init__(self, key = 'decoroute.app'):&lt;br /&gt;        self._key = key&lt;br /&gt;        self._map = UrlMap()&lt;br /&gt;        self._not_found = lambda e: ('404 NOT FOUND', [("Content-Type", "text/plain")], [''])&lt;br /&gt;    &lt;br /&gt;    @wsgistraw.app&lt;br /&gt;    def __call__(self, env):&lt;br /&gt;        try:&lt;br /&gt;            env[self._key] = self&lt;br /&gt;            endpoint, kw = self._map.route(env['PATH_INFO'])&lt;br /&gt;            return endpoint(env, **kw)&lt;br /&gt;        except NotFound:&lt;br /&gt;            return self._not_found(env)&lt;br /&gt;    &lt;br /&gt;    def expose(self, pattern, **kw):&lt;br /&gt;        def decorate(f):&lt;br /&gt;            self._map.add(pattern, f, **kw)&lt;br /&gt;            return f&lt;br /&gt;        return decorate&lt;br /&gt;    &lt;br /&gt;    def not_found(self):&lt;br /&gt;        def decorate(f):&lt;br /&gt;            self._not_found = f&lt;br /&gt;            return f&lt;br /&gt;        return decorate&lt;br /&gt;    &lt;br /&gt;    def url_for(self, endpoint, **kw):&lt;br /&gt;        return self._map.url_for(endpoint, **kw)&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Mon, 09 Jun 2008 07:10:57 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/5620</guid>
      <author>sevkin (Vsevolod Balashov)</author>
    </item>
    <item>
      <title>Storm ORM by Canonical in WSGI enabled applications</title>
      <link>http://snippets.dzone.com/posts/show/4408</link>
      <description>&lt;code&gt;&lt;br /&gt;#!/usr/bin/env python&lt;br /&gt;# vim:ts=4:sw=4:et&lt;br /&gt;# (c) 2007 Vsevolod Balashov &lt;vsevolod@balashov.name&gt; under terms of LGPL 2.1&lt;br /&gt;# use Storm ORM &lt;https://storm.canonical.com&gt; in WSGI enabled applications&lt;br /&gt;#&lt;br /&gt;# actual version on http://pypi.python.org/pypi/middlestorm&lt;br /&gt;&lt;br /&gt;"""WSGI middleware for Storm.&lt;br /&gt;&lt;br /&gt;This is the database access inteface for WSGI enabled (PEP 333) web applications.&lt;br /&gt;&lt;br /&gt;Pylons framework example:&lt;br /&gt;&lt;br /&gt;in wsgiapp.py&lt;br /&gt;&lt;br /&gt;from storm.database import create_database&lt;br /&gt;from middlestorm import MiddleStorm&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;# CUSTOM MIDDLEWARE HERE&lt;br /&gt;app = MiddleStorm(app, create_database(config['app_conf']['sqlalchemy.default.uri']))&lt;br /&gt;&lt;br /&gt;in controller:&lt;br /&gt;&lt;br /&gt;class DemoController(BaseController):&lt;br /&gt;    def index(self):&lt;br /&gt;        store = request.environ['storm.store']&lt;br /&gt;        ...&lt;br /&gt;"""&lt;br /&gt;&lt;br /&gt;from storm.database import Database&lt;br /&gt;from storm.store import Store&lt;br /&gt;from threading import local&lt;br /&gt;&lt;br /&gt;__all__ = ["MiddleStorm"]&lt;br /&gt;__author__ = "Vsevolod Balashov &lt;http://vsevolod.balashov.name&gt;"&lt;br /&gt;__version__ = "0.1"&lt;br /&gt;&lt;br /&gt;class SingleConn(Database):&lt;br /&gt;    """Database proxy class.&lt;br /&gt;    Share single database connection between all Store object instances in threads.&lt;br /&gt;    If you have readonly database or not use transactions why not?&lt;br /&gt;    """&lt;br /&gt;    def __init__(self, database):&lt;br /&gt;        self._database = database&lt;br /&gt;        self._connection = database.connect()&lt;br /&gt;    def connect(self):&lt;br /&gt;        return self._connection&lt;br /&gt;&lt;br /&gt;class MiddleStorm(object):&lt;br /&gt;    """WSGI middleware.&lt;br /&gt;    Add Store object instance in environ['storm.store']. Each thread contains own instance.&lt;br /&gt;    """&lt;br /&gt;&lt;br /&gt;    def __init__(self, app, database, single = False):&lt;br /&gt;        """Create WSGI middleware.&lt;br /&gt;        @param app: up level application or middleware.&lt;br /&gt;        @param database: instance of Database returned create_database.&lt;br /&gt;        @param: single: use single database connection in all threads. &lt;br /&gt;        """&lt;br /&gt;        assert isinstance(database, Database), \&lt;br /&gt;            'database must be subclass of storm.database.Database'&lt;br /&gt;        if single:&lt;br /&gt;            self._database = SingleConn(database)&lt;br /&gt;        else:&lt;br /&gt;            self._database = database&lt;br /&gt;        self._app = app&lt;br /&gt;        self._local = local()&lt;br /&gt;&lt;br /&gt;    def __call__(self, environ, start_response):&lt;br /&gt;        try:&lt;br /&gt;            environ['storm.store']  = self._local.store&lt;br /&gt;        except AttributeError:&lt;br /&gt;            environ['storm.store']  = \&lt;br /&gt;                self._local.__dict__.setdefault('store', Store(self._database))&lt;br /&gt;        return self._app(environ, start_response)&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Fri, 10 Aug 2007 11:39:51 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/4408</guid>
      <author>sevkin (Vsevolod Balashov)</author>
    </item>
  </channel>
</rss>
