1. Introducción

Hola a todos y bienvenidos al primer post de 2020 de nuestro querido blog!. En esta ocasión nos adentraremos dentro del mundo de las apis en Python mediante Flask!. Además instalaremos las dependencias necesarias para hacer uso del famoso lenguaje de consultas GraphQL. Fue desarrollado internamente por Facebook en 2012 y liberado en 2015 al resto del mundo. GraphQL es un lenguaje de consultas para apis que sustituye a REST. Entre otras cosas permite:

  • Solicitar los datos que únicamente se necesiten
  • Obtener muchos recursos en una sola petición
  • Descripción a través de un sistema de tipos

En este post crearemos un servidor a través de Flask y nos conectaremos a una base de datos MySQL a través de SQLAlchemy. Las consultas las haremos a través de Grapql.

Tecnologías empleadas:

  • Python 3.6
  • Flask 1.1.1
  • Graphene 2.1.8
  • SQLAlchemy 1.3.13
  • MySQL 5.7.29

Os podéis descargar el código de mi GitHub que se encuentra aquí.

Empezamos!

2. Instalación MySQL

Como es habitual en el blog instalamos MySQL a través de un docker-compose.

mysql:
    image: mysql:5.7.29
    volumes:
      - "./.mysql-data/db:/var/lib/mysql"
    restart: always
    ports:
      - 3306:3306
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: database
      MYSQL_USER: jorge
      MYSQL_PASSWORD: 1234

Levantamos el contenedor

$ docker-compose up

Creamos una tabla de usuarios e insertamos algunos registros

$ docker exec -it flaskgraphql_mysql_1 bash
$ mysql -h localhost -u root -P 3306 -p root
mysql> use database;
mysql> create table user(
	   id int primary key,
           name varchar(80),
           surname varchar(200),
           age int
        );
mysql> insert into user values(0, 'Jorge', 'Hernández', 30);
mysql> insert into user values(1, 'Jose', 'Hernández', 30);
mysql> insert into user values(2, 'Bárbara', 'Vázquez', 28);
mysql> insert into user values(3, 'Jose', 'Gutierrez', 33);

3. Creación virtualenv

Creamos el virtualenv e instalamos las dependencias necesarias

$ virtualenv -p python3 venv
$ source venv/bin/activate
(venv)$ pip install flask flask-graphql flask-migrate flask-sqlalchemy graphene graphene-sqlalchemy pymysql

3. Fuentes

Creamos una instancia de la clase Flask. Además establecemos la configuración para acceder a la base de datos a través de la variable de entorno SQLALCHEMY_DATABASE_URI

from flask import Flask

app = Flask(__name__)

app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://jorge:1234@localhost/database'
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True

Creamos el modelo asociado a la tabla user

from flask_sqlalchemy import SQLAlchemy

from app import app

db = SQLAlchemy(app)


class UserModel(db.Model):
    __tablename__ = 'user'

    userid = db.Column(db.Integer, primary_key=True)

    name = db.Column(db.String(256))

    surname = db.Column(db.String(256))

    age = db.Column(db.Integer)

    def __repr__(self):
        return '<User {} {} {} {}>'.format(self.id, self.name, self.surname, self.age)

Creamos el schema para GraphQL. Se instancia un objeto de la clase graphene.Schema que define las consultas que se podrán realizar. La clase SQLAlchemyConnectionField será encargada de realizar la magia!. Se encargará de componer las querys que se ejecutarán sobre el modelo UserModel a partir de las consultar realizadas.

from graphene_sqlalchemy import SQLAlchemyObjectType, SQLAlchemyConnectionField
from models import UserModel

class User(SQLAlchemyObjectType):
    class Meta:
        model = UserModel
        interfaces = (graphene.relay.Node,)

class Query(graphene.ObjectType):
    node = graphene.relay.Node.Field()
    user = SQLAlchemyConnectionField(User, name=graphene.String()) 

schema = graphene.Schema(query=Query, types=[User])

Creación de la vista a través del schema creado

from flask_graphql import GraphQLView

from app import app
from schema import schema

app.add_url_rule(
    '/graphql',
    view_func=GraphQLView.as_view(
        'graphql',
        schema=schema,
        graphiql=True
    )
)


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

arrancamos el servidor

flask run

y vamos a la uri http://localhost:5000/graphql desde la que poder hacer consultas POST sobre graphql.

4. Consultas

Obtener todos los usuarios

{
  user{
    edges{
      node{
        userid
        name
        age
      }
    }
  }
}

Resultado

5. Referencias