Python API Boilerplate

Python API using Flask, which accepts two arguments and returns one. We'll also add CORS (Cross-Origin Resource Sharing) rules to the application and then containerise it using Docker.

Python API Boilerplate

API Basic Code

Python API using Flask, which accepts two arguments and returns one. We'll also add CORS (Cross-Origin Resource Sharing) rules to the application and then containerise it using Docker.

Here is the Python Flask API with CORS:

from flask import Flask, request
from flask_cors import CORS

app = Flask(__name__)
CORS(app)

@app.route('/add', methods=['GET'])
def add():
    # Get the parameters from the request
    num1 = request.args.get('num1', type=int)
    num2 = request.args.get('num2', type=int)

    # Add the parameters
    result = num1 + num2

    return {
        'result': result
    }

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

In the above Python code, we've imported the CORS package and instantiated it passing our Flask application as an argument.

Now, let's create a Dockerfile for our application:

FROM python:3.8

WORKDIR /app

# Install requirements
COPY requirements.txt .
RUN pip install -r requirements.txt

# Copy the source code
COPY . .

EXPOSE 5000

CMD ["python", "app.py"]

This Dockerfile defines a Docker image that:

  1. Starts from the official Python 3.8 image.
  2. Sets the working directory to /app.
  3. Copies the requirements.txt file and installs any requirements.
  4. Copies the rest of the code to the image.
  5. Exposes port 5000 for the application to run on.
  6. Defines the command to start the application.

You will also need to create a requirements.txt file with our application's dependencies:

Flask==2.0.1
flask-cors==3.0.10

Once you have these files, you can build the Docker image with the following command:

docker build -t flask-api .

And then run the application with:

docker run -p 5000:5000 flask-api

With this setup, you should be able to visit http://localhost:5000/add?num1=3&num2=2 in a web browser and see the result {"result": 5}. The added CORS rules will allow requests from any origin, which you can customise according to your needs.

CORS rules

To customise the CORS rules in a Flask application, you can use the flask_cors library. This library allows you to specify which origins are allowed to make requests to your application, which HTTP methods are allowed and more.

Here's a basic example of how to use it:

from flask import Flask
from flask_cors import CORS

app = Flask(__name__)

CORS(app, resources={r"/api/*": {"origins": "*"}})

In this example, CORS is enabled for all origins ("*") for all routes that match the pattern /api/*.

If you want to allow only specific origins, you can replace * with a list of the allowed origins:

CORS(app, resources={r"/api/*": {"origins": ["http://example.com", "http://example.org"]}})

You can also specify other CORS rules. For example, you can specify which HTTP methods are allowed:

CORS(app, resources={r"/api/*": {"origins": "*", "methods": ["GET", "POST"]}})

And you can specify which headers are allowed:

CORS(app, resources={r"/api/*": {"origins": "*", "allow_headers": ["Content-Type"]}})

You can also enable CORS for specific routes only, by using the cross_origin decorator:

from flask_cors import cross_origin

@app.route("/api/data")
@cross_origin(origins=["http://example.com"])
def data():
    return {"message": "Hello, CORS!"}

In this example, CORS is enabled only for the /api/data route and only for the http://example.com origin.

Remember to replace http://example.com and http://example.org with the actual addresses of the sites you want to allow to access your Flask API.

HTTPS and Authentication

To enable HTTPS and Authentication in a Flask application, you will need to use an SSL/TLS certificate and an authentication extension like Flask-HTTPAuth or Flask-Security.

Firstly, let's enable authentication using Flask-HTTPAuth. Here's a simple example:

from flask import Flask, jsonify
from flask_httpauth import HTTPBasicAuth
from werkzeug.security import generate_password_hash, check_password_hash

app = Flask(__name__)
auth = HTTPBasicAuth()

users = {
    "john": generate_password_hash("hello"),
    "susan": generate_password_hash("bye")
}

@auth.verify_password
def verify_password(username, password):
    if username in users and \
            check_password_hash(users.get(username), password):
        return username

@app.route('/')
@auth.login_required
def index():
    return "Hello, %s!" % auth.current_user()

In the example above, we use Werkzeug's password hashing functions to securely store the users' passwords.

As for enabling HTTPS, Flask itself is a web framework and doesn't directly handle SSL. SSL is typically handled by a separate web server that routes incoming HTTPS requests to your Flask application. However, for development purposes, you can use Flask's built-in server to serve your application over HTTPS like so:

if __name__ == "__main__":
    app.run(ssl_context='adhoc')

In the code snippet above, the ssl_context='adhoc' argument makes Flask create a self-signed certificate for you.

Please note serving HTTPS directly from Flask is only recommended for development because Flask's built-in server is not designed to be particularly efficient, stable, or secure. For production applications, you should use a production-ready server like Gunicorn or uWSGI and a web server like Nginx or Apache to handle HTTPS.

Here's a simple example of how you might configure Nginx to handle SSL and forward requests to your Flask application:

server {
    listen 443 ssl;
    server_name yourdomain.com;

    ssl_certificate /etc/ssl/certs/yourdomain.com.crt;
    ssl_certificate_key /etc/ssl/private/yourdomain.com.key;

    location / {
        include uwsgi_params;
        uwsgi_pass unix:/tmp/yourapplication.sock;
    }
}

In this example, Nginx listens for HTTPS requests and forwards them to your Flask application via a Unix socket. You will need to replace yourdomain.com, /etc/ssl/certs/yourdomain.com.crt, /etc/ssl/private/yourdomain.com.key and /tmp/yourapplication.sock with your actual domain, SSL certificate, SSL key and UWSGI socket respectively.