Friday, February 7, 2020

REST on Python Flask for API's - 1


Python has been ranked as #1 language for many years. Both in terms of job opportunities and in terms of capabilities, Python has continuously proven it's worthy a language to invest on. Although I personally prefer a pollyglot solution for enterprise, I understand the problems a polyglot person like me brings to table - Top on the list techies, tools, security, libraries/frameworks, IDE and so forth.

If you are invested into Python, no fret. You can use Flask to build REST API's and then architect your microservice layer on top of it. You certainly don't need Golang, NodeJS or Java for that.


What is Flask?

Flask is a web framework. This means flask provides you with tools, libraries and technologies that allow you to build a web application. This web application can be some web pages, a blog, a wiki or go as big as a web-based calendar application or a commercial website.
Flask is part of the categories of the micro-framework. Micro-framework are normally framework with little to no dependencies to external libraries. This is what makes Flask a great solution for Micro-services

Python 3.x for us

We'll use 3.7 and above. The language is mostly the same as Python 2.7, but many details, especially how built-in objects like dictionaries and strings work, have changed considerably, and a lot of deprecated features have finally been removed. Also, the standard library has been reorganized in a few prominent places. Here are some major changes in Python3, we should be aware of
1. Views and Iterators Instead Of Lists
2. Introducing "Classes"
3. String formatting
4. Better exception handling
5. Finally, better overall performance


What is Virtualenv?

virtualenv is a tool to create isolated Python environments. Since Python 3.3, a subset of it has been integrated into the standard library under the venv module. Note though, that the venv module does not offer all features of this library (e.g. cannot create bootstrap scripts, cannot create virtual environments for other python versions than the host python, not relocatable, etc.). Tools in general as such still may prefer using virtualenv for its ease of upgrading (via pip), unified handling of different Python versions and some more advanced features.

Why virtualenv?

The basic problem being addressed is one of dependencies and versions, and indirectly permissions. Imagine you have an application that needs version 1 of LibFoo, but another application requires version 2. How can you use both these applications? If you install everything into /usr/lib/python2.7/site-packages (or whatever your platform’s standard location is), it’s easy to end up in a situation where you unintentionally upgrade an application that shouldn’t be upgraded.

Or more generally, what if you want to install an application and leave it be? If an application works, any change in its libraries or the versions of those libraries can break the application.

Also, what if you can’t install packages into the global site-packages directory? For instance, on a shared host.

In all these cases, virtualenv can help you. It creates an environment that has its own installation directories, that doesn’t share libraries with other virtualenv environments (and optionally doesn’t access the globally installed libraries either).


PIP should be installed first. If you have not done that, check here

virtialenv Installation

pip install virtualenv

A simple Flask solution

Let's build a simple Flask application that will serve just one route
Open your terminal or command prompt and get started

  • mkdir flask-by-example && cd flask-by-example
  • virtualenv venv
  • source venv/bin/activate
  • pip install Flask
  • open VSCode/SublimeText/PyCharm/Atom or any editor of your choice and create the following files
    • app.py
    • requirements.txt
  • open app.py and stick the following code

from flask import Flask
app = Flask(__name__)


@app.route('/')
def hello():
    return "Hello World!"

@app.route('/')
def hello_name(name):
 return "Hello {}!".format(name)

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

Run the application

python app.py

You have the application running. Open browser and check to see if all work’s fine for you (http://127.0.0.1:5000/)

To know all libraries used in this application, open terminal and type following command

pip freeze > requirements.txt
T
O       Open requirements.txt and check the list of dependencies your project has. Next time you start on flask project all that you need to do is

pip install -r requirements.txt

         All your dependencies are installed from a single line. Things can't be easier and cleaner than this, can it?

As we add more modules to our application, we need to get data and other configurations from environment. During initial phase of the project most developers start to hard code these into application. It becomes a challenge to identify and remove them at a later point. Easier route is to start by setting up configuration and dependencies the right way

      Create a simple file config.py and load it with the following content 

import os
basedir = os.path.abspath(os.path.dirname(__file__))


class Config(object):
    DEBUG = False
    TESTING = False
    CSRF_ENABLED = True
    SECRET_KEY = 'this-really-needs-to-be-changed'


class ProductionConfig(Config):
    DEBUG = False


class StagingConfig(Config):
    DEVELOPMENT = True
    DEBUG = True


class DevelopmentConfig(Config):
    DEVELOPMENT = True
    DEBUG = True


class TestingConfig(Config):
    TESTING = True

As you see from the code, we create constants in config that will later be consumed from application. This is by far a better choice to take and remove some simple errors that emerge out of application in later stage. Now the next question is how to update it as env variables and how to consume it from application?



Go back to terminal and install another package

pip install autoenv

sa    Create a .env file and add the following content

export APP_SETTINGS="config.DevelopmentConfig"

      From within app.py do the following

from flask import Flask

app = Flask(__name__)
my_env = app.config.from_object(os.environ['APP_SETTINGS'])

@app.route('/')
def hello():
    return "Hello World! in {0}".format(my_env)

.......
.......    


      Now, you know how to handle all those settings you need in the application like DB String, communication with other services, location of MQ's, log files and much more.




       Next up, let's build a a simple REST API solution

No comments: