Executando verificação de segurança...
7

Deploy de uma aplicação Flask na Vercel (serverless)

Introdução

Se você tem uma aplicação Python saiba que a Vercel pode ser uma solução gratuita para você fazer de deploy de suas aplicações como arquitetura serverless.

  • Limitação: Se você usa Python e desenvolve para Web, provavelmente usa Django. O Django é muito vínculado ao SQL. Se você precisa migrar dados num banco de dados SQL, a Vercel não é a solução para você. Pense não é um servidor que você levanta, cria arquivo de migração e faz migração.
  • Para quem isso serve, então? Qualquer pessoa que tenha uma aplicação Python que só faz aquisições HTML, renderizar HTML, ou que tenha uma API REST, por exemplo. Irei mostrar algumas possibilidades futuramente. Mas caso queira testar algum banco para serverless vejo como facilidade usar um MongoDB e DynamoDB.

Iniciando com Flask Framework

Flask é o principal micro framework do Python para criar aplicativos Web. Apesar de ser minimalista, podemos criar, com flexibilidade, muitas aplicações.

Você pode se aprofundar no Flask olhando sua documentação. Veja também

Na aplicação criada, não serão explicados todos os detalhes, já que essa não é a finalidade. O Flask foi escolhido justamente por minimalista. Por inspeção, já conseguimos entender o básico de seu funcionamento.

Vamos lá.

Primeiros passos da nossa aplicação

O primeiro passo é ter instalado em sua máquina o Python 3 e Node.js. Se você usa Linux com Kernel recente, o Python já deve instalado.

Instalando a CLI da Vercel

Com nodejs instalado, vamos instalar a CLI da Vercel globalmente com

npm i -g vercel

Criando ambiente de desenvolvimento

Outro passo é criar um ambiente de desenvolvimento virtual para rodar o projeto. Geralmente, recomendam o uso do virtualenv, mas pode ser usado o modulo venv também.

Nesse link mostro como instalar o miniconda e criar um ambiente de desenvolvimento. A vantagem do miniconda é que podemos instalar o nodejs também.

Configurando o projeto

Vamos criar uma simples aplicação, com algumas rotas. Nada muito complicado. Teremos a estrutura recomendada pela Vercel

.
├── api
│   └── index.py
├── data
│   └── data.json
├── requirements.txt
└── vercel.json

A pasta api terá nossa aplicação Flask. A pasta data podemos colocar aquivos para serem lidos. O arquivo requirements.txt terá as dependências do nosso projeto. Por último, o arquivo vercel.json será responsável por configurar nosso projeto para subir na Vercel.

Primeiro, criaremos uma pasta para o projeto para adicionarmos esses arquivos

mkdir vercel-flask-app
cd vercel-flask-app

Na minha máquina, usei o modulo venv para criar o ambiente virtual

python3 -m venv venv
. venv/bin/activate

Se preferir o virtualenv

virtualenv venv
. venv/bin/activate

Agora com ambiente ativado podemos instalar as dependências

pip install Flask

Seguinda a estrutua proposta, abra arquivo index.py com seu editor favorito. Recomendo o VSCode, Sublime Text 3 etc.

from flask import Flask, jsonify, json
from os.path import join

# Criando um dado de teste
livros = [
  {
    "id": 0,
    "titulo": "1984",
    "autor": "George Orwell",
    "ano_publicao": "1949"
  },
  {
    "id": 1,
    "titulo": "Laranja Mecânica",
    "autor": "Anthony Burgess",
    "ano_publicao": "1962"
  },
  {
    "id": 2,
    "titulo": "Admirável Mundo Novo",
    "autor": "Aldous Huxley",
    "ano_publicao": "1932"  
  }
]

app = Flask(__name__)

@app.route('/', methods=['GET'])
def home():
    return '<h1>Página da rota Home</h1>'

@app.route('/sobre', methods=['GET'])
def about():
    return '<h1>Pagina da rota Sobre</h1>'

@app.route('/portfolio', methods=['GET'])
def portfolio():
    return '<h1>Página da rota Portfolio</h1>'

@app.route('/contato', methods=['GET'])
def contact():
    return '<h1>Página da rota Contato</h1>'

# Puxando dados de data.json e serializando
@app.route("/api/cervejas", methods=['GET'])
def api():
    with open('data/data.json', 'r') as file:
        data = json.load(file)
        return jsonify(data)

# Serializando nosso dado de teste
@app.route('/api/livros', methods=['GET'])
def api_all():
    return jsonify(livros)

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

Criamos algumas rotas. Note que a rota /api/cervejas precisa do arquivo data.json. Vamos preencher esse arquivo

[
  {
    "address_2": null,
    "address_3": null,
    "brewery_type": "planning",
    "city": "Austin",
    "country": "United States",
    "county_province": null,
    "created_at": "2018-07-24T00:00:00.000Z",
    "id": 9094,
    "latitude": null,
    "longitude": null,
    "name": "Bnaf, LLC",
    "obdb_id": "bnaf-llc-austin",
    "phone": null,
    "postal_code": "78727-7602",
    "state": "Texas",
    "street": null,
    "updated_at": "2018-07-24T00:00:00.000Z",
    "website_url": null
  },
  {
    "address_2": null,
    "address_3": null,
    "brewery_type": "regional",
    "city": "Boulder",
    "country": "United States",
    "county_province": null,
    "created_at": "2018-07-24T00:00:00.000Z",
    "id": 9180,
    "latitude": "40.026439",
    "longitude": "-105.2480158",
    "name": "Boulder Beer Co",
    "obdb_id": "boulder-beer-co-boulder",
    "phone": null,
    "postal_code": "80301-5401",
    "state": "Colorado",
    "street": "2880 Wilderness Pl",
    "updated_at": "2018-08-24T00:00:00.000Z",
    "website_url": null
  },
  {
    "address_2": null,
    "address_3": null,
    "brewery_type": "planning",
    "city": "Clermont",
    "country": "United States",
    "county_province": null,
    "created_at": "2018-07-24T00:00:00.000Z",
    "id": 9754,
    "latitude": null,
    "longitude": null,
    "name": "Clermont Brewing Company",
    "obdb_id": "clermont-brewing-company-clermont",
    "phone": null,
    "postal_code": "34711-2108",
    "state": "Florida",
    "street": null,
    "updated_at": "2018-08-11T00:00:00.000Z",
    "website_url": null
  }
]

Esses dados foram retirados de um banco de dados chamado open brewery db.

Agora no terminal

python index.py

Por padrão, o Flask utiliza a porta 5000. Então, em seguida abra o link http://127.0.0.1:5000/ no seu navegador.

Você pode verificar se todas as rotas estão funcionando

Deploy na Vercel e Serverless Functions

Vercel é uma plataforma em nuvem para sites estáticos (Jamstack) e Serverless Functions que se adapta perfeitamente ao seu fluxo de trabalho. Ele permite que os desenvolvedores hospedem sites e serviços da web com deploys instantâneos, escalados automaticamente e não requer supervisão, tudo sem configuração.

A Vercel também é o responsável pelo incrível Next.js.

Há duas formas para o deploy. Aqui mostrarei como fazer localmente. A outra forma seria usar um repositório Git (Gitlab, GitHub, BitBucket).

Lembra da estrutura de pastas?

.
├── api
│   └── index.py
├── data
│   └── data.json
├── requirements.txt
└── vercel.json

Não importando a forma de deploy, precisaremos criar um arquivo com as dependências do projeto. Para isso

pip freeze > requirements.txt

que passará todos os pacotes instalados no nosso ambiente para o arquivo requirements.txt

Agora precisaremos editar o arquivo vercel.json na raiz do projeto com as algumas informações. Esse arquivo é o responsável de explicar que temos uma aplicação Python e, se houverem, quais são suas rotas (para mais informações)

{
  "version": 2,
  "builds": [
    {
      "src": "api/index.py",
      "use": "@vercel/python"
    }
  ],
  "routes": [
    {
      "src": "/",
      "dest": "/api/index.py"
    },
    {
      "src": "/contato",
      "dest": "/api/index.py"
    },
    {
      "src": "/sobre",
      "dest": "/api/index.py"
    },
    {
      "src": "/portfolio",
      "dest": "/api/index.py"
    },
    {
      "src": "/api/cervejas",
      "dest": "/api/index.py"
    },
    {
      "src": "/api/livros",
      "dest": "/api/index.py"
    }  
  ]
}

Meio grande? Também achei.

Notou que em "routes" a chave "dest" se repete? Então vamos reduzir esse bagunça para algo mais legível

{
  "version": 2,
  "builds": [
    {
      "src": "api/index.py",
      "use": "@vercel/python"
    }
  ],
  "routes": [
    {
      "src": "/(.*)",
      "dest": "/api/index.py"
    }
  ]
}

Após isso, basta usar a CLI da Vercel. Veja as opções disponíveis com vercel --help

Vamos testar localmente (afinal, não queremos fazer deploy de algo que não funciona)

vercel dev

A saída com comando deverá ser algo como

Vercel CLI 22.0.1
? Set up and deploy “~/vercel-flask-app”? [Y/n] y
? Which scope do you want to deploy to? cauachagas
? Link to existing project? [y/N] n
? What’s your project’s name? vercel-flask-app
? In which directory is your code located? ./
Installing required dependencies...
> Building @vercel/python:api/index.py
Installing required dependencies...
> Built @vercel/python:api/index.py [14s]

E ao final, ele dá acesso ao http://localhost:3000

Para fazer o deploy da aplicação

vercel

Para produção

vercel --prod

Em todos os casos, ele mostrará um link para acessar sua aplicação.

OBS: Não estou falando sobre variáveis de ambiente. Mais caso precise, utilize o site da vercel para expor as variáveis de ambiente que sua aplicação necessita.

Se quiser acessar a aplicação

Referências

Carregando publicação patrocinada...
1
1

Que bom, irmão. Eu só reaproveitei o que estava no meu blog (jogado às moscas, porque essa era a única publicação) lá em 2021. E o legal de tudo disso é que a aplicação (final do texto) ainda tá de pé desde de 2021 kkkkkk

1

Esse foi um trabalho bem completo, muito massa!

Uma curiosidade que tive com o markdown... Cono fez o pedaço de codigo para exibir a posição das pastas , pf?

1

Como qualquer outro de código. Basta indicar o sintaxe highlight (python, JavaScript, bash). Só copiei do terminal e colei no Markdown como código bash.

0