The Atom-REST syntax for resources is mainly beneficial to
non-interactive user agents (robots and front ends), and cases where
the resource is isolated from a "web site" (Amazon S3). But when the
resource is embedded in a visual web site, it goes against traditional
website usage. Traditionally the form and its action were at the same
URL, and POST was used for all actions. So GET displays the form, and
POST creates/updates/deletes the resource. RESTifarians call this
inferior and it has been drummed out of Routes and Pylons (although it
can be reconstructed manually). This led to the splitting of the
controller action from one method (for both display, validating, and
processing), to two (one for display, another for
validating/processing), and the @validate decorator which tries to
synchronize the two but is inadequate for edge cases (what if the
validator needs state such as the current record ID or database
record?).
I also notice that all the biggest social networking sites --
Facebook, MySpace, YouTube, etc -- totally violate REST at all levels,
with query string monstrosities that we would never use. Yet that has
not caused the sites to be unpopular or the owners' stock dividends to
fall.
Another thing is that map.resource has no delete confirmation form, so
I have to add one to every application. And it creates all routes
even if some are disallowed by application policy; e.g., creating
resources or deleting them. Perhaps the site insists that all
creation or deletion is done outside the web.
So I think there's room for a compromise, a kind of resource route
that's not Atom compatible but still has good URL structure, and a
one-method action. I don't have the exact specs on hand but it's
something like this:
def resource2(self, name, path, new=True, edit=True, delete=True):
GET /myresource : view index
GET /myresource/new : new form
POST /myresource/new : new action
GET /myresource/1 : view record 1
GET /myresource/1/edit : edit form
POST /myresource/1/edit : edit action
GET /myresource/1/delete : delete form
POST /myresource/1/delete : delete action
If the boolean args are false, routes for those actions would not be created.
I'd also like to see a resource route object in the routing table.
Currently map.resource creates a bunch of independent routes, which
don't have a group identity when introspected. But that's another
issue and longer term.
- coincidentally I was
> working on the post [1] below in which I refactor my way to a much
> more flexible alternative that builds on the new SubMapper idea. I'd
> be interested to know what people think.
>
> [1] DRY up your routes - a Pylons routing refactoring http://positiveincline.com/?p=561
Could you make Routes tickets for these? Then they'll be easier to
follow up on.
.submapper is documented now, but I'm not sure if readers can infer
all the cases you describe.
If not, it just needs some examples added
http://routes.groovie.org/manual.html (search for "submapper")
The new methods may be more radical than Routes wants to do, but
having it in tickets will make them easier to address. Or maybe you
already did; I see there's one ticket by you.
http://bitbucket.org/bbangert/routes/issue/21/add-submappersubmapper
--
Mike Orr <slugg...@gmail.com>
On Dec 21, 3:54 pm, Mike Orr <sluggos...@gmail.com> wrote:
> def resource2(self, name, path, new=True, edit=True, delete=True):
>
> GET /myresource : view index
> GET /myresource/new : new form
> POST /myresource/new : new action
> GET /myresource/1 : view record 1
> GET /myresource/1/edit : edit form
> POST /myresource/1/edit : edit action
> GET /myresource/1/delete : delete form
> POST /myresource/1/delete : delete action
I don't like stuff like this, so I could care less. But...
If you're going this route, it might make sense to do canned
conditions for the most likely implementations, like ned=True would
set up new, edit and delete.
i've seen that in a few different settings. most notably the Amazon S3
implementation -- where that option really does clean up a lot of code
and make it easier to work with.
Then there's the routes prettyprinter - there's no command for it but
even in the paster shell I have found it useful.
That leaves collection(). If you feel it may be too radical for
Routes that's OK I guess, but I will continue to use it - resource()
is just too clumsy (as is the Rails one for that matter, though with
fewer limitations). Whether collection() is the way forward or not,
some attention to the level of duplication necessary within routing.py
and between routing.py and the controllers would surely be good for
all.
> I'd also like to see a resource route object in the routing table.
> Currently map.resource creates a bunch of independent routes, which
> don't have a group identity when introspected. But that's another
> issue and longer term.
Like described_routes ;-) But that's only a representation, not a
routing implementation. Seriously though, I have been wondering if a
hierarchical organisation internally would be good for performance
too.
Regards,
Mike
> > [1] DRY up your routes - a Pylons routing refactoringhttp://positiveincline.com/?p=561
>
> Could you make Routes tickets for these? Then they'll be easier to
> follow up on.
>
> .submapper is documented now, but I'm not sure if readers can infer
> all the cases you describe.
> If not, it just needs some examples addedhttp://routes.groovie.org/manual.html (search for "submapper")
>
> The new methods may be more radical than Routes wants to do, but
> having it in tickets will make them easier to address. Or maybe you
> already did; I see there's one ticket by you.http://bitbucket.org/bbangert/routes/issue/21/add-submappersubmapper
>
> --
> Mike Orr <sluggos...@gmail.com>
with mapper.collection(
'myresources',
'myresource',
collection_actions = ['index', 'new'],
member_actions = ['show', 'update']) as c:
c.link('new', name='create_resource', method='POST')
c.member.link('delete', method='POST')
>>> print mapper
myresources GET /myresources
new_myresource GET /myresources/new
myresource GET /myresources/{id}
update_myresource PUT /myresources/{id}
create_resource POST /myresources/new
delete_myresource POST /myresources/{id}/delete
Alternatively you could model 'new' as a nested subresource but this
takes a couple more lines and probably not worth the bother here.
Mike
I'm just a little hesitant to move forward with adopting it in my app
at the moment because if routes 2 comes up with something completely
new/different, then I'll be depending on this new branch or migrating
my routes later when routes 2 is available.
I know api changes for a commonly used lib like routes should not be
made lightly and require thinking time, but I sure would like to know
which way it is headed.
On Dec 22, 2:42 am, "Mike Burrows (asplake)" <m...@asplake.co.uk>
wrote:
A nice next step would be to refactor a published example or two. A
squeaky clean tutorial example with a tidy routing config and no
redundant decorators would be nice, don't you think? If anyone
maintains suitable candiate and would like a collaborator, please get
in touch.
Regards,
Mike
m...@asplake.co.uk
http://positiveincline.com
Quick question, is setting conditions at the collection() level
supported? For example, most of my urls require a subdomain.
map.collection('events', 'event', conditions=dict(sub_domain=True))
File "/Routes-1.11dev-py2.6.egg/routes/mapper.py", line 164, in
connect
if isinstance(value, dict):
NameError: global name 'value' is not defined
On Dec 29, 2:51 am, "Mike Burrows (asplake)" <m...@asplake.co.uk>
wrote:
> I can't speak for Routes 2 but I'm pleased to report that my changes
> will soon make it into dev Routes. Actually "delighted" would be a
> better word - it's my first formal contribution :-)
>
> A nice next step would be to refactor a published example or two. A
> squeaky clean tutorial example with a tidy routing config and no
> redundant decorators would be nice, don't you think? If anyone
> maintains suitable candiate and would like a collaborator, please get
> in touch.
>
> Regards,
> Mike
> m...@asplake.co.ukhttp://positiveincline.com
map.collection('events', 'event', conditions=dict(sub_domain=True),
requirements=dict(id='\d+'))
On Dec 29, 2:54 pm, "Mike Burrows (asplake)" <m...@asplake.co.uk>
Ben said he's aiming for a release at the end of the year. It may be
a few days late. You can search the list archive for his own words.
The development version of Pylons is very similar to the upcoming
release, so if your application runs fine with it, you're ready to go.
Note that the development version has named branches. The trunk is
Pylons 1.0, which is incompatible with certain deprecated features.
The 0.10 branch is for Pylons 0.10, which retains compatibility.
--
Mike Orr <slugg...@gmail.com>
Routes 2 is cancelled. Some of the features have been backported to
Routes 1, and more are planned, but it will remain compatible.
I'm letting Ben deal with Routes 1 patches, which is why I haven't
commented on them.
> A nice next step would be to refactor a published example or two. A
> squeaky clean tutorial example with a tidy routing config and no
> redundant decorators would be nice, don't you think? If anyone
> maintains suitable candiate and would like a collaborator, please get
> in touch.
An example of what? If it's just the new Routes features, you can put
it in the Routes docs directory (Sphinx ReST format), and will
automatically be picked up if the patch is accepted. You'll probably
have to create an appendix in the manual for examples. If it covers
more than Routes (as "decorators" suggests), it will have to go into
Pylons somewhere, so the best place for now would be the Pylons
Cookbook in the wiki. You can make a general page for "routing
examples" if you don't see an appropriate place for it.
If anyone has time to go through the Pylons Cookbook and look for
stuff that should be in the official docs or is obsolete, now would be
a good time. Official docs material can go to me; just tell me where
it is.
--
Mike Orr <slugg...@gmail.com>
In the Pylons roadmap wiki page, it mentions a mysterious ;) new meta
framework called Marco. Is this hosted anywhere? I'd like to just
poke around and see where it is headed.
Regarding routes in general, the public routes api is really nice and
easy, but as I've been poking around in the source I've found parts
somewhat hard to follow - perhaps that is the nature of url matching/
generation (I'm no expert). Thus, I'm really not sure of where or how
I should customize behavior that can't be done through the public
api. For example, I had to modify util._subdomain_check to get a
behavior I wanted for url generation. I don't have any concrete
suggestions at the moment, just rambling thoughts after staring at the
source for too long.
> Mike Orr <sluggos...@gmail.com>
On 30 Dec 2009, at 03:17, Chris wrote:
> In the Pylons roadmap wiki page, it mentions a mysterious ;) new meta
> framework called Marco. Is this hosted anywhere? I'd like to just
> poke around and see where it is headed.
It's early days yet but ...
Project home is on coactivate: http://www.coactivate.org/projects/pypefitters/summary
Source is hosted on bitbucket: http://bitbucket.org/chrism/marco/
I have a few pages of preliminary notes: http://bel-epa.com/notes/Marco/
Cheers,
Graham
http://www.linkedin.com/in/ghiggins
-----BEGIN PGP SIGNATURE-----
iEYEARECAAYFAks64/wACgkQOsmLt1Nhivwf8gCeJsb2/50VDTXlvnYL44uHIGa/
IPEAn0I1g2TJYvjJplVbdY84bNz38EtKiQCVAgUBSzrj/FnrWVZ7aXD1AQKpiQQA
kQBZcJUb5XxJzzvzRTNfRzvOAFR1L07CIxpUvGGQjwKNHogjXr+6iELfxYc2Yr4M
LCH532zUvJDaEmD/OrOxE4iat/28dWwlIfgdpWLIY0GUMPukhTTD0uKdazN1lC35
vaM49foBOvcpiULgIYqRypLWlMFgHxNrI7V+GLOO19c=
=Gtw/
-----END PGP SIGNATURE-----
I put the Routes-exp (formerly Routes 2) code on bitbucket. It may be
easier to follow. The Routes internal structure will eventually be
made closer to this.
--
Mike Orr <slugg...@gmail.com>
Do we have any document or discussion to understand where the Pylons
lacks and how Marco solves the problem?
Thanks Mike, routes-exp is quite a bit easier and certainly fewer
sloc, ~1600 vs ~400. Nice work, and hope to see the changes in routes
someday.
>
> http://bitbucket.org/sluggo/routes-exp
>
> --
> Mike Orr <sluggos...@gmail.com>
The Marco core is a meta-framework, akin to Paste. It will have
several framework personalities on top of it, including a Pylons-ish
one, a TG2-ish one, and a repoze.BFG-ish one. How it will be branded
will be decided later. So the "Marco" package in PyPI may end up
refering to all of the above, or just to the common core. But either
way it will be possible to install the full kit with several framework
personalities, or just the parts you're interested in.
The Pylons-ish framework can currently run some Pylons applications,
so I've heard. If it succeeds it will likely become "Pylons 2".
Pylons is like an onion, so it can be difficult to answer, "What is
Pylons, and how many changes can you make before it's not Pylons
anymore?" In one sense, Pylons is the package called 'pylons'. But a
Pylons application includes more, and is held together via Paste. But
from a user's perspective, what matters is whether you can run
existing Pylons applications unchanged, and whether there are syntax
changes.
The goal of a Pylons-ish personality is to run Pylons 1 applications
(and hopefully 0.9.7 applications) with no changes to the controller
code, routing, templates, special globals, 'config' object, or INI
file. There may be a front-end configuration step: you may launch it
via something other than "paster serve development.ini", or the INI
file may be replaced by something equivalent.
I envision one personality for existing Pylons applications, and
another that would be free to make some syntax changes, such as
perhaps replacing the special globals with controller-instance
attributes. The latter might be called "Pylons 2", while the former
would just be "the Marco port of Pylons". It just depends on what
marketing/branding we want to do when the time comes. The code will
be the same no matter what the branding is, and maintained by
Pylons/TG developers as it is now.
> Do we have any document or discussion to understand where the Pylons
> lacks and how Marco solves the problem?
I tried to explain it in the Roadmap
(http://wiki.pylonshq.com/display/pylonscommunity/Pylons+Roadmap+to+1.0).
Graham's webpages record the raw discussion. The main point is, it's
more of interest to framework developers than framework users.
Marco is an extension of what Pylons is already doing. Pylons is "the
modular framework built on Paste/WSGI". Marco makes it even more
modular. Currently you can plug in any server and an application in
the INI file, any middleware in middleware.py, and any template engine
by reimplementing render_mako(). Marco allows framework developers to
plug in reusable framework components in a similar way. You can
"build your own framework" by plugging in the dispatch/routing style,
request/response style, etc, that you prefer.
The name for this is componentization. Zope.component provides the
underlying architecture. A configuration file specifies which
components to plug in to make a framework. Pylons users wouldn't
worry about this: it's all handled in the Pylons-ish personality.
But a future user could, if he wanted to, specify the equivalent of a
Pylons application (with components, routing, and configuration), all
in a single configuration file. It may be in XML, YAML, Python, or
another format -- Marco accepts multiple configuration formats.
Basically, in 2005 we tried to make framework code more interoperable
with WSGI and Paste. That worked well but has some limitations. WSGI
was originally envisioned to connect an aribitrary application to an
arbitrary server. It happened to allow middleware, and this gave
increased pluggability. But five years' experience has shown that raw
WSGI is too clunky for many things, even if it still does its original
job well. WebOb provides an abstraction above WSGI. And now Marco
provides a way to componentize all parts of the framework beyond what
middleware/Paste INI can do. We found a component architecture
already existing in Zope, extracted from the rest of Zope in Repoze,
and decided it was better than building our own. (Because it works
and has been tested for ten years.) So that is what has led to this
point.
The public discussion in Graham's archive goes from January to July
2009. After that, ChrisM and Ben were collaborating privately on
their own prototypes, and the discussions weren't archived. I haven't
been involved directly since April due to other commitments. But we
(the Pylons/TG/BFG developers) are all interested in seeing what comes
out of the prototypes, and hope to get more involved in it as we
finish our other commitments (Pylons 1.0, documentation, etc).
--
Mike Orr <slugg...@gmail.com>
As you mentioned, Pylons 2.0/x.y may hide the implementation details
of marco and yet provide rather more pluggable framework. I have used
the IoC extensively in .NET applications and curious to know how it is
works in the making python web components. Once things formally
announced, I can look at the source code to learn the progress. May be
separate user group shall be good for discussion.
Does this new architecture support running multiple applications
together to make one website? For example, say we have a blog
application, forum application, poll, feedback and cms application but
we can assemble them together to make the website. I think, Rails 3 (/
Merb), tries the similar stuff.
I wish you the best for development of Marco.
Regards,
Krish
On Dec 31, 12:40 am, Mike Orr <sluggos...@gmail.com> wrote:
> On Wed, Dec 30, 2009 at 1:26 AM, karikris...@gmail.com
> Mike Orr <sluggos...@gmail.com>
On 31 Dec 2009, at 01:04, karik...@gmail.com wrote:
> Does this new architecture support running multiple applications
> together to make one website? For example, say we have a blog
> application, forum application, poll, feedback and cms application but
> we can assemble them together to make the website. I think, Rails 3 (/
> Merb), tries the similar stuff.
Well, therein lies the core of my interest in the topic and hence the
quick pass over a few approaches to the issue of providing a means of
facilitating the interoperation of multi-component web apps, just to
get a feel for what's on offer elsewhere. However, the interop issue
also emerges at the lower level of integrating the approaches taken by
different "frameworks" (for want of a better term). Multi-component
web apps isn't an explicit target for Marco per se but, as chrism
observes in his high-level overview proposal: "Multiple applications
in the same process space should be possible without (much) trickery."
It's something to be explored and that's where my interest lies.
BTW, development of an approach to, e.g. a Pylons-mediated MWA
solution, probably needs to take place in the context of something
radically useful like toppcloud [1], otherwise it could well be
destined to occupy a rather small and unimportant (but perhaps not
unprofitable) niche of the dynamic language web app world.
[1] http://bitbucket.org/ianb/toppcloud/src/tip/docs/index.txt
Cheers,
Graham
http://www.linkedin.com/in/ghiggins
-----BEGIN PGP SIGNATURE-----
iEYEARECAAYFAks7/k8ACgkQOsmLt1NhivyJtQCeL8J1UWUj1GwlQP7Zx0Z0TmO/
4YUAoOVtOuaY9DnAckRn42xJQM3Y6Uv5iQCVAgUBSzv+T1nrWVZ7aXD1AQLlQwP/
VPwwwthSIxKjP7hqkJC2C80uaYQgHvyUqxjAvlwqZ4x3+cpc3ex2SGBuszuR0t7O
qyupEoFsVkV/zSnyAPiOCi97jWoU+uLBNnO69hPjgxHwom2Q7aw7agJZc915eXKL
HHXTDy/Sz/3T5Dgoowx7AQvGSz0Im7hCBrf519P0jZ0=
=C19j
-----END PGP SIGNATURE-----
AttributeError: 'SubMapper' object has no attribute '__exit__'.
It's fixed now in the asplake/routes repo and will be in due course in
bbangert/routes if I haven't already tested Ben's patience past
breaking point. It was another merge error and completely my fault -
I was careless in the placement of some new code and didn't want to
add tests for the "with" syntax for fear of building in an unwanted
dependency on Python versions.
Apart from that, happy new year!
Mike
On Dec 29 2009, 9:54 am, "Mike Burrows (asplake)" <m...@asplake.co.uk>