Tutorial

Como processar dados de solicitação de entrada no Flask

Published on March 19, 2021
author

Anthony Herbert

Português
Como processar dados de solicitação de entrada no Flask

Introdução

Muitas vezes, os aplicativos Web necessitam do processamento dos dados de solicitação da entrada de usuários. Essa carga pode existir na forma de strings de consulta, dados de formulário e objetos JSON. O Flask, assim como qualquer outro framework Web, permite acessar os dados de solicitação.

Neste tutorial, será construído um aplicativo Flask com três rotas que aceitam strings de consulta, dados de formulário ou objetos JSON.

Pré-requisitos

Para completar este tutorial, você precisará de:

  • Este projeto exigirá o Python instalado em um ambiente local.
  • Este projeto usará o Pipenv, uma ferramenta pronta para a produção que visa trazer o melhor de todos os mundos do empacotamento ao mundo do Python. Ele tira proveito do Pipfile, pip e o virtualenv em um único comando.
  • Baixar e instalar uma ferramenta como o Postman será necessário para testar os pontos de extremidade da API.

Este tutorial foi verificado com o Pipenv v2020.11.15, Python v3.9.0 e o Flask v1.1.2.

Configurando o projeto

Para demonstrar as diferentes formas de usar solicitações, será necessário criar um aplicativo Flask. Embora o aplicativo de exemplo use uma estrutura simplificada para as funções de visualização e rotas, o que você aprenderá neste tutorial pode ser aplicado a qualquer método para organizar suas visualizações, como as visualizações baseadas em classe, blueprints, ou uma extensão como o Flask-Via.

Primeiramente, será necessário criar um diretório de projeto. Abra seu terminal e execute o seguinte comando:

  1. mkdir flask_request_example

Em seguida, navegue até o novo diretório:

  1. cd flask_request_example

Em seguida, instale o Flask. Abra seu terminal e execute o seguinte comando:

  1. pipenv install Flask

O comando pipenv criará um virtualenv para este projeto, um Pipfile, e também instalará o flask e um Pipfile.lock.

Para ativar o virtualenv do projeto, execute o seguinte comando:

  1. pipenv shell

Para acessar os dados de entrada no Flask, é necessário usar o objeto request (solicitação). O objeto request contém todos os dados de entrada da solicitação, que inclui o tipomime, referenciador, endereço IP, dados brutos, método HTTP, cabeçalhos, entre outras coisas.

Embora todas as informações contidas no objeto request possam ser úteis, para os fins deste artigo, você se concentrará nos dados que são normalmente fornecidos diretamente pelo chamador do ponto de extremidade.

Para ter acesso ao objeto request no Flask, será necessário importá-lo da biblioteca do Flask:

from flask import request

Depois disso, você pode usá-lo em qualquer uma das suas funções de visualização.

Use seu editor de código para criar um arquivo app.py. Importe o Flask e o objeto request. Além disso, estabeleça rotas para query-example, form-example e json-example:

app.py
# import main Flask class and request object
from flask import Flask, request

# create the Flask app
app = Flask(__name__)

@app.route('/query-example')
def query_example():
    return 'Query String Example'

@app.route('/form-example')
def form_example():
    return 'Form Data Example'

@app.route('/json-example')
def json_example():
    return 'JSON Object Example'

if __name__ == '__main__':
    # run app in debug mode on port 5000
    app.run(debug=True, port=5000)

Em seguida, abra seu terminal e inicie o aplicativo com o seguinte comando:

  1. python app.py

O aplicativo será iniciado na porta 5000. Sendo assim, você pode visualizar cada rota no seu navegador com os seguintes links:

http://127.0.0.1:5000/query-example (or localhost:5000/query-example)
http://127.0.0.1:5000/form-example (or localhost:5000/form-example)
http://127.0.0.1:5000/json-example (or localhost:5000/json-example)

O código estabelece três rotas e visitar cada rota exibirá as mensagens de "Query String Example", "Form Data Example" e "JSON Object Example", respectivamente.

Usando argumentos de consulta

Os argumentos de URL que você adiciona a uma string de consulta representam uma maneira comum de passar dados para um aplicativo Web. Enquanto navegava na Web, você provavelmente já se deparou com uma string de consulta antes.

Uma string de consulta se assemelha ao seguinte:

example.com?arg1=value1&arg2=value2

A string de consulta começa após o caractere de ponto de interrogação (?):

example.com?arg1=value1&arg2=value2

E possui pares de chave-valor separados por um caractere de E comercial (&):

example.com?arg1=value1&arg2=value2

Para cada par, a chave é seguida de um caractere de sinal igual (=) e então o valor.

arg1 : value1
arg2 : value2

As strings de consulta são úteis para passar dados que não exigem que o usuário tome nenhuma ação. Se quiser, é possível gerar uma string de consulta em algum lugar do seu aplicativo e adicioná-la a uma URL para que quando um usuário fizer uma solicitação, os dados sejam automaticamente passados a eles. Uma string de consulta também pode ser gerada por formulários que têm o GET como método.

Vamos adicionar uma string de consulta à rota query-example. Neste exemplo hipotético, você adicionará o nome de uma linguagem de programação que será exibido na tela. Crie uma chave "language" e um valor de "Python":

http://127.0.0.1:5000/query-example?language=Python

Se executar o aplicativo e navegar até essa URL, você verá que ele ainda exibe uma mensagem de "Query String Example".

Será necessário programar a parte que lida com os argumentos de consulta. Esse código lerá a chave language usando o request.args.get('language') ou request.args['language'].

Se chamarmos o request.args.get('language'), o aplicativo continuará em execução se a chave language não existir na URL. Neste caso, o resultado do método será None.

Se chamarmos o request.args['language'], o aplicativo retornará um erro 400 se a chave language não existir na URL.

Ao lidar com strings de consulta, é recomendável usar o request.args.get() para evitar que o aplicativo falhe.

Vamos ler a chave language e exibi-la como um resultado.

Modifique a rota query-example no app.py com o seguinte código:

app.py
@app.route('/query-example')
def query_example():
    # if key doesn't exist, returns None
    language = request.args.get('language')

    return '''<h1>The language value is: {}</h1>'''.format(language)

Em seguida, execute o aplicativo e navegue até a URL:

http://127.0.0.1:5000/query-example?language=Python

O navegador exibirá a seguinte mensagem:

Output
The language value is: Python

O argumento da URL é atribuído à variável language e então é retornado ao navegador.

Para adicionar mais parâmetros à string de consulta, adicione caracteres & e os novos pares de chave-valor no final da URL. Crie uma chave “framework” e um valor de ”Flask”:

http://127.0.0.1:5000/query-example?language=Python&framework=Flask

E se quiser ainda mais, continue adicionando caracteres & e pares de chave-valor. Crie uma chave “website” e um valor de ”DigitalOcean”:

http://127.0.0.1:5000/query-example?language=Python&framework=Flask&website=DigitalOcean

Para ter acesso a esses valores, você ainda usará o request.args.get() ou request.args[]. Vamos usar ambos para demonstrar o que acontece quando uma chave estiver faltando. Modifique a rota query_example para atribuir o valor dos resultados às variáveis e então exibi-las:

@app.route('/query-example')
def query_example():
    # if key doesn't exist, returns None
    language = request.args.get('language')

    # if key doesn't exist, returns a 400, bad request error
    framework = request.args['framework']

    # if key doesn't exist, returns None
    website = request.args.get('website')

    return '''
              <h1>The language value is: {}</h1>
              <h1>The framework value is: {}</h1>
              <h1>The website value is: {}'''.format(language, framework, website)

Em seguida, execute o aplicativo e navegue até a URL:

http://127.0.0.1:5000/query-example?language=Python&framework=Flask&website=DigitalOcean

O navegador exibirá a seguinte mensagem:

Output
The language value is: Python The framework value is: Flask The website value is: DigitalOcean

Remova a chave language da URL:

http://127.0.0.1:5000/query-example?framework=Flask&website=DigitalOcean

O navegador exibirá a mensagem a seguir. O valor None é utilizado se um valor não for fornecido para language:

Output
The language value is: None The framework value is: Flask The website value is: DigitalOcean

Remova a chave framework da URL:

http://127.0.0.1:5000/query-example?language=Python&website=DigitalOcean

O navegador deve encontrar um erro porque está esperando um valor para framework:

Output
werkzeug.exceptions.BadRequestKeyError werkzeug.exceptions.BadRequestKeyError: 400 Bad Request: The browser (or proxy) sent a request that this server could not understand. KeyError: 'framework'

Agora, você sabe como manusear strings de consulta. Vamos continuar para o próximo tipo de dados de entrada.

Usando dados de formulários

Os dados de formulário vêm de um formulário que foi enviado como uma solicitação POST para uma rota. Assim, ao invés de ver os dados na URL (exceto para casos quando o formulário for enviado com uma solicitação GET), os dados do formulário serão passados para o aplicativo em segundo plano. Embora os dados de formulário que são passados não possam ser facilmente vistos, seu aplicativo ainda pode lê-los.

Para demonstrar isso, modifique a rota form-example no app.py para aceitar tanto as solicitações GET quanto POST e retornar um formulário:

app.py
# allow both GET and POST requests
@app.route('/form-example', methods=['GET', 'POST'])
def form_example():
    return '''
              <form method="POST">
                  <div><label>Language: <input type="text" name="language"></label></div>
                  <div><label>Framework: <input type="text" name="framework"></label></div>
                  <input type="submit" value="Submit">
              </form>'''

Em seguida, execute o aplicativo e navegue até a URL:

http://127.0.0.1:5000/form-example

O navegador exibirá um formulário com dois campos de entrada — um para language e um para framework — e um para o botão de enviar.

A coisa mais importante para saber sobre este formulário é que ele executa uma solicitação POST na mesma rota que gerou o formulário. Todas as chaves que serão lidas no aplicativo vêm dos atributos name em nossas entradas de formulários. Neste caso, language e framework são os nomes das entradas. Sendo assim, você terá acesso a eles no aplicativo.

Dentro da função de visualização, será necessário verificar se o método de solicitação é o GET ou POST. Se for uma solicitação GET, você pode exibir o formulário. Caso contrário, se for uma solicitação POST, então será preciso processar os dados de entrada.

Modifique a rota form-example no app.py com o seguinte código:

app.py
# allow both GET and POST requests
@app.route('/form-example', methods=['GET', 'POST'])
def form_example():
    # handle the POST request
    if request.method == 'POST':
        language = request.form.get('language')
        framework = request.form.get('framework')
        return '''
                  <h1>The language value is: {}</h1>
                  <h1>The framework value is: {}</h1>'''.format(language, framework)

    # otherwise handle the GET request
    return '''
           <form method="POST">
               <div><label>Language: <input type="text" name="language"></label></div>
               <div><label>Framework: <input type="text" name="framework"></label></div>
               <input type="submit" value="Submit">
           </form>'''

Em seguida, execute o aplicativo e navegue até a URL:

http://127.0.0.1:5000/form-example

Preencha o campo language com o valor de Python e o campo framework com o valor de Flask. Em seguida, pressione Submit.

O navegador exibirá a seguinte mensagem:

Output
The language value is: Python The framework value is: Flask

Agora, você sabe como manusear dados de formulários. Vamos continuar para o próximo tipo de dados de entrada.

Usando dados de JSON

Os dados de JSON são normalmente construídos por um processo que chama a rota.

Um objeto JSON de exemplo se parece com este:

{
  "language": "Python",
  "framework": "Flask",
  "website": "Scotch",
  "version_info": {
    "python": "3.9.0",
    "flask": "1.1.2"
  },
  "examples": ["query", "form", "json"],
  "boolean_test": true
}

Essa estrutura permite que dados muito mais complicados sejam passados se comparada a strings de consulta e dados de formulários. No exemplo, podemos ver objetos JSON aninhados e uma matriz de itens. O Flask é capaz de manipular este formato de dados.

Modifique a rota form-example no app.py para aceitar solicitações POST e ignorar outras solicitações, como GET:

app.py
@app.route('/json-example', methods=['POST'])
def json_example():
    return 'JSON Object Example'

Diferentemente do navegador Web usado para strings de consulta e dados de formulários, para os fins deste artigo, um Postman será usado para enviar solicitações personalizadas para URLs de forma a enviar um objeto JSON.

Nota: se precisar de ajuda para navegar pela interface do Postman para as solicitações, consulte a documentação oficial.

No Postman, adicione a URL e altere o tipo para POST. Na guia de corpo, mude para raw e selecione JSON na lista suspensa.

Essas configurações são necessárias para que o Postman consiga enviar dados de JSON corretamente e para que seu aplicativo Flask compreenda que está recebendo JSON:

POST http://127.0.0.1:5000/json-example
Body
raw JSON

Em seguida, copie o exemplo de JSON anterior na entrada de texto.

Envie a solicitação e você deve obter uma resposta “JSON Object Example”. Isso pode ser um tanto decepcionante, mas é de se esperar, porque o código para manusear a resposta dos dados de JSON ainda não está escrito.

Para ler os dados, é necessário entender como o Flask traduz dados de JSON para estruturas de dados do Python:

  • Qualquer coisa que seja um objeto é convertida para um dict do Python. {“key” : ”value”} em JSON corresponde a somedict['key'], que retorna um valor em Python.
  • Uma matriz em JSON é convertida para uma lista no Python. Como a sintaxe é a mesma, aqui está uma lista de exemplo: [1,2,3,4,5]
  • Os valores dentro de aspas no objeto JSON se tornam strings no Python.
  • Os booleanos true e false se tornam True e False no Python.
  • Por fim, os números sem aspas em sua volta se tornam números no Python.

Agora, vamos trabalhar com o código para que leia os dados de JSON de entrada.

Primeiramente, vamos atribuir tudo do objeto JSON a uma variável usando o request.get_json().

O request.get_json() converte o objeto JSON para dados do Python. Vamos atribuir os dados de solicitação de entrada às variáveis e retorná-las fazendo as seguintes alterações na rota json-example:

app.py
# GET requests will be blocked
@app.route('/json-example', methods=['POST'])
def json_example():
    request_data = request.get_json()

    language = request_data['language']
    framework = request_data['framework']

    # two keys are needed because of the nested object
    python_version = request_data['version_info']['python']

    # an index is needed because of the array
    example = request_data['examples'][0]

    boolean_test = request_data['boolean_test']

    return '''
           The language value is: {}
           The framework value is: {}
           The Python version is: {}
           The item at index 0 in the example list is: {}
           The boolean value is: {}'''.format(language, framework, python_version, example, boolean_test)

Note como os elementos que não estão no nível superior são acessados. O ['version']['python'] é usado porque você está entrando em um objeto aninhado. E o ['examples'][0] é usado para acessar o índice 0 na matriz de exemplos.

Se o objeto JSON enviado com a solicitação não tiver uma chave que seja acessada na sua função de visualização, então a solicitação falhará. Se não quiser que ela falhe quando uma chave não existir, será necessário verificar se a chave existe antes de tentar acessá-la.

app.py
# GET requests will be blocked
@app.route('/json-example', methods=['POST'])
def json_example():
    request_data = request.get_json()

    language = None
    framework = None
    python_version = None
    example = None
    boolean_test = None

    if request_data:
        if 'language' in request_data:
            language = request_data['language']

        if 'framework' in request_data:
            framework = request_data['framework']

        if 'version_info' in request_data:
            if 'python' in request_data['version_info']:
                python_version = request_data['version_info']['python']

        if 'examples' in request_data:
            if (type(request_data['examples']) == list) and (len(request_data['examples']) > 0):
                example = request_data['examples'][0]

        if 'boolean_test' in request_data:
            boolean_test = request_data['boolean_test']

    return '''
           The language value is: {}
           The framework value is: {}
           The Python version is: {}
           The item at index 0 in the example list is: {}
           The boolean value is: {}'''.format(language, framework, python_version, example, boolean_test)

Execute o aplicativo e envie a solicitação JSON de exemplo usando o Postman. Na resposta, o seguinte resultado será exibido:

Output
The language value is: Python The framework value is: Flask The Python version is: 3.9 The item at index 0 in the example list is: query The boolean value is: false

Agora, você sabe como processar objetos JSON.

Conclusão

Neste tutorial, você construiu um aplicativo Flask com três rotas que aceitam strings de consulta, dados de formulário ou objetos JSON.

Além disso, lembre-se de que todas as abordagens precisaram lidar com o fato recorrente de falharem graciosamente quando uma chave está faltando.

Aviso: um tópico que não foi abordado neste artigo é a limpeza das entradas de usuário. A limpeza das entradas de usuário garante que os dados lidos pelo aplicativo não façam com que algo falhe de maneira inesperada ou contorne medidas de segurança.

Se quiser aprender mais sobre o Flask, confira nossa página de tópico do Flask para exercícios e projetos de programação.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products

About the authors
Default avatar
Anthony Herbert

author

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
Leave a comment


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Become a contributor for community

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

DigitalOcean Documentation

Full documentation for every DigitalOcean product.

Resources for startups and SMBs

The Wave has everything you need to know about building a business, from raising funding to marketing your product.

Get our newsletter

Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.

New accounts only. By submitting your email you agree to our Privacy Policy

The developer cloud

Scale up as you grow — whether you're running one virtual machine or ten thousand.

Get started for free

Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

*This promotional offer applies to new accounts only.