Vous êtes sur la page 1sur 70

Domain Specific

Frameworks
Why they rock and what can we do to get more of them

Wednesday, September 8, 2010


Who is this guy?

Wednesday, September 8, 2010


! " # $ % &
$ ' (

Wednesday, September 8, 2010


Wednesday, September 8, 2010
Wednesday, September 8, 2010
Domain Specific
Frameworks?

Wednesday, September 8, 2010


http://www.flickr.com/photos/jakerome/
Wednesday, September 8, 2010
http://www.flickr.com/photos/jakerome/
Wednesday, September 8, 2010
http://www.flickr.com/photos/ladydragonflyherworld/
Wednesday, September 8, 2010
http://www.flickr.com/photos/thomasthomas/
Wednesday, September 8, 2010
http://www.flickr.com/photos/zkorb/
Wednesday, September 8, 2010
http://www.flickr.com/photos/jm999uk/
Wednesday, September 8, 2010
http://www.flickr.com/photos/obeyken/

Wednesday, September 8, 2010


http://www.flickr.com/photos/10411888@N06/
Wednesday, September 8, 2010
http://www.flickr.com/photos/pauldineen/

Wednesday, September 8, 2010


http://www.flickr.com/photos/jakerome/
Wednesday, September 8, 2010
Wednesday, September 8, 2010
Wednesday, September 8, 2010
Wednesday, September 8, 2010
http://www.flickr.com/photos/matthigh/

Wednesday, September 8, 2010


http://www.flickr.com/photos/xiaming/
Wednesday, September 8, 2010
http://www.flickr.com/photos/iceman9294/
Wednesday, September 8, 2010
http://www.flickr.com/photos/avoiretc/

Wednesday, September 8, 2010


http://www.flickr.com/photos/jakerome/
Wednesday, September 8, 2010
http://www.flickr.com/photos/kazk/

Wednesday, September 8, 2010


http://www.flickr.com/photos/paloetic/
Wednesday, September 8, 2010
http://www.flickr.com/photos/what_i_see/
Wednesday, September 8, 2010
http://www.flickr.com/photos/avoiretc/

Wednesday, September 8, 2010


http://www.flickr.com/photos/pauldineen/

Wednesday, September 8, 2010


http://www.flickr.com/photos/10411888@N06/
Wednesday, September 8, 2010
http://www.flickr.com/photos/xiaming/
Wednesday, September 8, 2010
http://www.flickr.com/photos/captkodak/
Wednesday, September 8, 2010
Wednesday, September 8, 2010
Wednesday, September 8, 2010
Wednesday, September 8, 2010
Wednesday, September 8, 2010
http://www.flickr.com/photos/
Wednesday, September 8, 2010
http://www.flickr.com/photos/
Wednesday, September 8, 2010
Examples

Wednesday, September 8, 2010


http://www.flickr.com/photos/
Wednesday, September 8, 2010
from celery.task import Task

class CreateUserTask(Task):
def run(self, username, password):
create_user(username, password)

from celery.decorators import task


from django.contrib.auth import User

@task
def create_user(username, password):
User.objects.create(username=username, password=password)

Wednesday, September 8, 2010


from datetime import datetime, timedelta
from ourapp.tasks import CreateUserTask, UnbanTask

# Simple call
username = 'bob'
password = 'something'
CreateUserTask.delay(username=username, password=password)

# More advanced call


tomorrow = datetime.now() + timedelta(days=1)
UnbanTask.apply_async(args=[username], eta=tomorrow)

Wednesday, September 8, 2010


from celery.decorators import periodic_task
from datetime import timedelta

@periodic_task(run_every=timedelta(seconds=30))
def every_30_seconds():
print("Running periodic task!")

Wednesday, September 8, 2010


from celery.task.schedules import crontab
from celery.decorators import periodic_task

@periodic_task(run_every=crontab(hour=7, minute=30, day_of_week=1))


def every_monday_morning():
print("Execute every Monday at 7:30AM.")

Wednesday, September 8, 2010


from celery.concurrency.processes.pool import Pool
from myapp.stuff import do_really_expensive_stuff, some_collection

pool = Pool()

results = poll.map(do_really_expensive_stuff, some_collection)

Wednesday, September 8, 2010


http://www.flickr.com/photos/
Wednesday, September 8, 2010
# myapp/models.py

from django.db import models


from imagekit.models import ImageModel

class Photo(ImageModel):
name = models.CharField(max_length=100)
original_image = models.ImageField(upload_to='photos')
num_views = models.PositiveIntegerField(editable=False, default=0)

class IKOptions:
# This inner class is where we define the ImageKit options for
the model
spec_module = 'myapp.specs'
cache_dir = 'photos'
image_field = 'original_image'
save_count_as = 'num_views'

Wednesday, September 8, 2010


# myapp/specs.py

from imagekit.specs import ImageSpec


from imagekit import processors

# first we define our thumbnail resize processor


class ResizeThumb(processors.Resize):
width = 100
height = 75
crop = True

# now we define a display size resize processor


class ResizeDisplay(processors.Resize):
width = 600

# now lets create an adjustment processor to enhance the image at small


sizes
class EnchanceThumb(processors.Adjustment):
contrast = 1.2
sharpness = 1.1

# now we can define our thumbnail spec


class Thumbnail(ImageSpec):
access_as = 'thumbnail_image'
pre_cache = True
processors = [ResizeThumb, EnchanceThumb]

# and our display spec


class Display(ImageSpec):
increment_count = True
processors = [ResizeDisplay]

Wednesday, September 8, 2010


python manage.py ikflush myapp

Wednesday, September 8, 2010


<div class="original">
<img src="{{ photo.original_image.url }}" alt="{{ photo.name }}">
</div>

<div class="display">
<img src="{{ photo.display.url }}" alt="{{ photo.name }}">
</div>

<div class="thumbs">
{% for p in photos %}
<img src="{{ p.thumbnail_image.url }}" alt="{{ p.name }}">
{% endfor %}
</div>

Wednesday, September 8, 2010


http://www.flickr.com/photos/
Wednesday, September 8, 2010
class BlogPostHandler(BaseHandler):
allowed_methods = ('GET', 'PUT', 'DELETE')
fields = ('title', 'content', ('author', ('username', 'first_name')),
'content_size')
exclude = ('id', re.compile(r'^private_'))
model = Blogpost

@classmethod
def content_size(self, blogpost):
return len(blogpost.content)

def read(self, request, post_slug):


post = Blogpost.objects.get(slug=post_slug)
return post

@throttle(5, 10*60) # allow 5 times in 10 minutes


def update(self, request, post_slug):
post = Blogpost.objects.get(slug=post_slug)

post.title = request.PUT.get('title')
post.save()

return post

def delete(self, request, post_slug):


post = Blogpost.objects.get(slug=post_slug)

if not request.user == post.author:


return rc.FORBIDDEN # returns HTTP 401

post.delete()

return rc.DELETED # returns HTTP 204

Wednesday, September 8, 2010


from django.conf.urls.defaults import *
from piston.resource import Resource
from piston.authentication import HttpBasicAuthentication

from myapp.handlers import BlogPostHandler

auth = HttpBasicAuthentication(realm="My Realm")


ad = { 'authentication': auth }

blogpost_resource = Resource(handler=BlogPostHandler, **ad)

urlpatterns += patterns('',
url(r'^posts/(?P<post_slug>[^/]+)/$', blogpost_resource),
)

Wednesday, September 8, 2010


http://www.flickr.com/photos/lwr/
Wednesday, September 8, 2010
http://www.flickr.com/photos/renatamotta/
Wednesday, September 8, 2010
from celery.task.schedules import crontab
from celery.decorators import periodic_task

@periodic_task(run_every=crontab(hour=7, minute=30, day_of_week=1))


def every_monday_morning():
print("Execute every Monday at 7:30AM.")

Wednesday, September 8, 2010


http://www.flickr.com/photos/rctern/

Wednesday, September 8, 2010


from django.contrib import admin
from myproject.myapp.models import Author

class AuthorAdmin(admin.ModelAdmin):
date_hierarchy = 'pub_date'
exclude = ('book_count',)

admin.site.register(Author, AuthorAdmin)

Wednesday, September 8, 2010


http://www.flickr.com/photos/escher1/

Wednesday, September 8, 2010


from celery.task import Task

class CreateUserTask(Task):
def run(self, username, password):
create_user(username, password)

Wednesday, September 8, 2010


http://www.flickr.com/photos/roscoe/
Wednesday, September 8, 2010
class BlogPostHandler(BaseHandler):
allowed_methods = ('GET', 'PUT', 'DELETE')
fields = ('title', 'content', ('author', ('username', 'first_name')),
'content_size')
exclude = ('id', re.compile(r'^private_'))
model = Blogpost

@classmethod
def content_size(self, blogpost):
return len(blogpost.content)

def read(self, request, post_slug):


post = Blogpost.objects.get(slug=post_slug)
return post

@throttle(5, 10*60) # allow 5 times in 10 minutes


def update(self, request, post_slug):
post = Blogpost.objects.get(slug=post_slug)

post.title = request.PUT.get('title')
post.save()

return post

def delete(self, request, post_slug):


post = Blogpost.objects.get(slug=post_slug)

if not request.user == post.author:


return rc.FORBIDDEN # returns HTTP 401

post.delete()

return rc.DELETED # returns HTTP 204

Wednesday, September 8, 2010


http://www.flickr.com/photos/estherase/
Wednesday, September 8, 2010
http://www.flickr.com/photos/desiitaly/

Wednesday, September 8, 2010


http://www.flickr.com/photos/thesmith/
Wednesday, September 8, 2010
Wednesday, September 8, 2010
Wednesday, September 8, 2010
http://www.flickr.com/photos/jakerome/
Wednesday, September 8, 2010
http://www.flickr.com/photos/rarefrequency/

Coming soon...
Wednesday, September 8, 2010
@theSeanOC

seanoc.com

Wednesday, September 8, 2010

Vous aimerez peut-être aussi