This article is based on Top Python Tools for Developing Secure, Quality Code. A basic application (Hello world) will be created in flask, incorporating a series of tools that make it possible to evaluate the code, checking among other things compliance with Python's PEP8 and the security of the code. The tools and their links are shown below:
- Pipenv: Pipenv is a tool that aims to bring the best of all packaging worlds (bundler, composer, npm, cargo, yarn, etc.) to the Python world. It automatically creates and manages a virtualenv for your projects, and also adds/removes packages from your Pipfile as you install/uninstall packages.
pip install pipenv
- Safety: Safety checks your dependencies for known security vulnerabilities (Ochrona is the one recommended in the original article, but since there are no details for installing it, Safety will be used).
pip install safety
- Bandit: Bandit is a tool designed to find common security issues in Python code.
pip3 install bandit
- Black: The uncompromising Python code formatter (complying with Pep-8).
pip install black
- Mypy: Mypy is an optional static type checker for Python that aims to combine the benefits of dynamic (or "duck") typing and static typing.
pip install mypy
- pylint: Checks compliance with PEP8.
pip install pylint
- pycodestyle: Pycodestyle is a tool to check your Python code against some of the style conventions in PEP 8.
pip install pycodestyle
You can see the source code used in the article on Github.
Putting it all together
The article will use Travis-CI as the Continuous Integration tool, although any other continuous integration tool can be used. For more information about Travis-CI, here is a link to the tutorial (broken link).
File structure:
tutorialci/
├── app.py
├── .gitignore
├── Pipfile
├── .pylintrc
├── README.md
├── requirements.txt
└── .travis.yml
The necessary files are the following:
- app.py: Flask application.
- .gitignore: File that lets git ignore files or directories.
- PipFile: pipenv file.
- .pylintrc: pylint configuration file.
- README.md: readme file in markdown.
- requirements.txt: Requirements file to be used with pip (pip install -r requirements.txt).
- .travis.yml: yml file to configure travis-ci for the project.
app.py file
This file creates a web page that shows hello world.
from flask import Flask
app = Flask(__name__)
@app.route('/<nombre>')
def hola_mundo(nombre: str) -> str:
return hola_nombre(nombre)
def hola_nombre(nombre: str) -> int:
return f"hola, {nombre}"
if __name__ == '__main__':
app.run(debug=True)
Note: This code has errors on purpose in order to see how continuous integration works.
Pipfile file:
The Pipfile file has the following content:
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true
[dev-packages]
bandit = "*"
v = {editable = true,version = "*"}
black = "*"
mypy = "*"
safety = "*"
pycodestyle = "*"
pylint = "*"
[packages]
flask = "==0.12.2"
[requires]
python_version = "3.7"
It defines the package name, the packages for development (the ones mentioned above are included), then the packages required for the application to work, together with the required python version.
.pylintrc file
At the beginning the file will be empty, but its final content will be:
[MASTER]
disable=
C0111,
.travis.yml file
The travis file is in charge of the continuous integration flow; its content follows:
language: python
python:
- 3.7
install:
- pip install -U pip
- pip install pipenv
#- pip install -r requirements.txt
- pipenv install --dev
script:
- bandit ./*
- black --check .
- safety check -r requirements.txt
- mypy .
- pylint app.py
- pycodestyle app.py
It defines the programming language and its version, then the package installation procedure (note that pipenv install --dev is used to install the packages defined in Pipfile).
Github Repository
This is the github repository:
Connecting the github repository with Travis-CI
The github repository is connected to Travis-ci; the process is explained in the travis-ci (broken link) documentation.
Integration Process
The start of the continuous integration process is shown below:
errors
After committing and then pushing to github, Travis-ci shows an error in the package versions, which is solved with the following change in Pipfile:
PipFile
Bandit
The error that bandit returns is about flask running in debug mode; setting it to False solves it.
Safety
Safety did not return an error.
mypy
The Mypy errors are about type declarations.
The errors are on lines 7 and 10. The int on line 9 has to be changed to str, which would be the correct output.
PEP8 errors
- Black: Returns an error.
It says the code does not comply with the PEP8 format.
- pylint
There are errors on lines 13,1, 3,6 and 9.
The errors on lines 1, 6 and 9 are solved by putting the code C0111 in the .pylintrc file, as shown in its section.
- pycodestyle
There are errors on lines 5,9,12 and 13.
After fixing the errors, the integration returns no errors:
The final app.py file with its changes is shown below:
As you can see, the tools help you have quality code without security problems.
Make a donation! If you liked the article you can make a donation with Bitcoin (BTC) using the digital wallet of your choice to the following address: 17MtNybhdkA9GV3UNS6BTwPcuhjXoPrSzV
Or by scanning the QR code from your wallet:
