Search code examples
pythonflaskgoogle-colaboratoryfaviconngrok

How to add a favicon to a Flask route on Google colab without uploading a favicon file?


I would like to add a favicon to a route (/) on my Flask app on Google Colab, so that it will stop sending a second GET request which returns a 404.

How do I go about doing this?

I have seen various posts but they all include HTML files while I would like to do it on Google Colab itself without uploading the image every time?

import os
from flask import send_from_directory, Flask

app = Flask(__name__)
run_with_ngrok(app)  

@app.route('/')
def index():
    return '<h1>Hello!</h1>'

if __name__ == "__main__":
    app.run()

Solution

  • If you're on Google Colab and you don't want to upload or store any static HTML files or favicon.ico files, you can just return an entire HTML page from a string, then have a <head> block with a link to some favicon file.

    from flask import Flask, render_template_string
    from flask_ngrok import run_with_ngrok
    
    app = Flask(__name__)
    run_with_ngrok(app)  
    
    # Here I'm using a favicon.ico of a pizza from some random generator site
    FAVICON_URL='https://favicon-generator.org/favicon-generator/htdocs/favicons/2015-01-17/50e4281252565f8fc85151c075d4e937.ico'
    
    @app.route("/")
    def hello():
        content='Hello!'
        return render_template_string(f'''<!doctype html>
    <html>
        <head>
            <link rel="icon" href="{FAVICON_URL}">
        </head>
        <body>
            <h1>{content}</h1>
        </body>
    </html>
    ''')
    
    if __name__ == '__main__':
        app.run()  
    

    That gets rid of the 404 on /favicon (and actually displays an icon):

    using external favicon

    If you don't care about displaying an actual icon, you can try just leaving it "empty" with href="data:," as suggested in this answer from this post How to prevent favicon.ico requests?:

    @app.route("/")
    def hello():
        content='Hello!'
        return render_template_string(f'''<!doctype html>
    <html>
        <head>
            <link rel="icon" href="data:,">
        </head>
        <body>
            <h1>{content}</h1>
        </body>
    </html>
    ''')
    

    using empty favicon

    Both solutions seem to work on

    • Google Colab
    • Flask 1.1.2 and flask-ngrok 0.0.25
    • Firefox 88 and Chrome 90 on macOS

    A possible issue here is having to maintain an entire HTML page as an inline string which can be insecure and cumbersome ("Generating HTML from within Python is not fun"). I don't know how complex a web app you are planning to make. It makes sense on Google Colab, but using a setup with a static HTML file (+ Jinja templating) could be more maintainable.