Fundamentos da Web • Cliente-Servidor • HTML/CSS/JS • Roadmap • Flask hands-on
GET /pagina HTTP/1.1
Host: exemplo.com
Accept: text/html
HTTP/1.1 200 OK
Content-Type: text/html
<html>...</html>
Dica Entender requisições ajuda a debugar APIs e front-ends.
<!doctype html>
<html>
<head><title>Minha Página</title></head>
<body>
<h1>Título</h1>
<p>Parágrafo com <a href="#">link</a>.</p>
</body>
</html>
body { font-family: Arial, sans-serif; }
h1 { color: #1f6feb; }
.card {
border: 1px solid #ddd;
padding: 1rem; border-radius: 8px;
}
document.querySelector("#btn").addEventListener("click", () => {
const nome = document.querySelector("#nome").value;
alert(`Olá, ${nome}!`);
});
<input id="nome" placeholder="Seu nome" />
<button id="btn">Saudar</button>
<script>
// manipulação do DOM
const btn = document.getElementById("btn");
btn.onclick = () => {
const nome = document.getElementById("nome").value.trim();
console.log("Nome digitado:", nome);
};
</script>
-- SQL de exemplo
CREATE TABLE contatos (
id SERIAL PRIMARY KEY,
nome TEXT NOT NULL,
email TEXT NOT NULL UNIQUE
);
Segurança deve ser considerada desde o início do projeto.
Vamos criar uma aplicação simples para cadastrar e listar contatos.
# criar e ativar venv
python -m venv .venv
# Linux/macOS
source .venv/bin/activate
# Windows
# .venv\Scripts\activate
pip install Flask
Mantenha as dependências isoladas por projeto.
from flask import Flask, render_template, request, redirect, url_for
app = Flask(__name__)
contatos: list[dict] = [] # usar DB em produção
@app.route("/")
def index():
return render_template("index.html", contatos=contatos)
@app.route("/adicionar", methods=["POST"])
def adicionar_contato():
contato = {
"nome": request.form["nome"],
"email": request.form["email"],
"telefone": request.form["telefone"]
}
contatos.append(contato)
return redirect(url_for("index"))
if __name__ == "__main__":
app.run(debug=True)
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="utf-8">
<title>Minha Agenda</title>
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head>
<body>
<h1>Minha Agenda</h1>
<form method="POST" action="/adicionar" class="card">
<input type="text" name="nome" placeholder="Nome" required />
<input type="email" name="email" placeholder="Email" required />
<input type="tel" name="telefone" placeholder="Telefone" required />
<button type="submit">Adicionar</button>
</form>
<h2>Contatos</h2>
<ul>
{% for c in contatos %}
<li>{{ c.nome }} — {{ c.email }} — {{ c.telefone }}</li>
{% else %}
<li>Sem contatos.</li>
{% endfor %}
</ul>
</body>
</html>
* { box-sizing: border-box; }
body { font-family: system-ui, -apple-system, Segoe UI, Roboto, Arial;
max-width: 820px; margin: 40px auto; padding: 0 16px; }
h1 { color: #1f6feb; }
.card { display: grid; gap: 8px; padding: 12px;
border: 1px solid #ddd; border-radius: 10px; }
input, button { padding: 10px; border-radius: 8px; border: 1px solid #ccc; }
button { background: #1f6feb; color: white; border: none; cursor: pointer; }
button:hover { filter: brightness(1.05); }
python app.py
# acesse http://127.0.0.1:5000
Próximos passos: persistir em SQLite, validações de formulário, editar/excluir.
meu_projeto/
├─ app.py
├─ templates/
│ └─ index.html
├─ static/
│ └─ style.css
└─ .venv/
Convencional: templates/ para HTML (Jinja2) e static/ para CSS/JS/imagens.
<ul>
{% for item in itens %}
<li>{{ item.nome }}</li>
{% endfor %}
</ul>
@app.route("/contato/<int:cid>")
def detalhe(cid):
# buscar contato por id
...
from flask import request
@app.post("/enviar")
def enviar():
nome = request.form.get("nome")
return f"Olá, {nome}!"
from flask import jsonify
@app.get("/api/contatos")
def api_contatos():
return jsonify(contatos)
# contatos/rotas.py
from flask import Blueprint
bp = Blueprint("contatos", __name__)
@bp.get("/contatos")
def listar():
return "listar..."
# app.py
from contatos.rotas import bp
app.register_blueprint(bp)
# exemplo simples
pip install gunicorn
gunicorn -w 4 -b 0.0.0.0:8000 app:app
Daqui, evolua para banco de dados, segurança e testes.