10

I am new to python and hence falcon. I started developing a RESTful API and falcon so far is great for it. There is some other requirement to serve a static web page and I dont want to write an app or spawn a server for that.

Is it possible from the falcon app to serve the static web page?

wayfare
  • 1,802
  • 5
  • 20
  • 37
  • Not familiar with Falcon but according to this Github issue it doesn't seem that is supported: https://github.com/falconry/falcon/issues/219 – kylieCatt Jan 16 '16 at 00:13
  • 1
    Even if there is no explicit machinery in falcon nothing is stopping you from defining a route say `/static` that maps to some directory and read the file on path and return it in the response. The example in falcon docs that shows how to read and write images from the filesystem: http://falcon.readthedocs.org/en/stable/user/tutorial.html. But it isn't best practice - use the hosting webserver to serve up the static content. – AChampion Jan 16 '16 at 00:19

3 Answers3

14

First and most important, I have to say that you don't want to do that. What you should do is have a nginx server on top of your Falcon app, and serve any static file directly from nginx (and redirect the API calls to Falcon).

This being said, you can serve static files easily from Falcon. This is the code you are looking for:

import falcon


class StaticResource(object):
    def on_get(self, req, resp):
        resp.status = falcon.HTTP_200
        resp.content_type = 'text/html'
        with open('index.html', 'r') as f:
            resp.body = f.read()

app = falcon.API()
app.add_route('/', StaticResource())

You may want to set the file name as a parameter in the url, and get it in your resource, so your static resource can serve any requested file from a directory.

Marc Garcia
  • 3,287
  • 2
  • 28
  • 37
  • I like the idea of serving directly from the server. Thanks for the answer. – wayfare Jan 18 '16 at 21:58
  • 4
    Depending on how big your static content is, you might want to set `resp.stream = open('index.html', 'rb')` so that Falcon streams the file data from disk, rather than reading all of it into memory first. – Roman Levin Jul 21 '16 at 18:13
14

You should use:

api.add_static_route('/foo', foo_path)
api.add_static_route('/foo/bar', foobar_path)

Source from documentation

Peretz30
  • 1,264
  • 1
  • 11
  • 15
9

You can better control the routes to your static file like this:

import falcon
class StaticResource(object):
    def on_get(self, req, resp, filename):
        # do some sanity check on the filename
        resp.status = falcon.HTTP_200
        resp.content_type = 'appropriate/content-type'
        with open(filename, 'r') as f:
            resp.body = f.read()


app = falcon.API()
app.add_route('/static/{filename}', StaticResource())
joarleymoraes
  • 1,891
  • 14
  • 16
  • 1
    Remember to use `with open(filename, 'rb') as f:` (binary read mode) instead of `with open(filename, 'r') as f:` when publishing binary files such as jpg, zip etc. – Dirk May 09 '17 at 08:31
  • 4
    As of falcon 1.4 you can use `add_static_route`. [[changelog](https://falcon.readthedocs.io/en/stable/changes/1.4.0.html)] [[docs](https://falcon.readthedocs.io/en/stable/api/api.html#falcon.API.add_static_route)]. – nzaccardi Feb 24 '18 at 00:22