multiple apps - python style

0 views
Skip to first unread message

Kevin Dangoor

unread,
Jan 11, 2006, 1:44:19 PM1/11/06
to cherryp...@googlegroups.com
Something I'm angling for is the ability to compose TurboGears apps
Python-style. Here's an example:

1) install "Blog-1.0.egg"
2) set up your controller object like this:

from blog import Blog

class Root(turbogears.controllers.Root):
blog1 = Blog()
blog2 = Blog()

The way I read ticket 145, it sounds like the declaration of the blog
apps would need to be done via calls to tree.mount(). It would be nice
if that detail was hidden. Unfortunately, that Root controller doesn't
know if there's another object on top of it, so it can't just call
tree.mount() itself.

TurboGears has a monkeypatch against CherryPy at present to follow the
path along to the controller that ends up receiving the request and
hangs on to that path for building URLs to the Root of a given app.
*That* path could be used to call tree.mount(), but it only works in
the context of a request.

I recognize that there are many different ways that one can compose
apps. The thing that I like about this is that it's *natural* and fits
in with the way CherryPy programs look like fairly standard Python
programs.

Does this seem possible?

Kevin

--
Kevin Dangoor
Author of the Zesty News RSS newsreader

email: k...@blazingthings.com
company: http://www.BlazingThings.com
blog: http://www.BlueSkyOnMars.com

Remi Delon

unread,
Jan 12, 2006, 1:53:51 PM1/12/06
to cherryp...@googlegroups.com
> Something I'm angling for is the ability to compose TurboGears apps
> Python-style. Here's an example:
>
> 1) install "Blog-1.0.egg"
> 2) set up your controller object like this:
>
> from blog import Blog
>
> class Root(turbogears.controllers.Root):
> blog1 = Blog()
> blog2 = Blog()

Well, I put some thought into this and I came up with changeset [926].
It is only a proof-of-concept for now and it is backward-compatible.

I like Iain's idea that apps could only find out where they're mounted when
a request arrives.
We don't necessarily need to tell them in advance where they're monuted.

My change goes like this:
Basically, people who develop apps just have to specify a "is_app_root"
attribute in the root class of their app to tell CP that this class is the
root of the app.
CP then offers a new "cherrypy.url()" function which app developers can
call. They pass an absolute URL as if their app was mounted on '/' and
cherrypy.url() adds the necessary prefix to the URL.

So, a developer writing a weblog would provide this file:

** file blog.py **:

# import cherrypy
#
# class Blog:
# is_app_root = True
# def __init__(self):
# self.blog_admin = BlogAdmin()
# def index(self):
# return '<a href="%s">admin</a>' % cherrypy.url('/blog_admin')
# index.exposed = True
#
# class BlogAdmin:
# def index(self):
# return '<a href="%s">home</a>' % cherrypy.url('/')
# index.exposed = True


Someone wanting to "mount" several of these blogs in their site would write
this:

# import cherrypy
# from blob import Blog
# class Root:
# blog1 = Blog()
# blog2 = Blog()
# blog2.blog3 = Blog() # Recursive apps work too !
#
# cherrypy.root = Root()
# cherrypy.server.start()


The way it works is that when a request arrives, CP traverses the object
tree as usual, but when it encounters "is_app_root == True", is saves the
corresponding path to request.app_path.
cherrypy.url(u) just returns request.app_path + u


What do you think ?

Remi.

Kevin Dangoor

unread,
Jan 12, 2006, 2:07:57 PM1/12/06
to cherryp...@googlegroups.com
On 1/12/06, Remi Delon <re...@cherrypy.org> wrote:
> My change goes like this:
> Basically, people who develop apps just have to specify a "is_app_root"
> attribute in the root class of their app to tell CP that this class is the
> root of the app.
> CP then offers a new "cherrypy.url()" function which app developers can
> call. They pass an absolute URL as if their app was mounted on '/' and
> cherrypy.url() adds the necessary prefix to the URL.

This is effectively what TurboGears does today with the
controllers.Root class and the turbogears.url function (with the help
of a monkeypatch against CherryPy). The problem was with
configuration, because the app likely has static files that are
configured somewhere off of the app root.

If you couple what you're talking about with fumanchu's mounting
stuff, then I think this may work. The interesting question becomes:
how does CherryPy get the config for that app that was just discovered
via traversal?

Yes, this is exactly what i had in mind. There are situations where
externally configured URLs are ideal, but I really think that the
Pythonic way of composing a website is very natural for people to use
when their needs are not as complicated.

> The way it works is that when a request arrives, CP traverses the object
> tree as usual, but when it encounters "is_app_root == True", is saves the
> corresponding path to request.app_path.
> cherrypy.url(u) just returns request.app_path + u

I might suggest that cherrypy.url is set up like turbogears.url for
handling query parameters as a convenience:
def url(tgpath, tgparams=None, **kw):
"""Computes URLs.

tgpath can be a list or a string. If the path is absolute (starts
with a "/"), the server.webpath and the approot of the application
are prepended to the path. In order for the approot to be
detected properly, the root object should extend controllers.RootController.

Query parameters for the URL can be passed in as a dictionary in
the second argument *or* as keyword parameters."""

It's not a lot of code, but it makes life easier. That function is here:

http://www.turbogears.org/svn/turbogears/trunk/turbogears/util.py

Other than that, I think that combining this with fumanchu's Tree
should ultimately work.

Kevin

Reply all
Reply to author
Forward
0 new messages