[cherrypy-users] Setting up static directories...

430 views
Skip to first unread message

Omega

unread,
Apr 18, 2010, 8:10:42 PM4/18/10
to cherrypy-users
Hello all!

I'm just getting started with cherrypy and I'm really impressed with
what it has to offer! That said, there is a definite learning curve
to get my head around the lifecycle of cherrypy itself and how I
should build my applications up with it.

The first hurdle I'm at is setting up static dirs.... I have the
following source code structure:

/mycode
/mywebserver
myMainScript.py
Config
/CSS
myCSS.css

I want to host the CSS directory, so I have the following:

[global]
server.socket_port = 8080
server.thread_pool = 10
tools.sessions.on = True
tools.staticdir.on = True

[/CSS]
tools.staticdir.on = True
tools.staticdir.dir = "CSS"

Obviously this isn't working, but I can't quite figure out how the
static hosting works from the documentation. It is full of code
examples, but the explanatory text doesn't help me understand how
these directives are working or what contexts they should be used
from.

I know when I run my program it is executing from the mywebserver
package-directory. It is also finding the Config script without issue
when I tell it to simply load "Config" (with no path, thus in the
current directory). But it seems like my instructions to host CSS
aren't quite working.
Another point is that I am trying to write an application where the
current working directory is the context to serve from. I have had no
luck gleaning what the best convention is here and would love some
direction on that as well.

This is all really just me getting a handle on how cherrypy sees
itself and all the different logical concepts I need to absorb before
structuring apps around them. Thanks for any help!

--
You received this message because you are subscribed to the Google Groups "cherrypy-users" group.
To post to this group, send email to cherryp...@googlegroups.com.
To unsubscribe from this group, send email to cherrypy-user...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/cherrypy-users?hl=en.

steve

unread,
Apr 19, 2010, 10:33:49 AM4/19/10
to cherryp...@googlegroups.com, Omega
Hi,

On 04/19/2010 05:40 AM, Omega wrote:
> Hello all!
>
> [...snip...]
> The first hurdle I'm at is setting up static dirs.... I have the
> following source code structure:
>
> /mycode
> /mywebserver
> myMainScript.py
> Config
> /CSS
> myCSS.css
>
> I want to host the CSS directory, so I have the following:
>
> [global]
> server.socket_port = 8080
> server.thread_pool = 10
> tools.sessions.on = True
> tools.staticdir.on = True
>
> [/CSS]
> tools.staticdir.on = True
> tools.staticdir.dir = "CSS"
>
> Obviously this isn't working, but I can't quite figure out how the
> static hosting works from the documentation.

This is a source of some confusion and I think that although the current
documentation ...

http://www.cherrypy.org/wiki/StaticContent

...does mention it, IMHO, the source of confusion is not as emphasized as it
should be.

Anyways, here's the problem:

a. You should specify:

tools.staticdir.root = "/mycode/mywebserver/" under the section "[/]" which
informs cherrypy that all your static stuff is under that directory

b. You can then refer to your css directory in relative terms to the root:
ie:

[/CSS]
tools.staticdir.on = True
tools.staticdir.dir = 'CSS'

OR

a. You can choose not to set up a 'tools.staticdir.root', in which case you give
the absolute path name to your tools.staticdir.dir. ie:

[/CSS]
tools.staticdir.on = True
tools.staticdir.dir = '/mycode/mywebserver/CSS'


Let us know if either of these work for you.

cheers,
- steve

--
random new spiel: http://lonetwin.net/
random old spiel: http://lonetwin.blogspot.com/
what i'm stumbling into: http://lonetwin.stumbleupon.com/

Omega

unread,
Apr 19, 2010, 12:05:58 PM4/19/10
to cherrypy-users
Thanks for such a quick response! I opted for the second option.
Here's a summary of what happened:

[global]
server.socket_port = 8080
server.thread_pool = 10
tools.sessions.on = True

[/CSS]
tools.staticdir.on = True
tools.staticdir.dir = "/home/myusername/CSS"


(/home/myusername/CSS exists with one file underneath it, and as I'm
running the server as myself, I should have permissions)

When I navigate to:
localhost:8080/CSS/
or
localhost:8080/CSS

I get:

404 Not Found

The path '/CSS' was not found.

Traceback (most recent call last):
File "/usr/local/lib/python2.6/dist-packages/CherryPy-3.1.2-
py2.6.egg/cherrypy/_cprequest.py", line 606, in respond
cherrypy.response.body = self.handler()
File "/usr/local/lib/python2.6/dist-packages/CherryPy-3.1.2-
py2.6.egg/cherrypy/_cperror.py", line 227, in __call__
raise self
NotFound: (404, "The path '/CSS' was not found.")
Powered by CherryPy 3.1.2


I'm assuming at this point cherrypy doesn't support specifying
directories relative to the current working directory, and that at
some point in time, a full path off of the root must be specified
(either for individual directories, or after a base path is defined).


This next part can possibly qualify as a new discussion:
Is is common/advisable for cherrypy apps to contain the actual content
of a web site within the python package structure? I'm still confused
as to if and when python code and content/templates should break away
from each other and be stored separately.

Right now I have a base server which will wrap cherrypy, my database
and templating into an MVC. To create sites, I will simply
instantiate that web server and either instantiate default controller
classes, or subclass them for specific functionality.

This general server life cycle concept is often the first and biggest
hurdle to get over before I'm cruising ;)

Thanks again!

Voltron

unread,
Apr 19, 2010, 12:32:12 PM4/19/10
to cherrypy-users
1. Install firebug to debug the 404s that you are getting(http://
getfirebug.com/)
2. Use the cherrypy.url() function to build URLs to your static
content

I dont really understand what you mean by all your website content,
but Cherrypy supports MVC, this is how I structure some of my sites

site/
/controllers
/templates
/static
/tests
/forms

Import the modules and functions you need page handlers

Voltron

unread,
Apr 19, 2010, 12:39:38 PM4/19/10
to cherrypy-users
i meant:

import the modules and other code you need in your page handlers

Omega

unread,
Apr 19, 2010, 1:46:18 PM4/19/10
to cherrypy-users
I don't think the 404 I'm getting is browser related, both Chromium
and Firefox are giving me the same result. I do have firebug
installed, but nothing seems amiss here with the browsers. Looking at
cherrypy's debug outout, I can see that it is emitting the 404:

127.0.0.1 - - [19/Apr/2010:12:39:49] "GET /CSS HTTP/1.1" 404 1096 ""
"Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/533.6 (KHTML,
like Gecko) Chrome/5.0.379.0 Safari/533.6"

As I'm still new to cherrypy, I'm not sure if the error it's giving is
meaningful or not? It's saying the path "/CSS" was not found, but as
I've defined a config file, this doesn't make sense.


Also...
Your structure is great and nearly identical to what I would be
looking to make! My questions after that tie into how you load
classes and how do you bootstrap such a setup. Where does your actual
MVC code live and how does it call upon the different components? In
my PHP days, I was very focused on dynamic class loading for my MVC.
Given cherrypy allows you to explicitly map instances to URLs, it's a
little different.

In your example, is the controllers directory a python package? Where
are you actually running the web server? Is there a second body of
code that makes up "your MVC engine" which you just point to directory
structures like the one you mentioned? How do you configure it and
how do you load the controllers?

It's little things like that where I'm trying to make something
structured, that doesn't turn into a mess later on. It's one thing to
just crack open a text editor and dump code into files. But it's
another to have a more overarching design.

I really appreciate you taking the time to answer my questions, rest
assured I'm taking it all in!

steve

unread,
Apr 20, 2010, 5:16:16 AM4/20/10
to cherryp...@googlegroups.com, Omega
Hi,
On 04/19/2010 11:16 PM, Omega wrote:
> I don't think the 404 I'm getting is browser related, both Chromium
> and Firefox are giving me the same result. I do have firebug
> installed, but nothing seems amiss here with the browsers. Looking at
> cherrypy's debug outout, I can see that it is emitting the 404:
>
> 127.0.0.1 - - [19/Apr/2010:12:39:49] "GET /CSS HTTP/1.1" 404 1096 ""
> "Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/533.6 (KHTML,
> like Gecko) Chrome/5.0.379.0 Safari/533.6"
>
> As I'm still new to cherrypy, I'm not sure if the error it's giving is
> meaningful or not? It's saying the path "/CSS" was not found, but as
> I've defined a config file, this doesn't make sense.
>
What happens when you request for the file within '/CSS' rather than '/CSS' itself ?

I am willing to bet that you will get that file. By default, cherrypy will not
serve up the directory index if you request for a staticdir path (how is it
supposed to know that's what it is supposed to do ?). If you do need directory
indexes here is how to do it:

http://tools.cherrypy.org/wiki/staticdirindex

An alternate way would be to define a 'default' method:
http://www.cherrypy.org/wiki/CherryPyTutorial#Partialmatchesandthedefaultmethod

but, if i'm not mistaken, you'd have to define the tools.staticdir.root as the
top level of your app (ie: under section [/]) for this to work correctly (the
approach (a) that I mentioned in my earlier reply).

>
> Also...
> Your structure is great and nearly identical to what I would be
> looking to make! My questions after that tie into how you load
> classes and how do you bootstrap such a setup. Where does your actual
> MVC code live and how does it call upon the different components? In
> my PHP days, I was very focused on dynamic class loading for my MVC.
> Given cherrypy allows you to explicitly map instances to URLs, it's a
> little different.
>
I would recommend that you read up a bit here:
http://www.cherrypy.org/wiki/CherryPyTutorial#Findingthecorrectobject

cherrypy's object mapping is fairly simple and intuitive. Don't assume it is
overly complicated. You decided where you want to 'mount' your application root
and all components under it by specifying this in the config.


> In your example, is the controllers directory a python package? Where
> are you actually running the web server? Is there a second body of
> code that makes up "your MVC engine" which you just point to directory
> structures like the one you mentioned? How do you configure it and
> how do you load the controllers?
>
> It's little things like that where I'm trying to make something
> structured, that doesn't turn into a mess later on. It's one thing to
> just crack open a text editor and dump code into files. But it's
> another to have a more overarching design.
>
I'd suggest that you describe what it is that you are trying to do, independent
of cherrypy (ie: describe the design/structure of your app) and we could
possibly help map that to a cherrypy app.

Omega

unread,
Apr 20, 2010, 8:56:15 PM4/20/10
to cherrypy-users
Apologies, in trying to zero in on my description, I've not only
become obscure, but also come up with answers and more questions along
the way!

Now that I have a better handle on how I want to use my cherrypy-based
server and the details of my web app code, I've realized that I don't
need to specify static directories in the configuration (more on that
later).
I've definitely taken the time to understand how cherrypy maps paths
to the instances I provide (a graph of objects). But of course, this
presumes that you have defined this graph somewhere. Which won't at
all be the case for me as that implies some sort of map that needs to
be maintained. Knowing how cherrypy checks its options before giving
a 404, what I appear to want is a single class which will perform all
my standard response-building operations based on the URL.
Understanding that this is what I wanted was likely my first point of
confusion as I'm new to cherrypy. I'm sure where we can all see where
this is going now though, I'm making an MVC! *groan*



What I've gotten started with so far is:
o Devising my own "web app" structure and starting my web server in
the web app's directory.
o Adding the "Controllers" subdirectory of the cwd to the python
search path.
o Adding a "Static" subdirectory of the cwd to be hosted as "http://
host/Static".
o Create the handler class which is an object with a default(self,
*args, **kwargs) method defined. I assign this as the root to capture
all unhandled requests.
o In my handler, I can infer everything about the path requested.
- Load the according module in the "Controllers" subdirectory,
containing a like-named class and instantiate the class.
- Use a similar method to pick a template (once I've settled
on a templating engine).
- Invoke the method on the class, passing a reference to the
template and database.
- Invoke the template's render method to generate output.
- (gracefully handle missing controllers or templates allowing
for template-less or controller-less responses)


So I guess my current questions now are:
o How do I instruct cherrypy through code (and not its configuration
file) to statically host a directory in it's entirety?
o Is there a way to tell cherrypy to continue it's normal routine for
handling on one of my controller classes that have been dynamically
loaded above? Or am I forced to sniff out and invoke the methods
myself at this point (not a pain, just avoiding reinventing the
wheel)?


I'll try to preempt at least two questions...
o With dynamic module loading, I'm restricting it to modules found in
the Controllers dir, so hopfully this doesn't raise anyones' security
hairs. It will always be jailed to "./Controllers/Hahaha.py".
o "Why?" or "Why not use rails?" For the purposes of what I plan on
using this application engine for, I'm interested in using zodb, which
is python only. Coming from PHP, cherrypy seemed like a natural fit
for me given it's very tight abstraction of the HTTP request/response
lifecycle. I'm simply trying to shore it up with an easy and portable
web application structure based on all the different components I'm
gluing together.

Actually, to be honest, I'm floored by how potent cherrypy is in this
regard. If my current approach is sane, cherrypy makes URL rewriters
look as complex and nuanced as JCL! ;)

If I've missed anything, I'll post it after this response. Hopefully
this gives you a better idea of what I've got swirling around in my
head!




On Apr 20, 4:16 am, steve <st...@lonetwin.net> wrote:
> Hi,
> On 04/19/2010 11:16 PM, Omega wrote:> I don't think the 404 I'm getting is browser related, both Chromium
> > and Firefox are giving me the same result.  I do have firebug
> > installed, but nothing seems amiss here with the browsers.  Looking at
> > cherrypy's debug outout, I can see that it is emitting the 404:
>
> > 127.0.0.1 - - [19/Apr/2010:12:39:49] "GET /CSS HTTP/1.1" 404 1096 ""
> > "Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/533.6 (KHTML,
> > like Gecko) Chrome/5.0.379.0 Safari/533.6"
>
> > As I'm still new to cherrypy, I'm not sure if the error it's giving is
> > meaningful or not?  It's saying the path "/CSS" was not found, but as
> > I've defined a config file, this doesn't make sense.
>
> What happens when you request for the file within '/CSS' rather than '/CSS' itself ?
>
> I am willing to bet that you will get that file. By default, cherrypy will not
> serve up the directory index if you request for a staticdir path (how is it
> supposed to know that's what it is supposed to do ?). If you do need directory
> indexes here is how to do it:
>
> http://tools.cherrypy.org/wiki/staticdirindex
>
> An alternate way would be to define a 'default' method:http://www.cherrypy.org/wiki/CherryPyTutorial#Partialmatchesandthedef...

Omega

unread,
Apr 21, 2010, 10:10:42 PM4/21/10
to cherrypy-users
I'm currently slogging through http://www.cherrypy.org/wiki/CherryPySpec
and I've noticed the section on dispatchers.

Could what I'm creating be considered a somewhat customized
dispatcher? Is there a more preferred method for creating a
dispatcher than what I'm currently doing? Also, is there a way to
invoke the default cherrypy dispatcher (or portions of it) manually?
Say, after I've located my class, I wish to have cherrypy apply it's
default routines to locate the callable on an instance of it...?

Onward!
Reply all
Reply to author
Forward
0 new messages