<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DZone Snippets: decorator code</title>
    <link>http://snippets.dzone.com/posts</link>
    <pubDate>Mon, 06 Oct 2008 08:31:05 GMT</pubDate>
    <description>DZone Snippets: decorator 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>Thread Pool and Threaded Python decorators</title>
      <link>http://snippets.dzone.com/posts/show/4425</link>
      <description>&lt;code&gt;&lt;br /&gt;#!/usr/bin/env python&lt;br /&gt;# -*- coding: utf-8 -*-&lt;br /&gt;# vim:ts=4:sw=4:et&lt;br /&gt;# (c) 2007 under terms of LGPL v 2.1&lt;br /&gt;# by Vsevolod S. Balashov &lt;vsevolod@balashov.name&gt; &lt;br /&gt;&lt;br /&gt;from threading import Thread&lt;br /&gt;&lt;br /&gt;def threaded(func):&lt;br /&gt;    def proxy(*args, **kwargs):&lt;br /&gt;        thread = Thread(target=func, args=args, kwargs=kwargs)&lt;br /&gt;        thread.start()&lt;br /&gt;        return thread&lt;br /&gt;    return proxy&lt;br /&gt;&lt;br /&gt;from Queue import Queue&lt;br /&gt;&lt;br /&gt;class Pool(Queue):&lt;br /&gt;    def __init__(self, maxsize):&lt;br /&gt;        assert maxsize &gt; 0, 'maxsize &gt; 0 required for Pool class'&lt;br /&gt;        Queue.__init__(self, maxsize)&lt;br /&gt;        for i in range(maxsize):&lt;br /&gt;            thread = Thread(target = self._worker)&lt;br /&gt;            thread.setDaemon(True)&lt;br /&gt;            thread.start()&lt;br /&gt;&lt;br /&gt;    def _worker(self):&lt;br /&gt;        while True:&lt;br /&gt;            try:&lt;br /&gt;                func, args, kwargs = self.get()&lt;br /&gt;                func(*args, **kwargs)&lt;br /&gt;            except:&lt;br /&gt;                self.task_done()&lt;br /&gt;                self.join()&lt;br /&gt;                raise&lt;br /&gt;            self.task_done()&lt;br /&gt;&lt;br /&gt;    def addJob(self, func, *args, **kwargs):&lt;br /&gt;        self.put((func, args, kwargs))&lt;br /&gt;&lt;br /&gt;    def __enter__(self):&lt;br /&gt;        pass&lt;br /&gt;&lt;br /&gt;    def __exit__(self, exc_type, exc_value, traceback):&lt;br /&gt;        self.join()&lt;br /&gt;&lt;br /&gt;def threadpool(pool):&lt;br /&gt;    assert pool.__class__ == Pool, 'threadpool decorator require a Pool object'&lt;br /&gt;    def decorator(func):&lt;br /&gt;        def proxy(*args, **kwargs):&lt;br /&gt;            pool.put((func, args, kwargs))&lt;br /&gt;            return pool&lt;br /&gt;        return proxy&lt;br /&gt;    return decorator&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;example usage&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;from threadpool import *&lt;br /&gt;&lt;br /&gt;from time import sleep&lt;br /&gt;from random import random&lt;br /&gt;&lt;br /&gt;pool = Pool(3)&lt;br /&gt;    &lt;br /&gt;@threadpool(pool)&lt;br /&gt;def test_threadpool(i):&lt;br /&gt;    print 'threadpool %i enter' % i&lt;br /&gt;    sleep(random())&lt;br /&gt;    print 'threadpool %i exit' % i&lt;br /&gt;&lt;br /&gt;print 'threadpool example'&lt;br /&gt;for i in range(6):&lt;br /&gt;    test_threadpool(i)&lt;br /&gt;pool.join()&lt;br /&gt;print 'done'&lt;br /&gt;print ''&lt;br /&gt;&lt;br /&gt;@threaded&lt;br /&gt;def test_threaded(i):&lt;br /&gt;    print 'threaded %i enter' % i&lt;br /&gt;    sleep(random())&lt;br /&gt;    print 'threaded %i exit' % i&lt;br /&gt;&lt;br /&gt;print 'threaded example'&lt;br /&gt;for i in range(5):&lt;br /&gt;    test_threaded(i)&lt;br /&gt;print 'done'&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;result output&lt;br /&gt;&lt;br /&gt;threadpool example&lt;br /&gt;threadpool 0 enter&lt;br /&gt;threadpool 1 enter&lt;br /&gt;threadpool 2 enter&lt;br /&gt;threadpool 0 exit&lt;br /&gt;threadpool 3 enter&lt;br /&gt;threadpool 1 exit&lt;br /&gt;threadpool 4 enter&lt;br /&gt;threadpool 2 exit&lt;br /&gt;threadpool 5 enter&lt;br /&gt;threadpool 3 exit&lt;br /&gt;threadpool 5 exit&lt;br /&gt;threadpool 4 exit&lt;br /&gt;done&lt;br /&gt;&lt;br /&gt;threaded example&lt;br /&gt;done&lt;br /&gt;threaded 0 enter&lt;br /&gt;threaded 1 enter&lt;br /&gt;threaded 2 enter&lt;br /&gt;threaded 3 enter&lt;br /&gt;threaded 4 enter&lt;br /&gt;threaded 1 exit&lt;br /&gt;threaded 2 exit&lt;br /&gt;threaded 3 exit&lt;br /&gt;threaded 0 exit&lt;br /&gt;threaded 4 exit</description>
      <pubDate>Thu, 16 Aug 2007 12:55:37 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/4425</guid>
      <author>sevkin (Vsevolod Balashov)</author>
    </item>
    <item>
      <title>Python profile decorator</title>
      <link>http://snippets.dzone.com/posts/show/3346</link>
      <description>Python profile decorator. More info on this blog post: &lt;a href="http://www.biais.org/blog/index.php/2007/01/20/18-python-profiling-decorator"&gt;http://www.biais.org/blog/index.php/2007/01/20/18-python-profiling-decorator&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;# Maxime Biais &lt;http://www.biais.org/blog&gt;&lt;br /&gt;&lt;br /&gt;import hotshot, hotshot.stats&lt;br /&gt; &lt;br /&gt;def profileit(printlines=1):&lt;br /&gt;    def _my(func):&lt;br /&gt;        def _func(*args, **kargs):&lt;br /&gt;            prof = hotshot.Profile("profiling.data")&lt;br /&gt;            res = prof.runcall(func, *args, **kargs)&lt;br /&gt;            prof.close()&lt;br /&gt;            stats = hotshot.stats.load("profiling.data")&lt;br /&gt;            stats.strip_dirs()&lt;br /&gt;            stats.sort_stats('time', 'calls')&lt;br /&gt;            print "&gt;&gt;&gt;---- Begin profiling print"&lt;br /&gt;            stats.print_stats(printlines)&lt;br /&gt;            print "&gt;&gt;&gt;---- End profiling print"&lt;br /&gt;            return res&lt;br /&gt;        return _func&lt;br /&gt;    return _my&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Usage:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;@profileit(20)&lt;br /&gt;def mop():&lt;br /&gt;    a = 0&lt;br /&gt;    for i in range(100):&lt;br /&gt;        a += mip()&lt;br /&gt;    return a&lt;br /&gt;print mop()&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Mon, 22 Jan 2007 11:03:10 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/3346</guid>
      <author>maxme (Maxime Biais)</author>
    </item>
  </channel>
</rss>
