How to serve a static webpage from falcon application?
Asked Answered
M

3

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?

Machicolate answered 16/1, 2016 at 0:7 Comment(2)
Not familiar with Falcon but according to this Github issue it doesn't seem that is supported: github.com/falconry/falcon/issues/219Tonjatonjes
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: falcon.readthedocs.org/en/stable/user/tutorial.html. But it isn't best practice - use the hosting webserver to serve up the static content.Forland
L
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())
Latea answered 25/3, 2016 at 19:2 Comment(2)
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.Malacostracan
As of falcon 1.4 you can use add_static_route. [changelog] [docs].Interspace
S
15

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.

Shiftless answered 16/1, 2016 at 13:23 Comment(2)
I like the idea of serving directly from the server. Thanks for the answer.Machicolate
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.Haughty
I
14

You should use:

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

Source from documentation

Implead answered 31/1, 2018 at 13:8 Comment(1)
Note that '/foo' in this example is the query path, while 'foo_path' is the path to the files on the filesystem.Akvavit
L
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())
Latea answered 25/3, 2016 at 19:2 Comment(2)
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.Malacostracan
As of falcon 1.4 you can use add_static_route. [changelog] [docs].Interspace

© 2022 - 2024 — McMap. All rights reserved.