Skip to content

Instantly share code, notes, and snippets.

@defnull
Created March 13, 2012 20:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save defnull/2031499 to your computer and use it in GitHub Desktop.
Save defnull/2031499 to your computer and use it in GitHub Desktop.
Bottle ResourceManager Preview
from bottle import Bottle
app = Bottle()
# Resource configuration (relative to current file)
app.resources.add_path('./data/', base=__file__)
# Override default resources with files in test directory
app.resources.add_path('/home/marc/dev/test_data/', index=0)
# Some functions that need file resources ...
def connect_db():
db_file = app.resources.find('sqlite.db')
return sqlite3.connect(db_file)
def init_db():
with app.resources.open('schema.sql') as fp:
db = connect_db()
db.cursor().executescript(fp.read())
@uKev
Copy link

uKev commented Mar 13, 2012

I guess the difference between find() and open() is that open("somefile") means open the file in the (root directory of the app || current working directory || added ressources directory (which one?) || ????) with name "somefile" and find() will look into each subdirectory of (...) if the file is there? Doesn't sound like a good architecture for me at a first look :(.

The design bears .htaccess of apache in my mind, explained here:
http://www.cherokee-project.com/doc/other_faq.html#faq21

I think the author of the app should know which file is in which directory of his app. But maybe I just don't see it :(..

@defnull
Copy link
Author

defnull commented Mar 13, 2012

OK, some explanation is needed :)

ResourceManager.find() searches all paths in order to find the specified file and returns an absolute path. ResourceManager.open() does the same, but returns an opened file object. But they do NOT search sub-directories.

The trick is that you can work with relative paths once you tell bottle where to look for files and don't have to change the working directory or fiddle with os.path.join() all the time. And you can add additional paths if you want to add (or replace) files to/from a project.

Use-case: You download a third-party blog-application and app.mount() it onto your own application. Then you want to change some CSS or image files. With a ResourceManager you can simply add_path() a local directory, place your files there and the blog-application can find your custom files.

@uKev
Copy link

uKev commented Mar 14, 2012

Ah, that makes a lot more sense now :)! Great.

Yes, I think something like get() is better than find(). Find implies some sort of searching. Maybe get could be a bit confusing as we are in an web/http context where get has a special meaning... but I have nothing better for now. get_path() or get_abs_path may be a bit long...

hm, what about: app.ressources["schema.sql"] ?

I guess

app.resources.add_path('/home/marc/dev/', index=0)
with app.resources.open("data/schema.sql") as fp:
    pass
with app.resources.open("design/design.css") as fp:
    pass

would work too?

What about making app.resources available in every template without adding it on each returned dictionary with relative paths?
So I can do something like this in the template:

<link rel="stylesheet" href="{{ resources['static/design.css'] }}" type="text/css">

But maybe that would be a bit to much magic :).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment