Skip to content

01 - Get-it - O retorno

Parte 2: Respondendo com páginas HTML

Nosso servidor já responde com Hello World, mas queremos muito mais que isso. Queremos implementar o nosso Get-it e para isso a página precisa ter muito mais conteúdo e precisa ser apresentado de maneira estruturada. Está na hora de trazermos o bom e velho HTML de volta!

Vamos devolver uma página HTML simples, apenas para relembrar as coisas:

from flask import Flask, request

app = Flask(__name__)

RESPONSE_TEMPLATE = '''<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Get-it</title>
</head>
<body>

<h1>Get-it</h1>
<p>Como o Post-it, mas com outro verbo</p>

</body>
</html>
'''


@app.route('/')
def index():
    print(request.method)
    print(request.headers)

    return RESPONSE_TEMPLATE


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

Testou? Funcionou? Podemos ir para o próximo passo.

Mostrando a lista de anotações

Podemos começar a pensar no conteúdo da nossa página principal. Vamos começar mostrando uma lista simples com os títulos e detalhes das anotações. Você vai precisar baixar a seguinte imagem clicando neste link. Através do terminal, crie uma pasta chamada static. Dentro desta pasta, crie outra pasta chamada img. Salve essa imagem dentro da pasta img. Ou seja, o conteúdo do seu repositório será:

- DIRETORIO-DO-SEU-SERVIDOR
  |- servidor.py
  |- static
    |- img
      |- logo-getit.png

Para a lista de anotações vamos utilizar as tags HTML unordered list (<ul>), list item (<li>), heading (<h3>) e paragraph (<p>). Além disso, vamos mostrar uma imagem com o logo ao invés de um texto com o título:

from flask import Flask, request

app = Flask(__name__)

RESPONSE_TEMPLATE = '''<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Get-it</title>
</head>
<body>

<img src="img/logo-getit.png">
<p>Como o Post-it, mas com outro verbo</p>

<ul>
  <li>
    <h3>Receita de miojo</h3>
    <p>Bata com um martelo antes de abrir o pacote. Misture o tempero, coloque em uma vasilha e aproveite seu snack :)</p>
  </li>
  <li>
    <h3>Pão doce</h3>
    <p>Abra o pão e coloque o seu suco em pó favorito.</p>
  </li>
  <li>
    <h3>Sorvete com cristais de leite</h3>
    <p>Sirva o seu sorvete favorito em uma vasilha e jogue leite em cima.</p>
  </li>
  <li>
    <h3>Iogurte natural</h3>
    <p>Deixe o leite fora da geladeira (esse é mentira, não faça isso).</p>
  </li>
  <li>
    <h3>Homer Simpson</h3>
    <p>~( 8(|)</p>
  </li>
  <li>
    <h3>Numero mágico</h3>
    <p>142857</p>
  </li>
  <li>
    <h3>Série da Fundação - Isaac Asimov</h3>
    <p>É boa, leia.</p>
  </li>
</ul>

</body>
</html>
'''

@app.route('/')
def index():
    print(request.method)
    print(request.headers)

    return RESPONSE_TEMPLATE


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

Se você rodou o código acima deve ter percebido que algo deu errado. Você não achou que seria tão simples assim, não é mesmo?

O arquivo da imagem do logo existe no seu computador (ou deveria existir - caso contrário, não se esqueça de baixar as imagens), mas o servidor precisa enviar esses arquivos como resposta quando forem solicitados.

Diferenciando rotas

Temos que implementar algumas coisas, mas vamos por partes. Verifique a saída no seu terminal. Você deve encontrar algo assim:

127.0.0.1 - - [24/Jan/2025 14:27:28] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [24/Jan/2025 14:27:28] "GET /img/logo-getit.png HTTP/1.1" 404 -
127.0.0.1 - - [24/Jan/2025 14:27:28] "GET /favicon.ico HTTP/1.1" 404 -

Quando o navegador acessa a página, ele faz uma requisição para /. Esta requisção é respondida com a página HTML que criamos. Dentro desse HTML, temos um link para a imagem do logo. O navegador então faz uma nova requisição para /img/logo-getit.png. Como somente definimos uma resposta para /, o servidor responde com um erro 404, que é o código HTTP para "não encontrado".

Altere novamente o código do seu servidor para:

from flask import Flask, render_template_string, url_for

app = Flask(__name__)

RESPONSE_TEMPLATE = '''<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Get-it</title>
</head>
<body>

<img src="{{ url_for('static', filename='img/logo-getit.png') }}">
<p>Como o Post-it, mas com outro verbo</p>

<ul>
  <li>
    <h3>Receita de miojo</h3>
    <p>Bata com um martelo antes de abrir o pacote. Misture o tempero, coloque em uma vasilha e aproveite seu snack :)</p>
  </li>
  <li>
    <h3>Pão doce</h3>
    <p>Abra o pão e coloque o seu suco em pó favorito.</p>
  </li>
  <li>
    <h3>Sorvete com cristais de leite</h3>
    <p>Sirva o seu sorvete favorito em uma vasilha e jogue leite em cima.</p>
  </li>
  <li>
    <h3>Iogurte natural</h3>
    <p>Deixe o leite fora da geladeira (esse é mentira, não faça isso).</p>
  </li>
  <li>
    <h3>Homer Simpson</h3>
    <p>~( 8(|)</p>
  </li>
  <li>
    <h3>Numero mágico</h3>
    <p>142857</p>
  </li>
  <li>
    <h3>Série da Fundação - Isaac Asimov</h3>
    <p>É boa, leia.</p>
  </li>
</ul>

</body>
</html>
'''

# Configurando a pasta de arquivos estáticos
app.static_folder = 'static'

@app.route('/')
def index():
    # print(request.method)
    # print(request.headers)

    return render_template_string(RESPONSE_TEMPLATE)


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

O comando {{ url_for('static', filename='img/logo-getit.png') }} é uma função do Flask que gera a URL para um arquivo estático. O Flask sabe que os arquivos estáticos estão no diretório static e que o arquivo logo-getit.png está dentro do diretório img. O Flask vai gerar a URL correta para o arquivo, independente de onde o servidor estiver rodando. Agora, quando o servidor receber uma requisição para /img/logo-getit.png, ele vai procurar o arquivo no diretório static/img e enviar o conteúdo do arquivo como resposta. Se o arquivo não for encontrado, o servidor vai responder com um erro 404.

Depois de atualizar o código, o servidor deve funcionar corretamente, mostrando a imagem. Sim, está feio, mas nós resolvemos isso no próximo handout. Por enquanto vai ficar assim mesmo.

As páginas de detalhes ainda não estão prontas, mas antes disso precisamos refatorar o código porque ele já está acumulando muitas responsabilidades. Depois de se hidratar e fazer um alongamento, siga para a parte 3 do handout.