fíam

(rhymes with liam)

  • Time to release: django-digest and django-oauthsp

    July 28, 2008 at 15:14:24 CEST

    Let me be clear on this: altough I'm already using this code in byNotes, I still consider it in alpha stage, so think twice before incorporating it into your project.

    django-digest is an app for helping with digest authentication. It implements the basic models needed for storing the data, while authentication is handle by wapi middleware.

    On the other hand, django-oauthsp implements the service provider side of OAuth with all the bells and whistles. Currently, it supports the full OAuth spec, custom token attributes, token renewal as specified by ScalableOAuth and problem reporting as specified by ProblemReporting. It also includes some views for requesting, authorizing, reviewing and revoking user tokens as well as registering, editing and listing consumers.

    If you try this apps, you know, leave some feedback in the comments ;).

  • First wapi release

    July 14, 2008 at 16:22:25 CEST

    Wapi is somewhat 80% finished, so I think it's ready for the first release. The zipfile includes the wapi code as well as some examples taken from byNotes.

    You'll notice there are authentication methods for Basic, Digest and OAuth. However, only the former is usable for now, since the other two depend on Django applications which are't ready for release (but are likely to be ready before this week ends).

    If you try this, leave some feedback in a comment ;). I advise you to not use this code into production yet, since the API may change in the near future.

  • Wapi release coming next week

    July 11, 2008 at 18:50:44 CEST

    Wapi, the django application for publishing web apis, will be ready next week. These are the features implemented for now:

    • Exposing ResT apis with transparent serialization (i.e. your code just returns a serialization preset, wapi formats it for you).
    • API-as-class approach: Every function defined inside a class translates to an API method. Then, the class is plugged inside an exposer and it takes care of receiving the parameters and passing them to your function.
    • Authentication middleware: The exposers take an optional parameter which let's your API authenticate users. Currently, there are authentication methods for HTTP Basic (against django.contrib.user database or custom auth function), HTTP Digest (custom auth with helpers for preparing a django.contrib.user database for digest auth) and OAuth (with extensions for token duration and token attributes, all customizable).
    • The newserializers API is included inside wapi as wapi.serializers.
    • Decorators for marking functions as login-required, read-only, write-only...

    And these are the features planned for the future:

    • SOAP exposer
    • Automatic WDSL generation

    What do you think about it? Do you miss something which could be useful for exposing Web APIs?

  • byNotes slashdotted

    July 2, 2008 at 11:50:17 CEST

    Wow, I've just noticed byNotes got slashdotted yesterday! The nice thing is the byNotes server managed to survive the traffic spike, even with MySQL and PostgreSQL both running in the same machine as the web server. And without any caching enabled!! Definitely, Django sites handle slashdottings very well.

  • Plugging a RSS feed into a Django template

    July 1, 2008 at 19:16:58 CEST

    As some of you may have noticed, I've added my latest notes at byNotes in the sidebar. I wanted to do it in the template side, because I like to keep my views as clean as possible, so I wrote a template tag for fetching a RSS feed and displaying it. Here is the code:

    from datetime import datetime
    import time
    
    from django.core.cache import cache
    from django import template
    
    import feedparser
    
    register = template.Library()
    
    @register.filter
    def todatetime(value):
        return datetime(*time.localtime(time.mktime(value))[:6])
    
    @register.tag
    def rssplug(parser, token):
        try:
            tag_name, address, template = token.split_contents()
        except ValueError:
            raise template.TemplateSyntaxError('%s tag requires 2 arguments' % token.split_contents()[0])
    
        return RssPlugNode(address, template)
    
    def resolve(var_or_value, ctx):
        if var_or_value[0] == '"':
            return var_or_value[1:-1]
    
        return ctx.resolve_variable(var_or_value)
    
    class RssPlugNode(template.Node):
        def __init__(self, address, templ):
            self.address = address
            self.templ = templ
    
        def rss(self, addr):
            ckey = 'rssplug_%s' % addr
            data = cache.get(ckey)
            if data:
                return data
            data = feedparser.parse(addr)
            cache.set(ckey, data)
            return data
    
        def render(self, context):
            address = resolve(self.address, context)
            tmpl = resolve(self.templ, context)
            t = template.loader.get_template(tmpl)
            return ''.join([t.render(template.Context({ 'item': item })) for item in self.rss(address).entries])
    

    As you can see, this tag uses a template for rendering every feed item, making it very flexible. You can output any information you want, as long as feedparser supports it. Let's see how a item template looks like:

    {% load i18n %}
    {% load rssplug %}
    <a href="{{ item.link }}">{{ item.description|safe|truncatewords_html:10 }}</a>
    <p class="date">{% blocktrans with item.date_parsed|todatetime|timesince as when %}{{ when }} ago{% endblocktrans %}</p>
    

    Notice I'm using a filter in rssplug called todatetime, since feedparser returns a time.struct_time and timesince expects a datetime.datetime. Now let's see an example from the template including the rss feed:

    <div class="navbox" id="rssplug">
        <h3>{% trans "Latest notes" %}</h3>
        <div class="navbox-body">
            {% load rssplug %}
            {% rssplug "http://bynotes.com/_feeds/public/fiam/?limit=5" "note.html" %}
        </div>
    </div>
    

    The code for rssplug.py is available in Blango's public git repository, but I've also made it avaible here.