Outils personnels
Vous êtes ici : Accueil Topics pylons
HADOPI - Le Net en France : black-out

pylons

30/04/2009

minitage 1.0 is out

by kiorky — last modified 30/04/2009 21:12

I did not find the time earlier to post about it.

Minitage 1.0 is out for a week now.

What you can find there ?

  1. Documentation has been drasticly improved
    See by yourself:
  2. Trac got Git support
  3. There are cgit and gitweb instances configured against all minitage repositories
  4. A lot of bugfixes, as always
  5. Recipes have been rewritten a bit to stick to zc.recipe.* implementations
  6. minitage.recipe egg based recipes got a fresh touch:
    • They do not totally rely any more on easy_install dependency system, just on their declared dependencies (extras are also supported). Thas was something i disliked with zc.recipe.egg, potentially, the easy_install call can install something, which we would'nt. And also, in some cases, the extras requirement could be wiped out. All are bugs reported upstream on the zc.buildout launchpad bugtracker.
    • Their installer should now try not to look in the site-packages first, but rather the eggs cache to avoid conflict errors.
    • I also implemented an adaptation of the zc.buildout redo_pyc function which seems to be somehow slow.
  7. Welcome to the buildout.minitagificator egg which help minitage to conquer the world with replacing some well known recipes with their equivalent minitage implementations with some violent monkey patches. It's a buildout extension.
  8. The "static fetcher" has been improved and bug fixed
  9. There some new cool API functions like a search function which take regexes to look for minibuilds in the available minilays
  10. minitage.paste got a great step forward with all pastes
  11. All templates now have now minitage layout as an optionnal dependency. That means that you do not need minitage to generate templates, however, the normal use is to use them in minitage.
    • Plone32 template:
      • Predefined set of products to install
      • A developper mode where you have aditionnal tools installed (ptprofiler, collective.autorestart on linux, and so on) and debug mode turned on by default
      • wsgi configuration and launchers
      • A working filesystemstorage integration
      • You can use either RelStorage, ZEO or classical ZODB access
      • You can give to paster whatever you want to custom the buildout generation by some predefined keys.
    • Zope3 template:
      • wsgi configuration and launchers (paster and Zdaemon based)
      • You can use either RelStorage, ZEO or classical ZODB access
      • You can give to paster whatever you want to custom the buildout generation by some predefined keys.
    • Django template:
      • wsgi configuration and launchers
      • GeoDjango support
      • dj.paste (http://pypi.python.org/pypi/dj.paste) integration. This paster factory enables you to have multiple django instances in the same pipeline
      • A basic application created when you generate your project to quickstart.
      • You can give to paster whatever you want to custom the buildout generation by some predefined keys.
    • Nearly all templates which have WSGI support got Spawning integration. Spawning is an über performant python based WSGI server.
    • postgresql, varnish, varnish2, and env profils:
      • Can run now without minitage or any project installed
    • The new paste-initd profil:
      • it generates an initscript wrapper to trigger a "paster serve" from some paste configuration of your choice

What are the minitage projects and profiles, after all ?

All are paster (see PasteScripts on pypi) templates.

Projects target to quickstart an application or a project like a plone3 or a django website.

Profiles, on the other side, are a piece of integration, targeted to be in general integrated into a minitage based project. That can be a postgresql database instance, or a shell environement file with has all minitage dependencies, that you can source when playing with your project.

21/10/2008

Pylons, xmlrpc and doctest

by kiorky — last modified 21/10/2008 22:40
Classé sous :

How to make some doctests with pylons and an xmlrpc controller

I m actually developping some application around XMLRPC protocol at work.

We are using Pylons for the framework part, and i played this afternoon at setting up some testing environnement for doing doctests.

This test is a proof of concept, it 's code extracted from our internal application, it's just a starter for you. The whole is working with some tweaks.


controllers/mycontroller.py, a simple controller doing simple stuff

class MyController(XMLRPCController):
    """controller."""                           

    def index(self):
        return '\_o<'

 

lib/base.py, Please add the XMLRPCController import

lib/base.py:from pylons.controllers import WSGIController, XMLRPCController

 

Then, we are setted up to continue with tests

First of all, the doctest boilerplate:

tests/test_doctest_files.py

import doctest
from doctest import DocFileSuite

from myproject.tests import setUp, tearDown
flags = (doctest.ELLIPSIS | doctest.NORMALIZE_WHITESPACE | doctest.REPORT_ONLY_FIRST_FAILURE)

def test_suite():
    return DocFileSuite(
        "test.txt",     
        setUp = setUp,  
        tearDown = tearDown,
        optionflags = flags 
    )

 

setUp and tearDown will have a central place as they are intialising the application.

As we can't use paste.fixture.TestApp objects with XMLRPC because it does not bind everywhere, the idea is

  • launch the server somewhere in a thread
  • use it later, as usual throught xmlrplib.
  • We will even declare it as a global to ease the doctests writings.
  • We also add a wrapper to url_for to return the host to bind to.
tests/__init__.py
import os
import sys
import re
import threading
from ConfigParser import ConfigParser
from unittest import TestCase

import paste.fixture
import paste.script.appinstall
from paste.deploy import loadapp
from paste.httpserver import serve
from routes.util import url_for

here_dir = os.path.dirname(os.path.abspath(__file__))
conf_dir = os.path.dirname(os.path.dirname(here_dir))
test_file = os.path.join(here_dir, 'test.ini')

cmd = paste.script.appinstall.SetupCommand('setup-app')

cmd.run([test_file])

def setUp(test, *args, **kwargs):
    print "\t-----------------------------------------------------------------"
    print "\t---    Setting up database test environment, please stand by. ---"
    print "\t-----------------------------------------------------------------"
    config = ConfigParser()
    config.read(
        os.path.join(os.path.dirname(sys.argv[0]), '..', 'etc', 'config.ini')
    )

    infos = ConfigParser()
    infos.read(test_file)
    sinfos = infos._sections['server:main']
    wsgiapp = loadapp('config:test.ini', relative_to = here_dir)
    server = test.globs['server'] = serve(wsgiapp,





    t = threading.Thread(target=server.serve_forever)
    t.setDaemon(True)
    t.start()
    test.globs['app'] = paste.fixture.TestApp(wsgiapp)
    def url_for_wrapper(*args, **kwargs):
        lkwargs = {'protocol': 'http' ,'host':  "%s:%s" % (server.server_name, server.server_port)}
        lkwargs.update(kwargs)
        return url_for(*args, **lkwargs)
    test.globs['url_for'] = url_for_wrapper
    test.globs['url_for_orig'] = url_for

def tearDown(test):
    test.globs['server'].server_close()

class TestController(TestCase):
    def __init__(self, *args, **kwargs):
        wsgiapp = loadapp('config:test.ini', relative_to = here_dir)
        self.app = paste.fixture.TestApp(wsgiapp)
        TestCase.__init__(self, *args, **kwargs)


 

And finally, letz play with our doctest

tests/text.txt

>>> create_url = url_for(controller='mycontroller')

>>> import xmlrpclib
>>> s = xmlrpclib.Server(create_url)
>>> s.index()
'\\_o<'