Emulating Ruby's anonymous blocks with Myghty 3
Ruby’s anonymous block capability is probably the main feature I find myself wishing Python had on more than one occasion. While the upcoming Python 2.5 PEP 323 provides for the “with” statement which will enhance generators to get a bit closer. Though as Ryan Tomayko notes, this still doesn’t make the block available within the “generator”.
There are of course, many uses for having the block (with its closure scope), available in the function/generator you’re using. I’ve seen this used to easily register code call-backs with a CleanUp/Initializaiton manager, and other cases where its preferable to actually retain the block in its entirety for later execution. It’s also very useful when you want the function to control execution of the block, and return its output in a modified form.
In these ways, it would appear that the generator enhancements won’t quite be bringing the full power of Ruby anonymous blocks to Python. However, I recently found out that a relatively recent feature in my favorite Python template language, Myghty, implements something quite close to this.
Myghty’s Component Calls with Content
In a previous entry on Formencode and SQLObject I noted how useful the component call with content can be. What I failed to note (I didn’t know at the time as well), was that not only is the function/component able to get the content of the content “block”, but its also able to execute it again and again.
Consider this example from my prior entry:
Hi, lets translate the content under:
<&| MODULE:mylib:translate, lang='es' &>
This entire block of content will be sent in as a
single variable to translate.myt
for use. This includes any <b>HTML tags and such</b> as well.
</&>
and the function it calls:
from mytranslater import translated
def translate(m, lang):
body = "<p>The translated text is:</p>"
body += translated(lang, m.content())
m.write(body)
The m.content() call can be called as many times as you want the output of it, and it retains the scope of its original location. This in many ways emulates how Ruby can yield to the block and capture its output, however it is not possible to stash the block itself (in Myghty/Python).
Next up is to actually be able to use values from the function inside the block. In Ruby this is done in a very elegant fashion letting you declare what you’ll call them, then use them, like so:
SomelistOfints.each do |item|
item += 2
end
To emulate this behavior, our block has to make a special function call and know the name of the value in advance. Here’s an example:
% randomvar = 423
<&| MODULE:mylib:translate, lang='es' &>
This entire block of content will be sent in
as a single variable to translate.myt for use.
This includes any <b>HTML tags and such</b> as
well. Here's something supplied by
translate: <% m.content_args['value'] %>.
Of course, <% randomvar %> is still in scope too.
</&>
And just for fun, our translate function will call the block with some different values:
def translate(m, lang):
body = "<p>The translated and repeated text is:</p>"
for val in range(0,4):
body += m.content(value=val)
body += "<p>That's it, nothing else.</p>"
m.write(body)
The important thing to remember that makes the concept powerful is that the block above is called in the scope you saw it in the template. Whatever variables were available there are used as normal.
Close…
This method brings us close to Ruby’s anonymous blocks, as close as might be possible in Python. Unfortunately its only usable within Myghty (if not, please let me know), and its still not true anonymous blocks. At the very least, its close enough to make me happy for now. While I could just switch to Ruby entirely, there’s still way too many things about Python that I’d miss.
From the details of PEP 343, it appears that this full capability to pass the block in was purposely avoided as having flow control in the “macro” makes the code inscrutable. Hopefully someday the utility and power such functionality provides will result in it being available in Python. Or at the very least, some clever person can try a variant in PyPy and see what sticks.
And yes, I know nested functions can be used and passed around with their closure, but its pretty annoying to be nesting functions back and forth solely for that purpose. It feels like all we have is a hammer…
Further reference:
Handling Form data w/Formencode+SQLObject Redux 2
In a prior post on handling form data I covered how to easily populate a form using FormEncode/SQLObject and validate/save the data.
One of the things I noted was that I had to take the HTML form output first, and use htmlfill with it to populate it with defaults and errors before displaying. This required some extra lines I wasn’t to thrilled with in the controller. After an evening of chatting with Ian Bicking about whether FormEncode could somehow be cleaned up to make this easier, Ian suggested I use a Myghty feature I had forgotten about.
Component Calling with Content blocks in Myghty
Somewhat ironic since I use Myghty all day and Ian doesn’t (afaik). It’s a very useful feature called Component Calls with Content. It’s probably easiest to understand the cool ability this provides by seeing it. In Myghty, each template is known as a component, and complex arrangements can easily be put together by component inheritance and component calls between them.
Normal Python function calls and expressions in a Myghty component (template) looks like this:
Hi everyone, 2 + 2 = <% 2+2 %> and your name is <% lookup_name() %>
To include content from other components, you can either call the component through the function call m.comp('/some/template.myt') or you can use the component call syntax:
Hi everyone
<& /sidebar.myt &>
So here’s how we will use a component call with content:
Hi, lets translate the content under:
<&| /translate.myt, lang='es' &>
This entire block of content will be sent in as a single variable to translate.myt
for use. This includes any <b>HTML tags and such</b> as well.
</&>
And the translate.myt template might look like:
<p>The translated text is:</p>
<% translated(lang, content) %>
<%args>
lang
</%args>
<%init>
from mytranslater import translated
content = m.content()
</%init>
This is probably a lot to absorb, as it utilizes a few different Myghty concepts. Components can have arguments they expect, here the translate.myt component expects a lang arg which is passed in. The content block is then available as m.content() inside the template. The <%init> block is called first and variables defined there are available inside the template.
So how does this help us with the original problem?
Module Components
So far, all of these abilities are possible in Myghty’s ancestor, Mason. One more powerful construct available in Myghty however is the ability to not only call components, but Module Components.
I’ve been familiar with these for awhile as I use them for Controllers. It had never occurred to me though, that they can call any function in a module as if it was a component, not just ‘Controllers’.
Module components allow you to do a variety of interesting things, mainly, calling functions, classes, or objects that are in Python modules. Let’s take a look at the last translate.myt example using this approach instead.
Hi, lets translate the content under:
<&| MODULE:mylib:translate, lang='es' &>
This entire block of content will be sent in as a single variable to translate.myt
for use. This includes any <b>HTML tags and such</b> as well.
</&>
And the mylib Python module (assumed to be in the search path):
from mytranslater import translated
def translate(m, lang):
body = "<p>The translated text is:</p>"
body += translated(lang, m.content())
m.write(body)
Myghty will examine the function signature to determine what variables it wants and will search the current scope to make sure they’re passed in. Very handy. :)
Putting it All Together
So let’s see how this helps us out, first, rather than having to take the form and render it in the controller, we’ll push this into the template using a component call with content. So our new myform.myt looks like:
# myform.myt
<html>
<head><title>basic form</title></head>
<body>
<&| MODULE:mylib:formfill, defaults=defaults, errors=errors &>
<form action="/mypage" method="post">
Username: <input type="text" name="username" size="26" />
<form:error name="username">
Age: <input type="text" name="age" size="3" />
<form:error name="age">
<input type="submit" value="Send it" />
</form>
</&>
</body>
</html>
<%args>
defaults
errors
</%args>
Our mylib module:
from formencode import htmlfill
def formfill(m, defaults, errors):
form = m.content()
m.write(htmlfill.render(form, defaults, errors))
And the new controller:
from ourschema import UserInfoSchema
from oursqlstuff import UserInfo
def mypage(m):
errors, defaults = {}, m.request_args
if m.request_args:
form, errors = UserInfoSchema(), {}
try:
form_result = form.to_python(m.request_args)
except api.Invalid, e:
errors = e.unpack_errors()
if not errors:
UserInfo(**form_result) # database insert
return m.subexec('/thankyou.myt')
m.subexec('myform.myt', defaults=defaults, errors=errors)
We’ve cut it down 1 line, from 12 to 11, however we no longer have to go through the slightly awkward maneuver of capturing the rendered form and running htmlfill over it in the controller. This is now handled easily in the template using a component call with content. The module component we use is extremely portable and can be used to wrap any form anywhere with automatic fill-in of errors and default values.
FormEncode 0.4 also deprecates HTMLForm which we were using before, so this will help out when thats no longer available.
Module component calls are quite useful, and make it easy to group together powerful function libraries that interact with Myghty parts. Being able to pass them content allows all sorts of new constructs to be created.
If you’re using Myghty with FormEncode and SQLObject, I’d highly suggest switching to this method instead of the one I blogged about before.
Editing Myghty with TextMate 2
TextMate is a rather slick little text editor, with a bunch of cool automation stuff thats great for programmers. You’ve probably already seen it if you’ve watched any of those demo movies for some of the latest web frameworks.
Anyways, as I mainly use Myghty, I needed a syntax highlighting mode for its format. So I made a Myghty bundle for TextMate. This should also be useful for those using Mason as only a few minor adjustments regarding the underlying language highlighter need to be tweaked (Change source.python -> source.perl). This also has a few automation snippets to speed things up.
To install:- Unzip
- Drag into
~/Library/Application Support/TextMate/Bundles/ - Restart TextMate (Not absolutely sure this is needed though)
Enjoy!
Hooked on Myghty 1
I’ve been programming web sites for many years, and have yet to come across a templating language as appealing as Mason / Myghty. To avoid confusion I’m going to talk about Myghty, but since its a direct port of Mason (plus some MVC stuff) all of my comments apply to Mason as well (unless otherwise noted). So if you find yourself stuck using Perl (or you prefer Perl) and something here sounds appealing, by all means use Mason as I did.
Despite Myghty only having come into existence approximately 14 months ago, the code-base is stable, very quick, and has been running in production environments for over 8 months. This is mainly because it started as a very direct port of Mason to Python, it then grew a few additional features that made it great for MVC use. The methodologies present in Mason (thus Myghty as well) are known to scale to very large and complex sites, as this list of Mason-powered sites shows. But it’s the little things added up that really make Myghty my template language of choice.
This is a rather lengthy post as I highlight and explain some core concepts of Myghty, please bear with me… also, if you’d like to follow along and try the examples out, its really easy to get started using Myghty with Paste.
Syntax
Template languages vary a lot in style, there are the very basic string replacement template languages all the way to more advanced template languages. Myghty definitely weighs in on the latter as it has many of its own concepts with regards to templating that produce a very robust and advanced templating system.
The syntax itself is also very appealing to me, as I’m a fan of templating languages that keep their guts inside < > signs. The only exception to this being if you need a quick line of Python, which is done just by having a % in front of it. Here’s what a loop would look like:
% for person in people:
<b>Hi</b><% person %>
% #end
You’ll notice an additional line is needed to indicate the end of the loop. This is because Python uses white-space to determine blocks and Myghty needs to know when the indentation is over.
Components and Inheritance
In Myghty, each template is more properly referred to as a Component. When a component is directly called as a request (or sub-request), inheritance is applied. This is how a site’s skin is typically applied. Rather than having to specify in your template that it includes or extends some other template, in Myghty your component automatically inherits from an autohandler file above it.
An easier way to think of it is to consider your template directory layout as a Class, and all the templates in it are methods. Every directory inside that root one is another Class, and so on. Theautohandler in this context acts much like your __init__ method. Here’s a little example:
# /autohandler
<html>
<head>
<title>Sitename</title>
</head>
<body>
% m.call_next()
</body>
</html>
# /index.myt
<p>Welcome to your site!</p>
When the autohandler encounters a m.call_next() command it calls the next component in the inheritance chain until eventually it gets down to the original component that was requested. It could end up going through several autohandler files on the way down to your component, each one creating sections of your site appropriate for where the component is located.
This makes life really easy if you need to move content around and have it pick up the proper “skin” for the site. The concept is also rather easy for web designers to grasp, and I’ve had no problem teaching web designers the basics they need to know about Myghty to be quickly adding sections to a website.
Methods
Of course, we have to have a way for our index.myt page to get its own title up to the autohandler which creates that section. This is where Methods become useful. Methods allow you to define (typically small) sections inside your component that can be called almost like functions, even from outside the component the method is in. If you’ve ever had to write a Python function for use in a template that has so much HTML in it you went nuts, methods will make you quite happy (more on that shortly).
/index.myt page filling in the HTML title:
# /autohandler
<html>
<head>
<title><& SELF:title &></title>
</head>
<body>
% m.call_next()
</body>
</html>
<%method title>
Your Site
</%method>
# /index.myt
<p>Welcome to your site!</p>
<%method title>
<& PARENT:title &> - Welcome Page
</%method>
The title this page will have is Your Site - Welcome Page. When calling a method, we use the same syntax as when calling another component (yes, an entire component can be called). The <&&> syntax is used, with a method we also declare the name of it following the :. Using the SELF location tells Myghty to search down the inheritance (including itself), so calling SELF:title searches down the inheritance until it comes across the most deeply nested component containing a method called title. Using PARENT searches the up looking for the first component that contains a method called title.
# /autohandler is the same as above
# /products/autohandler
% m.call_next()
<%method title>
<& PARENT:title &> - Products
</%method>
# /products/sprocket.myt
<p>Buy a sprocket, they're great....</p>
<%method title>
<& PARENT:title &> - Sprocket Details
</%method>
The title will now be Your Site - Products - Sprocket Details if you request the /products/sprocket.myt component. As I mentioned earlier, this makes it very easy to move files around as inheritance fills in so much for you.
Component Calls and Arguments
While I’m just using these methods calls for the title, the contents of a method block can contain Python code and variables as well just as our component can. In keeping with the spirit of explanation by example, here’s how we could put a sidebar in our main autohandler:
# /autohandler
<html>
<head>
<title><& SELF:title &></title>
</head>
<body>
<& /sidebar.myt &>
% m.call_next()
</body>
</html>
# /sidebar.myt
<div class="sidebar">
<ul>List of sidebar stuff</ul>
</div>
If you’ve used Rails, they call the ability to insert other components “rendering a partial”. If you’re other component needs some data that you have in your autohandler, here’s how you can pass variables into a component when you call it:
# /autohandler
<html>
<head>
<title><& SELF:title &></title>
</head>
<body>
<& /sidebar.myt, argument=variable &>
% m.call_next()
</body>
</html>
# /sidebar.myt
<h2><% argument %></h2>
<div class="sidebar">
<ul>List of sidebar stuff</ul>
</div>
<%args>
argument = "Default"
</%args>
The args block designates arguments that can be passed into the component, as well as letting you setup default arguments in case none were passed in.
Init and Python Blocks
As much as we all hate it (in a MVC context), sooner or later you need to have a chunk or two of Python code in your template. In Myghty we have several options for putting Python in our component, the most obvious is to use the% code... syntax but that quickly becomes tiresome if we have 8 lines of Python code. So we can put that in a block like so:
# /somefile.myt
<%python>
x = 10
y = 20
z = []
for a in range(1,100):
z.append(x*y+a)
</%python>
Having python blocks like that is a very common scheme in many Python template languages, but has a side-effect that can become quite irritating. It sticks you with having code through-out your template or having a large block at the top. In Myghty, there’s another block that can be defined only once in a component called an init block. It looks exactly like the above example but instead of <%python> we use <%init>.
This init block can go anywhere in your component, and I usually stick it at the very bottom. This way when designers open the page they aren’t smacked with Python code and they can just ignore the foreign language at the bottom. The init block runs before the rest of your component, so you can stick in variable initialization, import a module if you need one, etc. I’ve found this to be a great way to keep the Python bits that creep into my components out of the way.
Caching
If the rest wasn’t enough to interest you, this section and the next really start to lay on the goods. Myghty lets any component cache itself, you can cache by key as well in case there’s several different versions of a component that you wish to use. Caching a component is very useful and its very easy in Myghty.
# /index.myt
<p>Welcome to your site!</p>
<%method title>
<& PARENT:title &> - Welcome Page
</%method>
<%init>
if m.cache_self():
return
do_really_slow_stuff()
</%init>
Upon the component load, it will check to see if it has a cached version of itself on hand (and cache itself in the process otherwise), then return the output. You can cache individual parts of a component, and even cache function output (if its pickle-able). This ability makes it very easy to design a site, then go through and if sections of it take a long time, put a cache command in the parts of the page that render the slowest.
The caching system can use the file system, memory, or memcached to store data.
Multiple Component Roots
In Myghty, the directory that is searched for components is called the Component Root. An extremely powerful and more advanced function is to use multiple component roots.
Here’s what a standard configuration for Myghty would look like to define a component_root to search:
component_root = "/path/to/your/components"
Most (if not all) template languages let you specify the directory containing your templates. Myghty goes another step furthor and lets you define multiple roots:
component_root = [
{'main':"/web/sites/mysite/htdocs"},
{'components':"/web/sites/mysite/components"},
{'alt':"/usr/local/lib/special-comp"}
]
If you have multiple component roots, and you ask for /lib/view_user.myt, Myghty will search for that under each of those directories you specified to component_root.
This is a very powerful ability as you can add component roots and override other components. I cannot stress enough how useful and vital this feature is for me. It’s exceptionally useful if you want to run multiple sites with different skins, ie, co-branding your site perhaps. All you need to do is setup a new Myghty server, and configure the component roots to the other site and make a new component root for your co-branded site.
Here’s a possible config given our original site is configured as shown above:
component_root = [
{'cobrand':"/web/sites/cobrand/htdocs"},
{'main':"/web/sites/mysite/htdocs"},
{'components':"/web/sites/mysite/components"},
{'alt':"/usr/local/lib/special-comp"}
]
Now I could just create a /autohandler in the new directory, and when Myghty is searching the inheritance chain looking for autohandler’s, it loads /web/sites/cobrand/htdocs/autohandler instead of /web/sites/mysite/htdocs/autohandler. I could also specify a certain component using the key in front, main:/some/component.myt.
Using Myghty in MVC
Myghty has Sessions, Filters, Content Escaping, and some rather advanced functionality for switching buffer spaces on component output that even surpasses Mason. A further extension of the Component concept is the Module Component concept, which allows you to design your web application in the MVC paradigm with a Controller class.
The benefit of using Myghty’s MVC vs using Myghty strictly as a template language within a different MVC web application, is that you gain the ability to easily call Controllers from within a template. While you might wonder at first why you’d want to do this, it can be very useful when using AJAX and a section of a page is going to be filled in by an AJAX request. Calling the Controller for its output from the template lets you easily put in the starting content. There’s other benefits as well, my prior article on Myghty covered the other import reason, which is the Custom Resolvers ability that you wouldn’t have if a different framework is handling the request.
If this has you interested and you’d like to learn Myghty in depth, my suggestion would be to read the Mason Book while keeping the Myghty docs handy to see what the Python implementation looks like. Myghty is a very advanced template framework that handles the VC in MVC, and I’ve yet to find another template language I enjoy as much.
Python Paste Power 6
Mmm, tasty, a headline of P-word’s. Recently Ian Bicking went on a bit of a release spree with a whole bunch of goodness that I’m way too lazy to link to in this paragraph. The ones I’ve been waiting for were all in the line-up: Paste, Paste Script, and Paste Deploy. I blogged about paste and setuptools earlier and hadn’t followed up as I indicated I would partly because I was waiting on their official release.
So, what’s the big deal? Paste and its buddies solve a host of issues that commonly confront Python web developers and web administrators, the front page of Python Paste does a good job of explaining briefly why each group should care. Thus, I’ll move directly onto the fun that comes with using them.
Yes, I think its fun, but that might be just because I have a thing for installing web frameworks…. so I’ll cover using Paste as two groups of users, as a Web Developer, and as a Web Administrator.
Using Paste as a Web Developer
First off, to create a web application we need to setup a directory for the project. Since we want our web application to be Paste-enabled, the template for the web application should be using setuptools. That way when we package up our web application and give/sell it on the Internet, the people (Web Admins) using it will be able to install and run it easily.
So… lets see what framework I should use to whip up this little web application. I’ll run apaster command that lets me see what Paste-enabled web frameworks I have installed that come with new web application directory templates:
% paster create --list-templates
Available templates:
basic_package: A basic setuptools-enabled package
myghty_modulecomponents: Module Component Template
myghty_routes: Routes Template
myghty_simple: Simple Template
paste_deploy: A web application deployed through paste.deploy
pylons: Pylons application template
turbogears: TurboGear application template
Cool, right? Well, maybe its just cause I like having a big toolbelt of web frameworks sitting around. Obviously not a lot of web frameworks have paste templates available yet, but more are adding support and I’ll be rather excited when that list is 20 or more long.
If you go and install the Paste packages, your list won’t be quite as long as mine (insert evil laugh) as I’m running the CVS of Myghty (0.99 release with these templates coming shortly), along with some other stuff I’ve whipped up. Merely installing a web framework package that’s Paste-enabled and has templates available will make it show up in that list.
Another interesting thing to consider here, is that there’s no requirement that only web frameworks are allowed to create directory templates. Maybe a web application you’re working on, is so powerful you want to make it easy for end-users to extend it with their own custom add-ons. You could provide a paster template that creates a plug-in ready directory template for custom themes. There’s a ton of power packed in the various ways you can extend these tools, building on the dynamic discovery stuff in setuptools.
Moving along though, I’ll go ahead and use Turbogears.
% paster create --template=turbogears pygo
Selected and implied templates:
TurboPaste#turbogears TurboGear application template
Variables:
package: pygo
project: pygo
Creating template turbogears
Creating ./pygo/
Recursing into +package+
Creating ./pygo/pygo/
Copying __init__.py to ./pygo/pygo/__init__.py
Copying model.py to ./pygo/pygo/model.py
Recursing into templates
Creating ./pygo/pygo/templates/
Copying __init__.py to ./pygo/pygo/templates/__init__.py
Copying +package+-start.py_tmpl to ./pygo/pygo-start.py
Copying dev.cfg_tmpl to ./pygo/dev.cfg
Copying prod.cfg to ./pygo/prod.cfg
Copying setup.py_tmpl to ./pygo/setup.py
Running /opt/local/bin/python setup.py egg_info
As you can see, it just setup our new project for us, which I called pygo because it was the first name that popped into my head. If you’ve actually used TurboGears, looking at that should have raised some red flags as its missing a bunch of stuff that a TurboGears project needs. This is mainly because the template was created by Ian as a demonstration of how to make a Turbogears-style template. Hopefully an upcoming version of TurboGears will be Paste-enabled so I can create a new project like this (hint hint). :)
Ah well, I’ll just make a basic Myghty project using Routes instead:
% paster create --template=myghty_routes pygo
Selected and implied templates:
Myghty#myghty_routes Routes Template
Variables:
package: pygo
project: pygo
Creating template myghty_routes
Creating ./pygo/
...Bunch more files...
So that’s all there is to creating new projects with the web framework of your choice (if its Paste-enabled). How do we go and start it up?
~% cd pygo
~/pygo% paster serve server.conf
Starting server in PID 6090.
In the case of the myghty_routes template, it starts the server on port 5000. A quick look at the server.conf file makes it obvious:
[server:main]
use = egg:PasteScript#wsgiutils
host = 127.0.0.1
port = 5000
[app:main]
use = egg:pygo#paste
That’s really all the Paste you have to worry about as a web developer (though it has even more capabilities you’ll probably want to use). We can see here that its using wsgiutils from PasteScript to run the server. You can easily swap that out for any of the server support that flup offers such Fast CGI, SCGI, or AJP.
At this point, as a web developer, you’d go ahead and create your web application. Especially since the default myghty_routes template is pretty boring if you don’t put anything in it. But for this example, we’ll assume its done and distribute it as a single egg file for people:
~/pygo% python setup.py bdist_egg
running bdist_egg
running egg_info
... whole bunch of stuff here...
~/pygo% ls dist/
pygo-0.0.0-py2.4.egg
That’s it. This is easy, right? You’re ready to go ahead and give your egg to anyone running Python 2.4 now (You could make a source distribution and upload it to Cheese Shop just as easily). So let’s try and totally forget that we’re a web developer, and assume a different role.
Using Paste as a Web Administrator
Ah yes, the joys of setting up web applications you come across. Well, I’ve rarely gotten any joy out of it at least. Let’s take a look at how Paste does make it a lot easier. First, we’ll need to install the insanely useful Pygo webapp that some other thoughtful user created. If this Pygo application was released and uploaded to the Cheese Shop, I could install it like so:
% sudo easy_install Pygo Searching for Pygo
Reading http://www.python.org/pypi/Pygo/
Best match: Pygo 0.0
Downloading http://cheeseshop.python.org/packages/2.4/P/Pygo...
Processing pygo-0.0.0-py2.4.egg
... more stuff happens...
Installed /usr/local/lib/python2.4/site-packages/pygo-0.0.0-py2.4.egg
Processing dependencies for Pygo
Now, since I didn’t actually upload it to Cheese Shop, I’ve faked that screen. But that’s pretty close to how it would’ve looked if I had released pygo and uploaded it to Cheese Shop.
After this one command, as a web administrator, we now have the pygo application installed. There shouldn’t be any need to be installing web applications over and over for every user that wants to run it as the vast majority of web applications get their customization and settings from a database.
What needs to be configured, is the instance of the web application that each user is running. We can set that up for each user inside our Paste configuration file like so:
[server:main]
use = egg:PasteScript#flup_scgi_thread
host = 127.0.0.1
port = 3000
[composit:main]
use = egg:Paste#urlmap
/blog/fred = fredpygo
/blog/janet = janetpygo
[app:fredpygo]
use = egg:pygo
database = mysql:/username@localhost/database
[app:janetpygo]
use = egg:pygo
These configuration files are quite flexible, and allow different instances of a web application to run at different locations. In that case, one of them is running for ‘fred’ at /blog/fred. Each block for an app can have additional arguments that setup the database to use, and other settings that should probably be customized for each user. I threw in an additional database argument for one of them as an example.
Maybe you’re not a web administrator, but a web user comfortable downloading and installing many of the other webapps out there (Typo, MovableType, phpBB, etc.). Setting up your own site, using whatever Paste-enabled Python webapps you want is just as easy. Ideally ISP’s and such would just run the easyinstall command to install whatever the ‘popular’ webapps of the week are, and they can update them easily, keep old versions around if needed, etc.
Making Python Web-Application Distribution/Use Easy
This is pretty powerful stuff, and its quite easy to use. Even if you’re not making a web application with the intent to distribute it to the world, Paste is still going to help you out in a lot of ways.
An ISP or webapp end-user only needs to know how to add your webapp to their config file and installing it is a breeze thanks to setuptools. I think this has an enormous benefit for the Python web community, as it’ll significantly increase the ease of use when it comes to installing and managing web applications. Python web developers will gain some good footing to create Python Web Applications that compete with and surpass PHP webapps, especially if more ISP’s start supporting Paste-enabled applications.
Well, that’s my hope at least as I’m sure the title of this section made clear.
For the Python web framework creators out there, I like writing web applications (with various web frameworks), and I really like how easy Paste makes it to create them, package them up, and use them. Please add Paste support to your web framework, I’ll be happy to help and the Paste mail list is very responsive.
Older posts: 1 2





