Recipe for returning a file as response to a request

16 views
Skip to first unread message

Curtis

unread,
Jan 18, 2013, 2:38:20 PM1/18/13
to aspen...@googlegroups.com
I'm trying to use Aspen for some quick and dirty impedance matching between some static content and a service that is sending HTTP requests with a peculiar format.

I want to receive a request of the form "foo?x=1&y=2&z=3", pick out a file in the filesystem based on that (e.g. "1/2/3.png") and then return that as the response to the request.

Is there a recipe for loading a file and returning the contents plus mime type as the response in a simplate? I started poking through the source to see how Aspen processes requests to return static files, but then I thought I would just be lazy and ask.

Thanks,
--Curtis

Chad Whitacre

unread,
Jan 18, 2013, 3:20:10 PM1/18/13
to Curtis, aspen-users
Curtis,

So /foo is an aspen endpoint that takes a querystring? An aspen endpoint without its own file extension is going to act as a Negotiated Simplate:


Here's an untested simplate example:

--------BEGIN--------
import mimetypes
^L
filepath = '/'.join([qs['x'], qs['y'], qs['z']])
response.body = open(filepath).read()
response.headers['Content-Type'] = mimetypes.guess(filepath)
^L text/plain
--------END--------

Does that point in the right direction?

IIRC, you might even be able to skip the read and set response.body to a file-like object directly.

Since it's a negotiated simplate (and not a rendered simplate) I'm pretty sure you need the "text/plain" so-called "specline" for the so-called "content page".


chad



--
You received this message because you are subscribed to the Google Groups "aspen-users" group.
To view this discussion on the web visit https://groups.google.com/d/msg/aspen-users/-/jL9Cm5Hw8dIJ.
To post to this group, send email to aspen...@googlegroups.com.
To unsubscribe from this group, send email to aspen-users...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/aspen-users?hl=en.


Curtis Galloway

unread,
Jan 18, 2013, 6:25:09 PM1/18/13
to Chad Whitacre, aspen-users
Close, but not quite:

--------BEGIN--------
import mimetypes, os
^L
dirname = os.path.dirname(request.fs)
filepath = os.path.join(dirname, '/'.join([qs['x'], qs['y'], qs['z']]))
response.body = open(filepath, 'rb').read()
response.headers['Content-Type'] = mimetypes.guess_type(filepath)[0]
^L text/plain
--------END--------

...except that even though it's returning the contents of the file in the body of the response, the client doesn't get the data.  Hmmm.

--Curtis

Chad Whitacre

unread,
Jan 19, 2013, 4:23:10 AM1/19/13
to Curtis Galloway, aspen-users
Curtis,

Ah, right, sorry. What's happening is that the text/plain content page is clobbering the response.body that you set.

Option 1: raise response, like this:

...
response.body = foo
response.headers['Foo'] = 'bar'
raise response
^L text/plain

Option 2: use the content page, like this:

...
response.headers['Foo'] = 'bar'
^L text/plain
{{ open(filepath, 'rb').read()


Again, that's untested. Option 2 will be more performant at scale (raising is an order of magnitude slower than not), though I'm not entirely sure how option 2 will behave with the mismatch in content types. Option 1 should do the trick if option 2 doesn't work and performance isn't a driving concern.

Also, I would not expect request.fs to point to a directory. Are you sure that's right?

Lastly, you can drop to pdb inside simplates, to aid debugging. Throw this any ol' place in page 2 of your simplate:

import pdb; pdb.set_trace()


chad
Reply all
Reply to author
Forward
0 new messages