apistar: novo framework REST feito para python3

PythOnRio - Setembro - 2017

quem?

Luciano Ratamero

Python/JavaScript

lucianoratamero.github.io

fb.com/lucianoratamero

@lucianoratamero

avisos

o que é o apistar

  • framework para APIs REST
  • mais veloz que falcon
  • autodocumentado
  • documentação interativa

(aqui você já pode scrollar pro lado direito ;D)

sobre o que iremos falar

  • views
  • schemas
  • ORM
  • documentação

começando!

  • pip install apistar
    apistar new .
    apistar run

welcome

  • http://localhost:8080/
    {"message": "Welcome to API Star!"}

welcome com nome

  • http://localhost:8080/?name=lulu
    {"message": "Welcome to API Star, lulu!"}

views

  • def welcome(name=None):
        if name is None:
            return {'message': 'Welcome to API Star!'}
        return {'message': 'Welcome to API Star, %s!' % name}

routes

  • from apistar import Include, Route
    from apistar.handlers import docs_urls, static_urls
    
    routes = [
        Route('/', 'GET', welcome),
        Include('/docs', docs_urls),
        Include('/static', static_urls)
    ]
    

docs

  • http://localhost:8080/docs/

typesystem e schemas

  • from apistar import typesystem
    
    class Nota(typesystem.Integer):
        description = 'Nota pro produto'
        minimum = 1
        maximum = 5
    
    class TamanhoDeProduto(typesystem.Enum):
        description = 'Acho que esse se explica'
        enum = ['pequeno', 'normal', 'grande']

objetos complexos

  • from apistar import typesystem
    
    class Produto(typesystem.Object):
        properties = {
            'nome': typesystem.string(description='Nome, cara. Nome.', min_length=1, max_length=100),
            'nota': Nota,
            'tamanho': TamanhoDeProduto,
        }
        required = ['nome', 'nota', 'tamanho']

de volta às docs

  • http://localhost:8080/docs/

sessão do banco de dados

  • from apistar import http
    from apistar.backends.django_orm import Session
    from src import schemas
    
    def criar_produto(produto: schemas.Produto, session: Session):
        if not produto:
            return
        db_produto = session.Produto(**produto)
        db_produto.save()
        return http.Response(
            content=schemas.Produto(db_produto.__dict__),
            status=201
        )

banco de dados

  • sqlalchemy
  • django ORM

settings

  • settings = {
        'DATABASES': {
            'default': {
                'ENGINE': 'django.db.backends.sqlite3',
                'NAME': 'db.sqlite3',
            }
        },
        'INSTALLED_APPS': ['src', ]
    }

models == djangão

  • from django.db import models
    
    class Produto(models.Model):
        nota = models.PositiveSmallIntegerField()
        nome = models.CharField(max_length=100)
        tamanho = models.CharField(max_length=100)

criando tabelas == djangão

  • apistar makemigrations
    apistar migrate

de volta às docs

  • http://localhost:8080/docs/

validações customizadas

  • class CPFField(typesystem.String):
        min_length = 14
        max_length = 14
        pattern = "\d{3}\.\d{3}\.\d{3}-\d{2}"
    
        def __new__(cls, *args, **kwargs):
            cls.errors.update({'cpf_invalid': 'O CPF fornecido é inválido'})
            value = super().__new__(cls, *args, **kwargs)
            if not cpfcnpj.validate(value):
                raise TypeSystemError(cls=cls, code='cpf_invalid')
            return value

última visita às docs

  • http://localhost:8080/docs/

mas e os testes?

  • baseado em bibliotecas externas
  • pytest
  • requests
  • model_mommy

o que não deu pra falar

  • libs clientes
  • autenticação
  • templates
  • async
  • interface de linha de comando

dúvidas?

luciano@ratamero.com

cerveja/café