What is Flask?
Flask is a microframework for Python based on Werkzeug, Jinja 2 and good intentions.
Flask is a microframework for Python that you can use to quickly create API’s and websites. It’s a great and easy to use platform, let’s create a simple API, but first we will go through the basics.
Flask Installation
We’re going to install Flask in our virtual environment to later import it into our code.
pipenv install flask
A basic web server
Ok, now that we have installed Flask in our virtual environment, we will create the main page, let’s create a file named api.py
and input the following code snippet.
"""Flask API."""
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
"""Return main page."""
return 'It Works!'
if __name__ == '__main__':
app.run()
That’s enough to lift our API and return It Works! in the main page.
Working with Variables
Let’s create a function to our, let’s add a salute(name)
method that accepts one argument as a name and returns 'Hello, {name}!'
"""Flask API."""
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
"""Return main page."""
return 'It Works!'
@app.route('/<name>')
def salute(name):
"""Salute someone."""
return f'Hello, {name}!'
if __name__ == '__main__':
app.run()
You can also define if a variable should be Integer, String, etc, like this:
@app.route('/<string:name>')
Here’s a reference table:
Type | Comment |
---|---|
string | Accepts a string without slashes |
int | Accepts integers |
float | For floating point value |
path | Accept strings with slashe |
any | Accepts one of the provided item |
UUID | Accepts UUID strings |
Return a JSON Encoded String
We can Jsonify a dictionary and return it to the browser as a JSON serialized data, let’s input our dog data into a dictionary and serialize it:
# -- SNIP --
@app.route('/mydog')
def get_dog():
"""Return JSON data about our dog."""
doggo = {'name': 'sam', 'food': 'meat', 'hobby': 'sleep'}
return jsonify(doggo)
And when we go to /mydog
URL we can see our serialized dictionary:
A Flask Project
Let’s create a little Flask project to warm up, shall we? We’re going to do an API that scans localhost with Nmap and return its open ports with only one method.
api.py
"""An Nmap Scanner and Parser."""
import xmltodict
from subprocess import run
from flask import Flask, jsonify
app = Flask(__name__)
@app.route('/')
def index():
"""Return the main page."""
return "Nmap Scanner, a more sofisticated page is coming soon."
@app.route('/openports')
def scan_localhost():
"""Scan a host with Nmap."""
# run nmap scan from another proccess
run(['nmap', '-T5', '--open', '-oX', 'scan.xml', 'localhost'])
# parse Nmap XML report and covert it to a dictionary
with open('scan.xml') as raw_xml:
nmap_scan = xmltodict.parse(raw_xml.read())
# Jsonify the dictionary and return it
return jsonify(nmap_scan)
if __name__ == '__main__':
app.run()
So, what are we doing here?
- Firstly, we import the libraries Flask for our API of course, we also import run from the package subprocess which allows us to run subprocesses from Python, the library xmltodict to parse XML data and convert it into a dictionary so we can return it later as a Jsonified data.
- Now we defined our route
openports
@app.route('/openports')
def scan_localhost():
"""Scan a host with Nmap."""
- Spawn a Nmap subprocess that scan our localhost looking for open ports only, we designate our XML output to
scan.xml
.
# run nmap scan from another proccess
run(['nmap', '-T5', '--open', '-oX', 'scan.xml', 'localhost'])
- We open our report
scan.xml
, convert it to a dictionary withxmltodict.parse(raw_xml.read())
and store it intonmap_scan
.
# parse Nmap XML report and covert it to a dictionary
with open('scan.xml') as raw_xml:
nmap_scan = xmltodict.parse(raw_xml.read())
- Last, but not least, we return the dictionary into a Jsonified data.
# Jsonify the dictionary and return it
return jsonify(nmap_scan)
And when we visit https://localhost/openports we can successfully see our API in action:
Of course that our code could be way, waaaaay better, but a simple example will suffice.
Remember to checkout the Flask documentation, it is immensely useful and we only scratched the surface here.