Python: Guia prático do zero ao primeiro projeto
- #Python
Python é direto, versátil e ideal para começar na programação. Neste artigo você aprende o essencial para sair do zero ao primeiro projeto com qualidade. Falaremos de boas práticas, bibliotecas-chave, web com Flask/Django e do impacto na sua carreira.
1) Primeiros passos e boas práticas com Python
Objetivo desta seção: sair do absoluto zero até rodar seu primeiro projeto com qualidade (ambiente configurado, script funcionando, padrões de estilo, testes e organização).
1.1 Instalação e configuração (Python 3.x, VS Code)
O que você vai instalar agora
- Python 3.x (a linguagem).
- VS Code (editor).
- Extensão Python (suporte a lint, debug e Jupyter).
Passo a passo
- Instalar o Python 3.x
- Windows: baixe no site oficial do Python e, no instalador, marque “Add Python to PATH”.
- macOS: baixe o .pkg oficial ou use Homebrew:
brew install python
- Linux (Debian/Ubuntu):
sudo apt update
sudo apt install -y python3 python3-pip python3-venv
- Confirmar a instalação
# macOS/Linux
python --version
# Windows (alternativa)
py --version
- Saída esperada:
Python 3.x.x
. - Instalar o VS Code e a extensão Python
- Abra o VS Code → Extensions → procure Python (Microsoft) → Install.
- Pressione Ctrl+Shift+P → “Python: Select Interpreter” → escolha o Python 3.x detectado.
Se der erro “python não é reconhecido” no Windows, reinstale o Python marcando Add Python to PATH, ou usepy
em vez depython
.
1.2 Terminal, REPL, venv
e pip
Criar e abrir a pasta do projeto
mkdir meu_primeiro_projeto
cd meu_primeiro_projeto
# Dica: no VS Code, abra a pasta atual
code .
Criar ambiente virtual (um por projeto)
# cria o ambiente
python -m venv .venv
# ativar no Windows
.venv\Scripts\activate
# ativar no macOS/Linux
source .venv/bin/activate
Ao ativar, o terminal mostra (.venv)
no início da linha.
Atualizar o pip e instalar pacotes
python -m pip install --upgrade pip
pip install requests
pip freeze > requirements.txt
REPL (modo interativo)
python
>>> 2 + 2
4
>>> "python".upper()
'PYTHON'
>>> exit() # sai do REPL
Recriar dependências em outra máquina
pip install -r requirements.txt
1.3 Sintaxe base: tipos, controle de fluxo, funções
Criar seu primeiro script
- No VS Code, New File →
main.py
. - Cole e salve:
print("Olá, Python!")
- Execute:
python main.py
Saída esperada: Olá, Python!
Variáveis e tipos
nome = "Ana" # str
idade = 29 # int
altura = 1.68 # float
ativo = True # bool
print(nome, idade, altura, ativo)
Condicionais e laços
if idade >= 18:
print("Maior de idade")
else:
print("Menor de idade")
for i in range(3):
print("Contando:", i)
Funções com retorno
def saudacao(pessoa: str) -> str:
return f"Olá, {pessoa}!"
print(saudacao("Ana"))
1.4 Estruturas de dados: strings, listas, dicionários, conjuntos, tuplas
Exemplos essenciais (copie e rode)
# String
curso = "Python Para Iniciantes"
print(curso.lower(), len(curso))
# Lista
frutas = ["maçã", "banana"]
frutas.append("uva")
print(frutas[0], len(frutas)) # maçã 3
# Dicionário
pessoa = {"nome": "Ana", "idade": 29}
pessoa["cidade"] = "RJ"
print(pessoa["nome"], pessoa.get("cidade")) # Ana RJ
# Conjunto (sem repetição)
tags = {"python", "web", "python"}
print(tags) # {'python', 'web'}
# Tupla (imutável)
coord = (22.9, -43.2)
print(coord[0]) # 22.9
Compreensões (atalhos poderosos)
quadrados = [x*x for x in range(1, 6)] # lista
pares = {x for x in range(10) if x % 2 == 0} # conjunto
print(quadrados, pares)
1.5 Estilo e qualidade: PEP 8, docstrings, type hints, logging
PEP 8 (guia de estilo)
snake_case
para funções e variáveis.PascalCase
para classes.- Nomes claros e linhas curtas.
- Imports organizados (stdlib → terceiros → seus módulos).
TAXA_JUROS = 0.05 # constante em maiúsculas
class ContaBancaria:
"""Exemplo com PEP 8, docstring e tipagem."""
def __init__(self) -> None:
self._saldo: float = 0.0
def depositar(self, valor: float) -> bool:
"""Retorna True se o depósito foi aceito."""
if valor <= 0:
return False
self._saldo += valor
return True
Docstrings: explique o propósito
def calcular_imc(peso: float, altura: float) -> float:
"""
Calcula IMC arredondado em 2 casas.
Lança ValueError se altura <= 0.
"""
if altura <= 0:
raise ValueError("Altura inválida")
return round(peso / (altura ** 2), 2)
Logging (diagnóstico melhor que print
)
import logging
logging.basicConfig(level=logging.INFO)
logging.info("Iniciando processamento...")
1.6 Testes e formatação: pytest
, black
, ruff
, mypy
Instalar ferramentas de qualidade
pip install pytest black ruff mypy
Criar um teste automatizado (pasta tests/
)
- Crie a função testável em
main.py
(ousrc/…
se já estiver organizado):
def soma(a: float, b: float) -> float:
return a + b
- Crie
tests/test_main.py
:
from main import calcular_imc, soma
import pytest
def test_imc_ok():
assert calcular_imc(70, 1.75) == 22.86
def test_imc_erro():
with pytest.raises(ValueError):
calcular_imc(70, 0)
def test_soma():
assert soma(2, 3) == 5
- Rode os testes:
pytest -q
Saída esperada: 3 passed
.
Formatação e lint
black .
ruff .
black
formata o código;ruff
aponta problemas de estilo.
Checagem de tipos
mypy .
Se algo estiver inconsistente, o mypy
indica onde corrigir.
1.7 Organização de projeto: layout de pastas, requirements.txt
Estrutura inicial recomendada
meu_primeiro_projeto/
├─ src/
│ └─ meu_modulo/
│ ├─ __init__.py
│ └─ core.py
├─ tests/
│ └─ test_core.py
├─ .venv/
├─ requirements.txt
├─ .gitignore
└─ README.md
Exemplo mínimo de código organizado
src/meu_modulo/core.py
def calcular_imc(peso: float, altura: float) -> float:
if altura <= 0:
raise ValueError("Altura inválida")
return round(peso / (altura ** 2), 2)
tests/test_core.py
from meu_modulo.core import calcular_imc
import pytest
def test_imc_ok():
assert calcular_imc(70, 1.75) == 22.86
def test_imc_erro():
with pytest.raises(ValueError):
calcular_imc(70, 0)
- Executando testes nessa estrutura (garanta que está na raiz do projeto)
pytest -q
Manter dependências em dia
pip freeze > requirements.txt
2) Bibliotecas essenciais de Python
- 2.1 Stdlib que importa:
pathlib
,datetime
,json
,argparse
,itertools
- 2.2 Dados e gráficos: NumPy, Pandas, Matplotlib (e quando usar cada uma)
- 2.3 HTTP e automação: Requests/HTTPX, BeautifulSoup, Selenium, Schedule
- 2.4 CLIs e validação: Click/Typer, Pydantic
- 2.5 Qualidade contínua: pytest, coverage, linters e pre-commit
2) Bibliotecas essenciais de Python
Objetivo desta seção: instalar e usar, na prática, as bibliotecas padrão que você realmente precisa no começo.
Pré-requisito: você já criou um projeto comvenv
ativo (Seção 1). O terminal deve mostrar(.venv)
no início da linha.
2.1 Biblioteca padrão (Stdlib - Standard Library) que importa: pathlib
, datetime
, json
, argparse
, itertools
A stdlib já vem com o Python. Nada para instalar.
2.1.1 pathlib
— arquivos e pastas de forma simples
# src/arquivo_demo.py
from pathlib import Path
p = Path("notas.txt")
p.write_text("Primeira linha\n", encoding="utf-8")
conteudo = p.read_text(encoding="utf-8")
print("Lido:", conteudo)
# Listar .txt da pasta atual
for t in Path(".").glob("*.txt"):
print("Achei:", t.name)
Rodar:
python src/arquivo_demo.py
2.1.2 datetime
— datas e horas
# src/datas_demo.py
from datetime import datetime, timedelta
agora = datetime.now()
amanha = agora + timedelta(days=1)
print("Agora:", agora.isoformat(timespec="seconds"))
print("Amanhã:", amanha.strftime("%d/%m/%Y %H:%M"))
2.1.3 json
— salvar e carregar dados
# src/json_demo.py
import json
from pathlib import Path
dados = {"nome": "Ana", "pontuacao": 91, "tags": ["python", "iniciante"]}
Path("dados.json").write_text(json.dumps(dados, ensure_ascii=False, indent=2), encoding="utf-8")
texto = Path("dados.json").read_text(encoding="utf-8")
carregado = json.loads(texto)
print("OK:", carregado["nome"], carregado["pontuacao"])
2.1.4 argparse
— parâmetros de linha de comando
# src/cli_demo.py
import argparse
parser = argparse.ArgumentParser(description="Exemplo de CLI com argparse")
parser.add_argument("--nome", required=True, help="Seu nome")
args = parser.parse_args()
print(f"Olá, {args.nome}!")
Rodar:
python src/cli_demo.py --nome "Ana"
2.1.5 itertools
— produtividade com coleções
# src/itertools_demo.py
from itertools import combinations, groupby
itens = ["A", "B", "C"]
print(list(combinations(itens, 2))) # pares possíveis
alunos = [("Ana", "A"), ("Beto", "B"), ("Alice", "A")]
alunos.sort(key=lambda x: x[1])
for grupo, itens in groupby(alunos, key=lambda x: x[1]):
print("Grupo:", grupo, list(itens))
2.2 Dados e gráficos: NumPy, Pandas, Matplotlib (e quando usar cada uma)
Quando usar: NumPy → contas rápidas com vetores/arrays. Pandas → tabelas (CSV/Excel) com filtros e agregações. Matplotlib → gráficos básicos (linha, barra, pizza).
Instalar:
pip install numpy pandas matplotlib
2.2.1 NumPy — operações numéricas vetorizadas
# src/numpy_demo.py
import numpy as np
arr = np.array([1, 2, 3, 4], dtype=float)
print("Array:", arr)
print("Soma:", arr.sum())
print("Dobro:", arr * 2)
print("Média:", arr.mean())
2.2.2 Pandas — trabalhando com CSV/Excel
Crie um alunos.csv
:
nome,nota,turma
Ana,8.5,A
Beto,7.2,B
Carla,9.1,A
Código:
# src/pandas_demo.py
import pandas as pd
df = pd.read_csv("alunos.csv")
print(df.head())
# Filtrar
a = df[df["turma"] == "A"]
print("Turma A:", a)
# Média por turma
media = df.groupby("turma")["nota"].mean()
print("Média por turma:\n", media)
2.2.3 Matplotlib — visualização simples
# src/plot_demo.py
import pandas as pd
import matplotlib.pyplot as plt
df = pd.read_csv("alunos.csv")
media = df.groupby("turma")["nota"].mean()
media.plot(kind="bar", title="Média de notas por turma")
plt.xlabel("Turma")
plt.ylabel("Nota média")
plt.tight_layout()
plt.savefig("grafico_notas.png") # gera imagem
print("Gerado: grafico_notas.png")
2.3 HTTP e automação: Requests/HTTPX, BeautifulSoup, Selenium, Schedule
Instalar:
pip install requests httpx beautifulsoup4 selenium webdriver-manager schedule
Requests (sincrono) é ótimo para começar. HTTPX também é simples e suporta assíncrono. BeautifulSoup extrai dados de HTML. Selenium controla o navegador (precisa Chrome/Edge instalado). webdriver-manager baixa o driver automaticamente. Schedule agenda tarefas simples.
2.3.1 Requests — baixando JSON da web
# src/requests_demo.py
import requests
r = requests.get("https://httpbin.org/json", timeout=10)
r.raise_for_status() # erro claro se falhar
data = r.json()
print("Título:", data.get("slideshow", {}).get("title"))
2.3.2 BeautifulSoup — raspando HTML
# src/bs4_demo.py
import requests
from bs4 import BeautifulSoup
html = requests.get("https://httpbin.org/html", timeout=10).text
soup = BeautifulSoup(html, "html.parser")
titulo = soup.find("h1").get_text(strip=True)
print("Título da página:", titulo)
2.3.3 Selenium — automatizando um navegador
# src/selenium_demo.py
from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.service import Service
svc = Service(ChromeDriverManager().install())
driver = webdriver.Chrome(service=svc)
driver.get("https://httpbin.org/forms/post")
print("Título:", driver.title)
driver.quit()
Se o Chrome não estiver instalado, instale-o primeiro.
2.3.4 Schedule — agendando uma tarefa
# src/schedule_demo.py
import time
import subprocess
import sys
# Tenta importar 'schedule' e instala automaticamente se não estiver disponível
try:
import schedule
except ImportError:
print("Módulo 'schedule' não encontrado. Instalando...")
subprocess.check_call([sys.executable, "-m", "pip", "install", "schedule"])
import schedule
# Função que será executada periodicamente
def trabalho():
print("Executando tarefa...")
# Agendamento: executar a cada 1 minuto
schedule.every(1).minutes.do(trabalho)
print("Pressione CTRL+C para parar.")
while True:
schedule.run_pending()
time.sleep(1)
2.4 CLIs e validação: Click/Typer, Pydantic
Typer constrói CLIs modernas (baseado em Click). Pydantic valida dados com type hints.
Instalar:
pip install "typer[all]" pydantic
2.4.1 Typer — sua primeira CLI de verdade
# src/app_cli.py
import typer
app = typer.Typer(help="Exemplo de CLI com Typer")
@app.command()
def ola(nome: str = typer.Argument(..., help="Seu nome")):
"""Saúda o usuário."""
typer.echo(f"Olá, {nome}!")
if __name__ == "__main__":
app()
Rodar:
python src/app_cli.py --help
python src/app_cli.py ola Ana
2.4.2 Pydantic — validando dados com modelos
# src/validacao_demo.py
from pydantic import BaseModel, Field, ValidationError
class Usuario(BaseModel):
nome: str = Field(min_length=2)
idade: int = Field(ge=0)
email: str
try:
u = Usuario(nome="Ana", idade=29, email="ana@exemplo.com")
print("OK:", u.model_dump())
Usuario(nome="X", idade=-1, email="invalido")
except ValidationError as e:
print("Erros de validação:\n", e)
2.5 Qualidade contínua: pytest, coverage, linters e pre-commit
Meta: garantir qualidade automaticamente a cada alteração.
Instalar ferramentas:
pip install pytest pytest-cov black ruff pre-commit
2.5.1 Testes e cobertura
# rodar testes (mostrando cobertura)
pytest -q --cov=src --cov-report=term-missing
Ajuste --cov=src
para a pasta do seu código.
2.5.2 Formatação e lint locais
black .
ruff .
3) Desenvolvimento web Python com Flask e Django
Objetivo desta seção: Você vai criar um “Hello, World!” em Flask e Django, salvar dados com ORM, trabalhar com formulários, entender estrutura de projetos, configurações, testes e ter um caminho claro para o deploy.
Pré-requisitos mínimos
- Ter o Python 3.x instalado e um projeto com
venv
ativo (da Seção 1). - No terminal, deve aparecer
(.venv)
no início da linha.
3.1 Quando usar Flask e quando usar Django (micro x “baterias incluídas”)
Flask (microframework)
- Projeto pequeno, APIs simples, protótipos rápidos.
- Você escolhe as peças: ORM, formulários, auth.
- Curva de aprendizado suave.
Django (“baterias incluídas”)
- Projeto completo: painel admin, ORM, auth, formulários, templates.
- Ótimo para CRUDs, portais, backoffices.
- Estrutura mais “opinionada” e produtiva.
Regra prática: API ou app simples/rápido → Flask. Sistema completo com painel/admin e auth → Django.
3.2 “Hello, World!” em ambos: rotas, templates e responses
3.2.1 Flask — “Hello, World!” + template
Instalar Flask
pip install flask
Crie app.py
na raiz do projeto
from flask import Flask, render_template, jsonify
app = Flask(__name__)
@app.get("/")
def home():
# HTML via template
return render_template("index.html", nome="Mundo")
@app.get("/api/hello")
def api_hello():
# JSON
return jsonify(ok=True, msg="Olá da API!")
if __name__ == "__main__":
app.run(debug=True)
Crie a pasta de templates e um HTML simples
templates/
└─ index.html
templates/index.html
<!doctype html>
<html lang="pt-BR">
<head><meta charset="utf-8"><title>Flask Hello</title></head>
<body>
<h1>Olá, {{ nome }}!</h1>
<p>Se você está vendo isto, seu Flask está ok 🚀</p>
</body>
</html>
Rodar
python app.py
# Abra http://127.0.0.1:5000
# JSON em http://127.0.0.1:5000/api/hello
3.2.2 Django — “Hello, World!” + template
Instalar Django
pip install django
Criar o projeto
django-admin startproject mysite .
# cria manage.py e a pasta mysite/
Criar um app “core”
python manage.py startapp core
Registrar o app em mysite/settings.py
INSTALLED_APPS = [
# ...
"core",
]
Criar uma view em core/views.py
from django.http import HttpResponse
from django.shortcuts import render
def home(request):
return render(request, "index.html", {"nome": "Mundo"})
def api_hello(request):
return HttpResponse('{"ok": true, "msg": "Olá da API!"}', content_type="application/json")
Mapear URLs em mysite/urls.py
from django.contrib import admin
from django.urls import path
from core.views import home, api_hello
urlpatterns = [
path("admin/", admin.site.urls),
path("", home),
path("api/hello", api_hello),
]
Templates do Django Crie a pasta templates/
na raiz:
templates/
└─ index.html
templates/index.html
(pode reaproveitar o HTML do Flask)
<!doctype html>
<html lang="pt-BR">
<head><meta charset="utf-8"><title>Django Hello</title></head>
<body>
<h1>Olá, {{ nome }}!</h1>
<p>Se você está vendo isto, seu Django está ok 🚀</p>
</body>
</html>
Rodar
python manage.py runserver
# Abra http://127.0.0.1:8000
# JSON em http://127.0.0.1:8000/api/hello
Se o template não carregar, garanta queDIRS
emTEMPLATES
(emmysite/settings.py
) aponta paraBASE_DIR / "templates"
:
from pathlib import Path
BASE_DIR = Path(__file__).resolve().parent.parent
TEMPLATES = [{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [BASE_DIR / "templates"], # <— importante
"APP_DIRS": True,
"OPTIONS": {"context_processors": [...]},
}]
3.3 Banco e ORM: SQLAlchemy (Flask) vs. Django ORM
3.3.1 Flask + SQLAlchemy (SQLite para começar)
Instalar
pip install sqlalchemy flask_sqlalchemy
app.py
(trecho mínimo para DB)
from flask import Flask, jsonify
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///app.db"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
db = SQLAlchemy(app)
class Usuario(db.Model):
id = db.Column(db.Integer, primary_key=True)
nome = db.Column(db.String(80), nullable=False)
@app.before_first_request
def criar_tabelas():
db.create_all()
@app.get("/criar")
def criar():
u = Usuario(nome="Ana")
db.session.add(u)
db.session.commit()
return jsonify(ok=True, id=u.id)
@app.get("/usuarios")
def listar():
return jsonify([{"id": u.id, "nome": u.nome} for u in Usuario.query.all()])
if __name__ == "__main__":
app.run(debug=True)
Rodar
python app.py
# Visite /criar e depois /usuarios
Para migrações, depois você pode usar Flask-Migrate, mas aqui focamos no básico.
3.3.2 Django ORM (SQLite por padrão)
Model em core/models.py
from django.db import models
class Usuario(models.Model):
nome = models.CharField(max_length=80)
def __str__(self):
return self.nome
Ativar o app e migrar
# (já adicionamos "core" em INSTALLED_APPS)
python manage.py makemigrations
python manage.py migrate
Criar um registro no shell
python manage.py shell
from core.models import Usuario
Usuario.objects.create(nome="Ana")
exit()
Listar via view (core/views.py
)
from django.http import JsonResponse
from .models import Usuario
def usuarios(request):
data = list(Usuario.objects.values("id", "nome"))
return JsonResponse(data, safe=False)
URL para listar (mysite/urls.py
)
from core.views import usuarios
urlpatterns += [path("usuarios/", usuarios)]
3.4 Formulários, validação e autenticação (WTForms/Django Forms & Auth)
3.4.1 Flask + WTForms (via Flask-WTF)
Instalar
pip install flask-wtf email-validator
app.py
(form básico com CSRF)
from flask import Flask, render_template, redirect, url_for
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField
from wtforms.validators import DataRequired, Length
app = Flask(__name__)
app.config["SECRET_KEY"] = "troque-esta-chave"
class NomeForm(FlaskForm):
nome = StringField("Seu nome", validators=[DataRequired(), Length(min=2)])
enviar = SubmitField("Enviar")
@app.route("/form", methods=["GET", "POST"])
def form():
f = NomeForm()
if f.validate_on_submit():
return redirect(url_for("ola", nome=f.nome.data))
return render_template("form.html", form=f)
@app.get("/ola/<nome>")
def ola(nome):
return f"Olá, {nome}!"
if __name__ == "__main__":
app.run(debug=True)
templates/form.html
<!doctype html>
<html lang="pt-BR">
<body>
<form method="post">
{{ form.hidden_tag() }}
<p>{{ form.nome.label }} {{ form.nome(size=20) }}</p>
<p>{{ form.enviar() }}</p>
{% for field, errors in form.errors.items() %}
<div style="color:red">{{ field }}: {{ errors|join(", ") }}</div>
{% endfor %}
</form>
</body>
</html>
Autenticação no Flask: para iniciantes, comece com flask-login depois. Aqui mantivemos simples (somente formulário + validação).
3.4.2 Django Forms e Auth (logins prontos)
Form simples em core/forms.py
from django import forms
class NomeForm(forms.Form):
nome = forms.CharField(min_length=2, label="Seu nome")
View que usa o form (core/views.py
)
from django.shortcuts import render, redirect
from .forms import NomeForm
def form_view(request):
if request.method == "POST":
f = NomeForm(request.POST)
if f.is_valid():
nome = f.cleaned_data["nome"]
return redirect(f"/ola/{nome}")
else:
f = NomeForm()
return render(request, "form_django.html", {"form": f})
def ola_view(request, nome):
return render(request, "ola.html", {"nome": nome})
Templates
templates/
├─ form_django.html
└─ ola.html
templates/form_django.html
<!doctype html>
<html lang="pt-BR">
<body>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Enviar</button>
</form>
</body>
</html>
templates/ola.html
<!doctype html>
<html lang="pt-BR">
<body><h1>Olá, {{ nome }}!</h1></body>
</html>
URLs (mysite/urls.py
)
from core.views import form_view, ola_view
urlpatterns += [
path("form/", form_view),
path("ola/<str:nome>", ola_view),
]
Auth pronto (login/logout) Ative as URLs de auth:
# mysite/urls.py
from django.urls import path, include
urlpatterns += [path("accounts/", include("django.contrib.auth.urls"))]
Crie templates de login em templates/registration/login.html
(mínimo). Crie um usuário admin:
python manage.py createsuperuser
Abra /accounts/login/
e teste o login.
3.5 Estrutura de apps: Blueprints (Flask) e apps Django
3.5.1 Flask com Blueprints (organização por módulos)
Estrutura
flaskapp/
├─ app.py
├─ app/
│ ├─ __init__.py
│ └─ main/
│ ├─ __init__.py
│ └─ routes.py
└─ templates/
└─ index.html
app/__init__.py
from flask import Flask
from .main import main_bp
def create_app():
app = Flask(__name__)
app.register_blueprint(main_bp)
return app
app/main/routes.py
from flask import Blueprint, render_template
main_bp = Blueprint("main", __name__)
@main_bp.get("/")
def home():
return render_template("index.html", nome="Blueprints!")
app.py
(entrypoint)
from app import create_app
app = create_app()
if __name__ == "__main__":
app.run(debug=True)
Blueprints ajudam a separar áreas do sistema (ex.:users
,admin
,api
).
3.5.2 Django apps (um app por domínio)
Criar um novo app
python manage.py startapp blog
Registrar em INSTALLED_APPS
e criar blog/urls.py
para rotas do app. No mysite/urls.py
, inclua:
from django.urls import path, include
urlpatterns += [path("blog/", include("blog.urls"))]
Cada app tem models, views, templates e urls próprios. Isso mantém o projeto modular e escalável.
3.6 Configurações, .env
, testes, WSGI/ASGI e caminho para o deploy
3.6.1 Configurações e .env
Flask
pip install python-dotenv
Crie um .env
na raiz:
FLASK_ENV=development
SECRET_KEY=troque-esta-chave
No app.py
(ou app/__init__.py
):
from dotenv import load_dotenv; load_dotenv()
Django Use variáveis de ambiente no settings.py
:
import os
SECRET_KEY = os.getenv("SECRET_KEY", "dev-key-insegura")
DEBUG = os.getenv("DEBUG", "True") == "True"
Defina no sistema/host:
SECRET_KEY="uma-chave-segura"
DEBUG=False
3.6.2 Testes
Flask (pytest)
# test_app.py
from app import app
def test_home_ok():
c = app.test_client()
r = c.get("/")
assert r.status_code == 200
Rodar:
pytest -q
Django (test runner nativo)
# core/tests.py
from django.test import TestCase
from django.urls import reverse
class SmokeTest(TestCase):
def test_home(self):
r = self.client.get("/")
self.assertEqual(r.status_code, 200)
Rodar:
python manage.py test
3.6.3 WSGI/ASGI e deploy (visão rápida)
- Flask e Django expõem WSGI (tradicional) e Django também ASGI (assíncrono).
- Em produção, você costuma usar um servidor de aplicação atrás de um proxy (ex.: Nginx).
Exemplos simples de execução de produção local:
# Flask + Gunicorn (WSGI)
pip install gunicorn
gunicorn app:app
# Django + Gunicorn (WSGI)
gunicorn mysite.wsgi
# Django (ASGI) + Uvicorn
pip install uvicorn
uvicorn mysite.asgi:application
Para publicar “de verdade”, escolha um provedor (Railway, Render, Fly.io, etc.), defina variáveis de ambiente, banco real (PostgreSQL), coleta de estáticos (Django), e configure o proxy. O objetivo aqui é te deixar pronto para dar esse próximo passo.
O que você consegue fazer agora
- Rodar um site simples em Flask e em Django.
- Renderizar templates e retornar JSON.
- Salvar e listar dados com ORM (SQLite).
- Processar formulários e usar auth no Django.
- Organizar o projeto (Blueprints/apps).
- Configurar .env, rodar testes e entender WSGI/ASGI para deploy.
4) Impacto do Python na carreira de um desenvolvedor iniciante
Objetivo desta seção: mostrar o caminho mais curto entre aprender Python e ser contratado. Você vai montar um portfólio enxuto (com 4 projetos e código mínimo), escolher sua trilha, seguir um roadmap de 90 dias, entrar na comunidade/open source, e contar sua história no currículo, GitHub e entrevistas.
4.1 Portfólio que contrata: 4 projetos curtos e valiosos
Regra de ouro: projetos pequenos, completos e úteis. Cada repositório com README, testes (quando fizer sentido), prints/GIF e, se possível, deploy.
Padrão de repositório (execute no terminal):
mkdir projeto-x && cd projeto-x
python -m venv .venv
# Ativar: .venv\Scripts\activate (Windows) | source .venv/bin/activate (macOS/Linux)
git init
echo ".venv/" >> .gitignore
echo "__pycache__/" >> .gitignore
printf "# Projeto X\n\nComo rodar:\n1) criar venv\n2) instalar deps\n3) executar\n" > README.md
git add .
git commit -m "chore: estrutura inicial"
Projeto 1 — CLI To-Do com JSON (Fundamentos + Arquivos)
Objetivo: adicionar/listar/concluir tarefas, salvando em tarefas.json
. Bibliotecas: stdlib (não precisa instalar nada).
Arquivo: todo.py
# todo.py
from __future__ import annotations
import json
from pathlib import Path
import argparse
DB = Path("tarefas.json")
def carregar():
if DB.exists():
return json.loads(DB.read_text(encoding="utf-8"))
return []
def salvar(data):
DB.write_text(json.dumps(data, ensure_ascii=False, indent=2), encoding="utf-8")
def add(titulo: str):
data = carregar()
next_id = max((t["id"] for t in data), default=0) + 1
item = {"id": next_id, "titulo": titulo.strip(), "feito": False}
data.append(item)
salvar(data)
print(f"Adicionado #{next_id}: {titulo}")
def listar():
data = carregar()
if not data:
print("Lista vazia.")
return
for t in data:
status = "✅" if t["feito"] else "⏳"
print(f'[{t["id"]:03}] {status} {t["titulo"]}')
def done(id_: int):
data = carregar()
for t in data:
if t["id"] == id_:
t["feito"] = True
salvar(data)
print(f"Concluído #{id_}.")
return
print("Id não encontrado.")
def main():
p = argparse.ArgumentParser(prog="todo")
sub = p.add_subparsers(dest="cmd", required=True)
p_add = sub.add_parser("add"); p_add.add_argument("titulo")
sub.add_parser("list")
p_done = sub.add_parser("done"); p_done.add_argument("id", type=int)
args = p.parse_args()
if args.cmd == "add": add(args.titulo)
elif args.cmd == "list": listar()
elif args.cmd == "done": done(args.id)
if __name__ == "__main__":
main()
Testar:
python todo.py add "Estudar funções"
python todo.py add "Ler PEP 8"
python todo.py list
python todo.py done 1
python todo.py list
Projeto 2 — API Flask (IMC/Conversor) — Web básico
Objetivo: duas rotas simples que retornam JSON. Instalar:
pip install flask
Arquivo: app.py
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.get("/imc")
def imc():
try:
peso = float(request.args.get("peso", ""))
altura = float(request.args.get("altura", ""))
if altura <= 0:
raise ValueError
except Exception:
return jsonify(erro="Use /imc?peso=70&altura=1.75"), 400
return jsonify(imc=round(peso / (altura ** 2), 2))
@app.get("/celsius2fahrenheit")
def c2f():
try:
c = float(request.args.get("c", ""))
except Exception:
return jsonify(erro="Use /celsius2fahrenheit?c=25"), 400
return jsonify(fahrenheit=round(c * 9/5 + 32, 2))
if __name__ == "__main__":
app.run(debug=True)
Rodar e testar no navegador:
python app.py
# http://127.0.0.1:5000/imc?peso=70&altura=1.75
# http://127.0.0.1:5000/celsius2fahrenheit?c=25
Projeto 3 — Mini ETL com Pandas (Dados)
Objetivo: ler CSV, limpar dados, gerar relatório e gráfico. Instalar:
pip install pandas matplotlib
Crie vendas.csv
:
produto,qtd,preco
Açaí 500ml,3,17.90
Açaí 1000ml,2,27.90
Copo adicional,5,2.50
Arquivo: etl.py
import pandas as pd
import matplotlib.pyplot as plt
df = pd.read_csv("vendas.csv")
df = df.dropna(subset=["produto", "qtd", "preco"])
df = df[df["qtd"] > 0]
df["total"] = df["qtd"] * df["preco"]
rel = df.groupby("produto")["total"].sum().sort_values(ascending=False)
rel.to_csv("relatorio.csv")
rel.plot(kind="bar", title="Faturamento por produto")
plt.tight_layout()
plt.savefig("faturamento.png")
print("Gerados: relatorio.csv, faturamento.png")
Rodar:
python etl.py
Projeto 4 — Web Scraper + CSV (Automação/HTTP)
Objetivo: coletar dados de uma página de testes e salvar CSV. Instalar:
pip install requests beautifulsoup4
Arquivo: scraper.py
import csv, requests
from bs4 import BeautifulSoup
URL = "https://quotes.toscrape.com/" # site de testes para scraping
r = requests.get(URL, timeout=10)
r.raise_for_status()
soup = BeautifulSoup(r.text, "html.parser")
rows = []
for q in soup.select(".quote"):
texto = q.select_one(".text").get_text(strip=True)
autor = q.select_one(".author").get_text(strip=True)
rows.append({"texto": texto, "autor": autor})
with open("quotes.csv", "w", newline="", encoding="utf-8") as f:
w = csv.DictWriter(f, fieldnames=["texto", "autor"])
w.writeheader(); w.writerows(rows)
print("Salvo quotes.csv com", len(rows), "registros.")
Rodar:
python scraper.py
Boas práticas: respeiterobots.txt
/termos do site, usetimeout
, trate erros e evite alto volume de requisições.
4.2 Trilhas de evolução: Web, Dados, Automação e IA/ML
Escolha 1 trilha principal e 1 de apoio:
- Web (Flask/Django/FastAPI) Projetos: API REST, CRUD, autenticação básica, deploy simples. Estude: templates, ORM, testes de rota, WSGI/ASGI.
- Dados (NumPy/Pandas/Matplotlib/Seaborn) Projetos: análises com CSV, dashboards simples, relatórios. Estude: limpeza, agregações, visualizações, storytelling.
- Automação (Requests/BS4/Selenium/Schedule) Projetos: robôs de coleta, rotinas diárias, organização de arquivos. Estude: parsing HTML, navegador headless, ética/limites.
- IA/ML (scikit-learn primeiro) Projetos: regressão/classificação com dataset público. Estude: preparo de dados, métricas e overfitting (noções básicas).
4.3 Roadmap de 90 dias: estudo, prática e revisão
Meta realista: 1–2h por dia, 5 dias/semana. Entregas semanais.
Semanas 1–2 — Fundamentos + Git/GitHub
- Concluir Projeto 1 (CLI).
- Subir repo com README e prints/GIF.
Semanas 3–4 — Web básico
- Projeto 2 (API Flask).
- Adicionar testes de rota; rodar
black
eruff
. - Fazer um deploy simples (ex.: serviço grátis).
Semanas 5–6 — Dados
- Projeto 3 (ETL).
- Gerar gráfico e relatório; explicar no README.
Semanas 7–8 — Automação
- Projeto 4 (Scraper).
- Agendar com
schedule
; tratar exceções.
Semanas 9–10 — Revisão e vitrine
- Melhorar os 4 READMEs, incluir GIFs.
- Adicionar testes faltantes e
pre-commit
.
Semanas 11–12 — Consolidação
- Escolher 1 trilha principal.
- Evoluir 1 projeto para “v2” (mais testes, logs, estrutura).
- Ensaiar um pitch de 60s por projeto.
Rotina diária (exemplo)
- 25 min aula/leitura → 25 min prática → 10 min anotações.
- 2 dias/semana para revisão + issues no GitHub.
4.4 Comunidade e open source: como participar e aprender mais rápido
Por onde começar (passo a passo)
- Encontre um repositório com “good first issue” ou “help wanted”.
- Leia
README
eCONTRIBUTING.md
. - Faça fork, crie uma branch, implemente, commit e abra um Pull Request.
Comandos essenciais (após o fork):
git clone https://github.com/<seu-usuario>/<repo>.git
cd <repo>
git checkout -b feat/melhoria-docs
# edite arquivos...
git add .
git commit -m "docs: melhora passo a passo de instalação"
git push -u origin feat/melhoria-docs
# abra o Pull Request no GitHub
Contribuições que iniciantes conseguem fazer
- Melhorar documentação e exemplos.
- Adicionar testes faltantes.
- Automatizar formatação (Black/Ruff/Pre-commit).
- Criar exemplos de uso para tutoriais.
Rotina de comunidade
- Responder dúvidas em fóruns.
- Escrever 1 artigo curto por mês (ex.: DIO).
- Postar 1 dica por semana no LinkedIn.
4.5 Como contar sua experiência no currículo, GitHub e entrevistas
4.5.1 GitHub para iniciantes absolutos — do zero ao push
O que é o quê (em 5 linhas):
- Git: controle de versão local (rastreia mudanças).
- GitHub: hospeda repositórios remotos e facilita colaboração.
- Conceitos: repositório, commit (registro), branch (linha), push (enviar), pull (baixar), Pull Request (revisão/merge).
Passo 0 — Criar conta
- Cadastre-se no GitHub e verifique o e-mail.
Passo 1 — Instalar e configurar o Git
- Windows: “Git for Windows”.
- macOS:
brew install git
. - Linux (Debian/Ubuntu):
sudo apt install -y git
.
git config --global user.name "Seu Nome"
git config --global user.email "seu.email@exemplo.com"
Passo 2 — Criar repositório no GitHub (pela web)
- New repository → nome (ex.:
todo-cli
) → Public → Create.
Passo 3A — Já tem o projeto local e quer enviar (push)
# dentro da pasta do projeto
git init
git add .
git commit -m "chore: primeiro commit"
git branch -M main
git remote add origin https://github.com/<seu-usuario>/<repo>.git
git push -u origin main
Se pedir “senha” no push via HTTPS, crie um Token de Acesso Pessoal (PAT) nas configurações do GitHub (permite push).
Passo 3B — Ou clone o repositório vazio e trabalhe dentro dele
git clone https://github.com/<seu-usuario>/<repo>.git
cd <repo>
# adicione seus arquivos...
git add .
git commit -m "feat: primeira versão"
git push
Ciclo diário (local → remoto)
git status
git add .
git commit -m "feat: melhora /imc"
git push
Branches e Pull Request (resumo)
git checkout -b feat/validacao-parametros
# trabalhe, adicione, faça commits...
git push -u origin feat/validacao-parametros
# abra o Pull Request no GitHub e solicite revisão
4.5.2 Currículo, GitHub e entrevistas — como “vender” seus projetos
Currículo (1 página, direto):
- Headline: “Desenvolvedor Python (Júnior) — Web | Dados | Automação”.
- Habilidades: Python 3, Flask/Django, Pandas, Git, pytest, PEP8.
- Projetos (com links):
- CLI To-Do: leitura/escrita JSON, argparse/typer, testes.
- API Flask IMC: rotas, validação, testes e deploy simples.
- Mini ETL: agregações e gráficos com Pandas/Matplotlib.
- Scraper: requests/bs4, CSV, timeout e tratamento de erros.
GitHub (sua vitrine):
- Fixe (pin) os 4 repositórios principais.
- README com objetivo, como rodar, prints/GIF, testes.
- Commits pequenos e mensagens claras (
feat:
,fix:
,docs:
).
Como explicar (modelo STAR, 20–40s):
- Situação: “precisei de uma CLI simples para tarefas.”
- Tarefa: “organizar e priorizar com persistência local.”
- Ação: “usei Python+JSON, testes com pytest, Black/Ruff.”
- Resultado: “CRUD completo com README e GIF; feedback positivo.”
Perguntas comuns (respostas curtas):
- Por que Python? — Versátil, legível, grande ecossistema.
- Como garante qualidade? — Testes (pytest), formatação (Black), lint (Ruff),
pre-commit
. - Desafio recente? — Explique um bug, o teste que reproduziu e a correção.
Pitch pronto (60s):
“Sou desenvolvedor Python iniciante com foco em Web e Automação. Construi 4 projetos curtos: uma CLI com JSON, uma API Flask com testes e deploy, um mini ETL com Pandas/Matplotlib e um scraper com requests/bs4. Padronizo com PEP8, Black e Ruff, mantenho testes com pytest e estou evoluindo em Django/SQL. Procuro equipes que valorizem código limpo e aprendizado contínuo.”
Checklist final da seção
- [ ] 4 repositórios públicos rodando localmente.
- [ ] README completo com prints/GIF e (quando fizer sentido) testes.
- [ ] Trilha principal escolhida (Web, Dados, Automação ou IA/ML).
- [ ] Roadmap 90 dias iniciado (com calendário).
- [ ] 1 contribuição simples em open source (PR de docs/testes).
- [ ] Currículo 1 página + GitHub organizado + pitch de 60s ensaiado.
5) Conclusão e próximos passos
- 5.1 Checklist final de aprendizado
- 5.2 Desafio: publicar um repositório hoje e pedir feedback
5) Conclusão e próximos passos
Você saiu do zero, montou ambiente, praticou fundamentos, usou bibliotecas essenciais, criou apps web e estruturou um portfólio básico. Agora é hora de consolidar, publicar e pedir feedback.
5.1 Checklist final de aprendizado
Marque o que você já conseguiu. O que faltar vira tarefa da semana.
Ambiente e base
- [ ] Instalei Python 3.x, VS Code e selecionei o interpreter.
- [ ] Sei criar/ativar venv e instalar libs com pip.
- [ ] Rodei scripts (
python arquivo.py
) e usei o REPL. - [ ] Pratiquei tipos, condicionais, loops e funções.
- [ ] Entendi listas, dicionários, conjuntos, tuplas e compreensões.
Boas práticas e qualidade
- [ ] Apliquei PEP 8, docstrings e type hints.
- [ ] Uso logging para diagnósticos.
- [ ] Sei rodar pytest, black, ruff e mypy.
Bibliotecas e automação
- [ ] Usei pathlib, datetime, json, argparse, itertools.
- [ ] Li CSV e plotei gráficos com Pandas/Matplotlib.
- [ ] Fiz requisições HTTP (Requests/HTTPX) e scraping (BeautifulSoup).
- [ ] Agendei tarefas com schedule.
Web
- [ ] Criei Hello, World! em Flask e Django.
- [ ] Salvei/listrei dados com SQLAlchemy (Flask) ou Django ORM.
- [ ] Tratei formulários (Flask-WTF/Django Forms) e conheci auth no Django.
- [ ] Organizei projeto com Blueprints (Flask) e apps (Django).
- [ ] Sei onde configurar .env, diferença WSGI/ASGI e caminho de deploy.
Portfólio e carreira
- [ ] Tenho 4 repositórios simples (CLI, API Flask, ETL Pandas, Scraper).
- [ ] Cada repo tem README, prints/GIF e (quando fizer sentido) testes.
- [ ] Criei conta no GitHub, sei clonar, commitar, dar push.
- [ ] Participei da comunidade (issue/PR simples, fórum, artigo curto).
- [ ] Sigo um roadmap de 90 dias e tenho um pitch de 60s.
Algo ficou para trás? Volte na seção correspondente, faça os ajustes necessários e marque a caixa. Ver seu progresso no papel não só ajuda na organização, também dá aquela motivação extra para seguir em frente. Imprima este trecho e acompanhe sua evolução!
5.2 Desafio: publicar um repositório hoje e pedir feedback
Meta do dia (30–60 min): subir um dos seus projetos (ex.: CLI To-Do), deixar o README claro e pedir feedback público.
Passo 1 — Preparar a pasta local
cd /caminho/para/seu/projeto
python -m venv .venv
# Ativar: .venv\Scripts\activate (Windows) | source .venv/bin/activate (macOS/Linux)
# Dependências (se tiver)
pip freeze > requirements.txt
# Git
git init
echo ".venv/" >> .gitignore
echo "__pycache__/" >> .gitignore
git add .
git commit -m "chore: estrutura inicial do projeto"
Passo 2 — Criar o repositório no GitHub
- No GitHub: New repository → nome claro (ex.:
todo-cli-python
) → Public → Create. - Copie a URL HTTPS do repo.
Conectar e enviar:
git branch -M main
git remote add origin https://github.com/<seu-usuario>/todo-cli-python.git
git push -u origin main
Se o push pedir senha: gere um PAT (Personal Access Token) nas configurações do GitHub e use-o como “senha”.
Passo 3 — Escrever um README objetivo
Crie/edite README.md
(modelo mínimo):
# CLI To-Do em Python
Gerencie tarefas no terminal com arquivo `tarefas.json`.
## Como rodar
1) python -m venv .venv
2) Ative a venv (.venv\Scripts\activate no Windows | source .venv/bin/activate no macOS/Linux)
3) pip install -r requirements.txt (se houver)
4) python todo.py add "Estudar funções"
5) python todo.py list
## Exemplos
- Adicionar: `python todo.py add "Ler PEP 8"`
- Listar: `python todo.py list`
- Concluir: `python todo.py done 1`
## Estrutura
- `todo.py`: comandos add/list/done
- `tarefas.json`: base local (criado automaticamente)
## Próximos passos
- Testes com pytest
- Tipagem com mypy
- Publicar um GIF do uso no terminal
Commit e push do README:
git add README.md
git commit -m "docs: adiciona README com instruções e exemplos"
git push
Passo 4 — Abrir uma Issue “Feedback”
No GitHub do projeto → Issues → New issue → Título: Feedback do projeto
→ descrição:
O que acha do projeto?
- O README está claro?
- O código é fácil de entender?
- Sugestões de testes, organização ou melhorias?
Obrigado por revisar! 🙌
Passo 5 — Pedir feedback em público (DIO/LinkedIn/contatos)
Mensagem curta (copie/cole/adapte):
Publiquei minha CLI To-Do em Python (iniciante).
README com exemplos e passos claros.
Pode dar um feedback? O que melhorar primeiro?
Repo: https://github.com/<seu-usuario>/todo-cli-python
Obrigado! 🙌 #Python #Iniciante #Portfólio
Próximos 7 dias (micro-plano)
- Dia 1: publicar o repo (passos acima).
- Dia 2: adicionar pytest (1–2 testes) e rodar
black
/ruff
. - Dia 3: melhorar README com prints/GIF.
- Dia 4: abrir Issue de roadmap (o que vem depois).
- Dia 5: pedir feedback para 3 pessoas diferentes.
- Dia 6: aplicar melhorias sugeridas (commits pequenos).
- Dia 7: escrever um post curto sobre o que aprendeu.
Conclusão: publicar cedo, pedir feedback e iterar rápido acelera sua evolução e sua empregabilidade. Você já tem base técnica, projeto, roteiro e materiais prontos. Agora, poste seu primeiro repositório hoje e me diga o link — posso revisar e sugerir os próximos passos.