0

Each time user accesses http://www.example.com/some-random-symbols-1x1.png, I should return transparent image 1x1px. I've created according file, but how should I read it in my code to return to the user? I know how to display the image from the datastore or blobstore. But have no idea how to read and return binary file.

It can not be static file due to the following reasons:

  1. url will contain some-random-symbols;
  2. once url is accessed, prior to displaying images, I would like to log that somebody accessed the file.
LA_
  • 19,823
  • 58
  • 172
  • 308
  • It can be static. You can have a handler that serves that image for any URL matching a given regular expression, and accesses of static files are already logged by the server. – Wooble Oct 23 '12 at 17:52
  • Thanks, @Wooble. OK, got the idea. But log is not what I need. I would like to update datastore record with the flag that the file was accessed. I think I can not do it with static files. – LA_ Oct 23 '12 at 17:54
  • You could run a cron job and run over your logs to check if it has been accessed. – bossylobster Oct 23 '12 at 18:07
  • @bossylobster, do you think this is right approach? ;) – LA_ Oct 23 '12 at 18:23
  • I think serving static files is the right approach and whatever secondary concerns you have can be accomplished asynchronously. – bossylobster Oct 23 '12 at 18:27

2 Answers2

3

A 1x1 transparent PNG (or GIF) is small enough that you can hard-code the base64 representation directly and emit it directly via self.response.write() (after decoding).

Reading from disk every time is relatively expensive. If you want to go that route, lazily initialize a global variable.

Dave W. Smith
  • 24,318
  • 4
  • 40
  • 46
  • Thanks! Based on http://stackoverflow.com/questions/5368669/convert-base64-to-image-in-python I've found how to do it. – LA_ Oct 25 '12 at 17:03
2

In a more general case, I'd use the blobstore and the BlobstoreDownloadHandler, but for a tiny gif that will definitely fit into memory, something like this to read the file's content:

with open('path/to/file.gif') as f:
  img_content = f.read()

I'd put this outside of my handler, so it was done once per instance. If you're using 2.5, then you'll need to import 'with' from future, or open and close the file yourself.

then in your handler, assuming webapp2:

self.response.content_type = 'image/gif'
self.response.write(img_content)
Greg
  • 10,350
  • 1
  • 26
  • 35
  • Greg, that works well in development environment, but doesn't work at production - I am getting `: [Errno 2] No such file or directory: 'templates/img/1x1.gif'`. Any idea how to fix that? – LA_ Oct 25 '12 at 16:57
  • is templates/img matched by one of your static routes? Files in directories that match one of the 'upload:' lines don't get deployed to the app servers (where the python runs). – Greg Oct 25 '12 at 19:22