Python: Criação de uma API REST

Guia passo a passo para construir uma API REST com Flask em Python

👋 Bem-vindo à documentação da Stackhero!

A Stackhero disponibiliza uma solução Python cloud pronta a usar, concebida para simplificar o seu processo de deployment:

  • Implemente a sua aplicação em produção em segundos com um simples git push.
  • Utilize o seu próprio domínio, com configuração automática de certificado HTTPS para ligações seguras geridas por si.
  • Conte com backups automáticos, atualizações com um clique e preços previsíveis, para que se possa focar no seu código e não na gestão da infraestrutura.
  • Beneficie de elevada performance e segurança numa infraestrutura privada e dedicada. O seu ambiente está isolado e protegido.

Poupe tempo e simplifique o seu workflow: pode ter o seu código a funcionar com o alojamento Python cloud da Stackhero em apenas 5 minutos.

Este guia mostra-lhe como criar uma API REST simples utilizando Python e Flask. O Flask é um micro-framework leve que facilita a criação rápida de aplicações web e APIs.

Antes de começar, certifique-se de que tem instaladas as seguintes ferramentas:

  1. Python
  2. pip
  3. git
  4. asdf

Se precisar de ajuda para configurar o seu ambiente, consulte o guia Development platform. Em alternativa, pode começar a programar de imediato com a plataforma online Code-Hero. O Code-Hero disponibiliza um IDE e terminal online, com todas as ferramentas essenciais já instaladas. Assim, pode concentrar-se no seu código em vez de perder tempo com instalações e configurações.

API REST Python a correr no Code-Hero, acessível diretamente a partir do browserAPI REST Python a correr no Code-Hero, acessível diretamente a partir do browser

Comece por criar um novo diretório para o projeto. Neste exemplo, o projeto chama-se myRestApi:

mkdir myRestApi
cd myRestApi

Defina a versão do Python para a mais recente disponível com o asdf e inicialize um repositório Git:

asdf install python latest \
  && asdf local python latest

echo "__pycache__/" >> .gitignore

git init
git add -A .
git commit -m "First commit"

Para este exemplo, só precisa de uma dependência principal: Flask.

O Flask foi concebido para ser simples e rápido, permitindo-lhe criar e disponibilizar APIs web sem sobrecarga adicional. Inclui suporte nativo para routing, templates e gestão de pedidos HTTP, o que lhe permite passar da ideia à API funcional em poucos minutos.

Pode instalar o Flask e o python-dotenv usando o pip:

pip install Flask python-dotenv

Incluímos o python-dotenv para gerir variáveis de ambiente de forma segura e prática. Vai ver como utilizá-lo nos próximos passos.

Depois de instalar, congele as suas dependências num ficheiro requirements.txt:

pip freeze > requirements.txt

Congelar as dependências garante que todos usam as mesmas versões dos pacotes. Este pequeno passo pode poupar-lhe horas de resolução de problemas mais tarde.

Agora está pronto para escrever o código da sua API.

Crie um ficheiro chamado app.py e adicione o seguinte código:

import os
from dotenv import load_dotenv
from flask import Flask, jsonify, request

# Carregar variáveis de ambiente do .env para ambientes que não sejam de produção
if os.environ.get('ENV') != 'production':
    load_dotenv()

app = Flask(__name__)

# Dados de exemplo para tarefas
tasks = [
    {
        'id': 1,
        'title': 'Buy groceries',
        'description': 'Milk, Cheese, Pizza, Fruits',
        'done': False
    },
    {
        'id': 2,
        'title': 'Learn Python',
        'description': 'Learn Python programming basics',
        'done': False
    }
]

@app.route('/api/tasks', methods=['GET'])
def get_tasks():
    return jsonify({'tasks': tasks})

@app.route('/api/tasks/<int:task_id>', methods=['GET'])
def get_task(task_id):
    task = [task for task in tasks if task['id'] == task_id]
    if not task:
        return jsonify({'error': 'Task not found'}), 404
    return jsonify({'task': task[0]})

@app.route('/api/tasks', methods=['POST'])
def create_task():
    if not request.json or 'title' not in request.json:
        return jsonify({'error': 'Title is required'}), 400
    task = {
        'id': tasks[-1]['id'] + 1,
        'title': request.json['title'],
        'description': request.json.get('description', ""),
        'done': False
    }
    tasks.append(task)
    return jsonify({'task': task}), 201

if __name__ == '__main__':
    if os.environ.get('ENV') == 'production':
        app.run()
    else:
        app.run(host='0.0.0.0', port=8080, debug=True)

Pode iniciar o servidor com:

python app.py

Com host='0.0.0.0', a sua API fica acessível via browser quando utiliza o Code-Hero. Aceda a http://<XXXXXX>.stackhero-network.com:8080/api/tasks, substituindo <XXXXXX> pelo seu domínio Code-Hero.

Assim que o servidor estiver a correr, pode interagir com a sua API usando o cURL. Eis alguns exemplos de comandos:

  • Obter todas as tarefas:

    curl -s http://localhost:8080/api/tasks
    # Output:
    # {
    #   "tasks": [
    #     ...
    #   ]
    # }
    
  • Obter uma tarefa específica (ID 2):

    curl -s http://localhost:8080/api/tasks/2
    # Output:
    # {
    #   "task": {
    #     ...
    #   }
    # }
    
  • Criar uma nova tarefa:

    curl -s -X POST -H "Content-Type: application/json" \
    -d '{"title": "New task", "description": "Created with cURL"}' \
    http://localhost:8080/api/tasks
    # Output:
    # {
    #   "task": {
    #     ...
    #   }
    # }
    

Dica: Para uma saída mais legível, pode canalizar o resultado para o jq. Por exemplo, curl -s http://localhost:8080/api/tasks/2 | jq torna o JSON mais fácil de ler.

Exemplo de API REST Python com Flask, a correr no Stackhero Code-Hero, com o servidor (1) e o cliente a usar cURL (2)Exemplo de API REST Python com Flask, a correr no Stackhero Code-Hero, com o servidor (1) e o cliente a usar cURL (2)

As variáveis de ambiente ajudam-no a proteger segredos como credenciais de base de dados ou chaves de API. Utilizá-las mantém os dados sensíveis fora do seu código-fonte e do histórico do Git, e facilita a utilização de configurações diferentes para cada ambiente.

Para gerir variáveis de ambiente, pode usar o módulo python-dotenv. Se saltou o passo de instalação anterior, pode instalá-lo agora:

pip install python-dotenv
pip freeze > requirements.txt

Crie um ficheiro .env na raiz do seu projeto e adicione as variáveis de ambiente de desenvolvimento:

ENV="development"
DATABASE_PASSWORD="secretPassword"
THIRD_API_PRIVATE_KEY="secretKey"

Adicione .env ao seu .gitignore para garantir que não é incluído no Git:

echo ".env" >> .gitignore

Pode aceder a estas variáveis em Python usando os.environ.get():

import os

print(os.environ.get('ENV'))

O ficheiro .env destina-se apenas ao desenvolvimento. Para produção ou staging, pode definir as variáveis de ambiente diretamente no dashboard Stackhero, na configuração do seu serviço Python.

O servidor integrado do Flask é ótimo para desenvolvimento. Para produção, recomenda-se um servidor WSGI robusto como o Gunicorn. Veja como pode preparar-se:

  1. Instale o Gunicorn:

    pip install gunicorn
    pip freeze > requirements.txt
    
  2. Inicie a sua aplicação com o Gunicorn:

    ENV=production gunicorn app:app \
      --error-logfile - \
      -b 0.0.0.0:8080
    

    Aqui, app:app refere-se ao seu ficheiro (app.py) e à instância da aplicação Flask (app).

  3. Pode adicionar um Makefile para alternar facilmente entre os modos de desenvolvimento e produção:

    .DEFAULT_GOAL := dev
    
    # O Stackhero for Python executa por defeito a regra "run". Redefinimos para correr 'prod'.
    run: prod
    
    prod:
    	ENV=production gunicorn app:app \
    	  --error-logfile - \
    	  -b 0.0.0.0:8080
    
    dev:
    	python app.py
    

Pode iniciar o servidor em modo de desenvolvimento com make dev (ou simplesmente make), ou em modo de produção com make prod.

O Stackhero simplifica e torna seguro o deployment na cloud. Pode fazer deploy do seu projeto Python utilizando o serviço Python cloud hosting. As funcionalidades incluem:

  • Deployment com um simples git push
  • TLS (HTTPS) automático com domínios personalizáveis
  • Infraestrutura dedicada para segurança
  • Suporte para HTTP/2, TLS 1.3, WebSockets, GZIP & Brotli, ETag e acesso a portas TCP/UDP

Para fazer o deploy, siga estes passos:

  1. Obtenha a sua chave pública SSH:

    cat ~/.ssh/id_*.pub
    
  2. No dashboard Stackhero, abra o seu serviço "Stackhero for Python" e selecione "Configure".

  3. Cole a sua chave pública no campo "SSH public keys" ou "Key".

  4. Clique em "Validate" para confirmar a configuração.

Configuração da chave pública para "Stackhero for Python"Configuração da chave pública para "Stackhero for Python"

Se ainda não tem chaves SSH, pode gerá-las com:

ssh-keygen -t ed25519

Adicione um remote Git ao seu projeto com o comando fornecido no seu serviço Stackhero (substitua <XXXXXX> pelo domínio do seu serviço):

git remote add stackhero ssh://stackhero@<XXXXXX>.stackhero-network.com:222/project.git

Comando Git remoteComando Git remote

Quando estiver pronto para fazer deploy, envie o seu código com:

git push stackhero main

Lembre-se de fazer commit das suas alterações antes de fazer deploy. No Stackhero Code-Hero, pode usar a Command Palette (Ctrl+Shift+P ou Cmd+Shift+P) e escrever Git: Commit para commits rápidos.

Após o deployment, a sua API estará disponível em https://<XXXXXX>.stackhero-network.com/api/tasks. Substitua <XXXXXX> pelo domínio do seu serviço para aceder à sua API Flask.

Agora tem uma API REST funcional construída com Flask. Com esta base, é simples expandir a sua aplicação, ligar a bases de dados ou integrar com outros serviços. O Flask oferece-lhe a flexibilidade para evoluir de um simples protótipo para uma API de produção completa.