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á:
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.