Archive
[flask] show external images with an app. running on localhost
Problem
I have a Flask app. that I run on my local machine. I wrote it years ago and it worked well at that time. Now, I tried to run it again but the external images didn’t appear, they were broken. These are images that are located somewhere else, I just link them. When I copied their URL and pasted in the location bar of the browser, they appeared. What da?
Solution
It seems Firefox is blocking localhost, so when I visited http://127.0.0.1:5000, some of its elements got blocked.
As a workaround, I added the following line in my /etc/hosts file:
127.0.0.1 jabba-hq
Then, when I visted http://jabba-hq:5000, the images appeared normally.
installing a Flask webapp on a Digital Ocean Ubuntu 16.04 box using Systemd
I’ve updated my Digital Ocean Flask notes on GitHub. Now it includes information about installing a Flask webapp on a Digital Ocean Ubuntu 16.04 box using Systemd.
Flask RESTful POST JSON
Problem
Using Flask-RESTful, I needed an API endpoint that accepts JSON data.
Solution
I found the solution here: http://stackoverflow.com/questions/22273671/flask-restful-post-json-fails. You can copy / paste that code. Note that the JSON data is POSTed to your API endpoint, thus you need to implement the post() method.
However, how to test it?
1) using cURL:
$ curl -i -H "Content-Type: application/json" -H "Accept: application/json" -X POST -d "{\"Hello\":\"Karl\"}" http://domain/your_api_endpoint
Damn, that’s compicated, right? Is there an easier way?
2) using httpie:
You can install httpie with your favorite package manager. Then:
$ http POST http://domain/your_api_endpoint Hello=Karl
Installing a Flask webapp on a Digital Ocean (or Linode, etc.) Ubuntu box
How to install a Flask webapp on a Digital Ocean VPS that has Ubuntu Linux on it: https://github.com/jabbalaci/DigitalOceanFlask.
This writing of mine appeared in Import Python Weekly Newsletter No. 65.
gunicorn from upstart fails to start
Today I was trying to put together these: ubuntu + nginx + gunicorn + start gunicorn from upstart + flask + virtualenv. After a whole afternoon, I managed to do it. I will write a detailed post about it, but now I just want to concentrate on one part, which was the most problematic.
Problem
I wanted to start gunicorn from upstart. So I issued the following command:
$ sudo service gunicorn start gunicorn start/running, process 21415 $ sudo service gunicorn status gunicorn stop/waiting
Each time I tried to launch it, it failed.
Solution
First of all, I didn’t know where the upstart log files were located. I know, it’s lame, but after a few hours I relized that it’d be a good idea to google it… So, the log files are in this folder:
/var/log/upstart
The log of gunicorn is here:
/var/log/upstart/gunicorn.log
Now, I started to monitor the end of this file in another terminal with “tail -f /var/log/upstart/gunicorn.log“. With this information I could easily find the error. I put here my solution and then I add some explanation:
# /etc/init/gunicorn.conf # description "Gunicorn daemon for a Flask project" start on (local-filesystems and net-device-up IFACE=eth0) stop on runlevel [!12345] # If the process quits unexpectadly trigger a respawn respawn setuid demo setgid demo script . "/home/demo/.virtualenvs/myproj/bin/activate" cd /home/demo/projects/myproj/api exec gunicorn --name="my project" --bind=127.0.0.1:9000 --config /etc/gunicorn.d/gunicorn.py api:app --pid=gunicorn_from_nginx.pid end script
And you know what caused the problem? Instead of “.” I tried to use “source”. This is what I found in every tutorial. But as it turned out, this script is executed with “/bin/sh“, not with “/bin/bash“, and sh doesn’t know source. Geez…
The normal user on this machine is called “demo“. My Flask project is within a virtual environment. You can create a script block and the steps within are executed with “sh”. So first we “source” the virtual environment, then enter the directory where the Python script to be executed is located (here “api” is the name of the folder, and in there I have a file called “api.py“, which contains the “app” variable). gunicorn is also installed in the virtual environment! You don’t need to install it globally with “sudo“!
Nginx is listening on port 80 and every connection that arrives there are forwarded to this gunicorn instance on port 9000. But I’ll write about it a bit later.
Appendix
The content of “/etc/gunicorn.d/gunicorn.py“:
"""gunicorn WSGI server configuration."""
from multiprocessing import cpu_count
from os import environ
def max_workers():
return cpu_count() * 2 + 1
max_requests = 1000
worker_class = 'gevent'
workers = max_workers()
pretty JSON output with Flask-RESTful
Problem
Flask-RESTful is an awesome way to write REST APIs. In debug mode, its output is nicely indented, easy to read. However, in production mode the JSON is compressed and hard to read.
If debug is False, how to have a nicely formatted output?
Solution
from flask import Flask
from flask_restful import Api
app = Flask(__name__)
api = Api(app)
if production:
print("# running in production mode")
HOST = '0.0.0.0'
DEBUG = False
# START: temporary help for the UI developers, remove later
settings = app.config.get('RESTFUL_JSON', {})
settings.setdefault('indent', 2)
settings.setdefault('sort_keys', True)
app.config['RESTFUL_JSON'] = settings
# END
else:
print("# running in development mode")
HOST='127.0.0.1'
DEBUG = True
# ...
if __name__ == '__main__':
app.run(debug=DEBUG, host=HOST, port=1234)
Note that here I use the development server shipped with Flask, which is not suitable for real production. So this solution is between development and production.
[flask] render a template and jump to an anchor
Problem
You render a page but you want to jump to an anchor on the rendered page.
Solution
Here is a route:
@app.route('/about/')
def fn_about():
return render_template('about.html')
In the view add this (assuming you have jQuery):
<script> $(function(){ window.location.hash = "jump_here"; }); </script>
It’ll run once the HTML is loaded. Found it here.
[flask] validate a URL
Problem
In a Flask application I wanted to verify if a user-given URL is valid.
Solution
I found a simple validator package for that called validators (see it on GitHub).
Sample usage:
$ pip install validators
$ python
>>> import validators
>>> url = "http://index.hu"
>>> validators.url(url)
True
>>> url = "http://index.h/"
>>> validators.url(url)
ValidationFailure(func=url, args={'value': 'http://index.h/', 'require_tld': True})
The ValidationFailure class implements the __bool__ method, so you can easily check if validation failed:
if not validators.url(url):
flash("Error: you must provide a valid URL!")
Flask: linkify a text
Problem
I have a text that I present in a Flask application. The text can contain URLs, and I would like to linkify them, i.e. make them clickable links. Example:
before:
visit http://google.com for...
after:
visit <a href="http://google.com">http://google.com</a> for...
Solution
Before rolling out an own solution, it’s a good idea to check if there is a package for this problem. There is :), and it’s called bleach. Its usage couldn’t be simpler:
>>> import bleach
>>> bleach.linkify('an http://example.com url')
u'an <a href="http://example.com" rel="nofollow">http://example.com</a> url
Flask integration
In your main file (that calls app.run()) add the following filter:
import bleach
@app.template_filter('linkify')
def linkify(s):
return bleach.linkify(s)
Then use it in your jinja2 templates:
Description: {{ entry.description|linkify|safe }}
Warning! Apply the “safe” filter only if you trust the origin of the text you want to present in a linkified format.

You must be logged in to post a comment.