Guia Prático: O que é o ".env" e como utilizá-lo em Python
Ao desenvolver aplicações em Python, é fundamental separar configurações e segredos (senhas, chaves de API, credenciais de banco de dados) do código-fonte. O arquivo .env é o padrão da indústria para gerenciar essas variáveis no ambiente local.
1. O que é um arquivo .env?
O .env é um arquivo de texto simples localizado na raiz do projeto, utilizado para definir variáveis de ambiente locais no formato chave-valor (CHAVE=VALOR).
Por que usá-lo?
- Segurança: Evita o hardcoding de segredos (chaves de API, tokens e senhas) diretamente no código.
- Portabilidade: Permite que diferentes membros da equipe ou ambientes (desenvolvimento, homologação, produção) usem configurações distintas sem alterar o código.
- Conformidade com o Twelve-Factor App: Segue o princípio III da metodologia The Twelve-Factor App, que preconiza o armazenamento de configurações estritamente no ambiente.
2. Estrutura e Sintaxe do .env
Crie um arquivo chamado exatamente .env (com o ponto na frente e sem extensão) na raiz do seu projeto.
Exemplo de .env:
# Configurações de Banco de Dados
DB_HOST=localhost
DB_PORT=5432
DB_USER=postgres
DB_PASSWORD=minha_senha_super_secreta
DB_NAME=sistema_rpa
# Configurações de API e Serviços
API_KEY=sk_test_1234567890abcdef
DEBUG=True
TIMEOUT_SECONDS=30
# URLs e Endpoints
SERVICE_URL=https://api.empresa.com.br/v1
Regras de sintaxe:
- Uma variável por linha no formato
NOME_VARIAVEL=valor. - Linhas iniciadas com
#são comentários. - Não use espaços ao redor do sinal de igual (
=). - Aspas simples ou duplas são opcionais, exceto quando o valor contiver espaços ou caracteres especiais:
SAUDACAO="Olá, mundo com espaços"
3. A Regra de Ouro: .gitignore e .env.example
O arquivo .env NUNCA deve ser commitado no repositório Git.
1. Adicione ao .gitignore
No arquivo .gitignore do seu repositório, inclua:
.env
.env.*
!.env.example
2. Crie um .env.example
Para que outros desenvolvedores saibam quais variáveis o projeto necessita para rodar, crie um arquivo .env.example (este sim deve ser commitado) contendo apenas os nomes das chaves e valores fictícios:
# .env.example
DB_HOST=localhost
DB_PORT=5432
DB_USER=
DB_PASSWORD=
DB_NAME=
API_KEY=
DEBUG=True
TIMEOUT_SECONDS=30
4. Instalando a biblioteca python-dotenv
No ecossistema Python, a biblioteca mais popular e leve para ler arquivos .env é a python-dotenv.
Instale via terminal:
pip install python-dotenv
5. Como usar no código Python
Método 1: Básico com os.getenv
A função load_dotenv() lê o arquivo .env e injeta as variáveis no dicionário de ambiente global do sistema operacional (os.environ).
import os
from dotenv import load_dotenv
# Carrega as variáveis contidas no .env para o os.environ
load_dotenv()
# Lendo as variáveis
db_host = os.getenv("DB_HOST")
db_port = os.getenv("DB_PORT", "5432") # '5432' é o valor padrão caso não exista
api_key = os.getenv("API_KEY")
# Atenção aos tipos: os.getenv SEMPRE retorna string ou None!
debug_mode = os.getenv("DEBUG", "False").lower() in ("true", "1", "yes")
timeout = int(os.getenv("TIMEOUT_SECONDS", "10"))
print(f"Conectando a {db_host}:{db_port}...")
print(f"Modo Debug: {debug_mode} (Tipo: {type(debug_mode)})")
print(f"Timeout: {timeout} segundos (Tipo: {type(timeout)})")
Método 2: Garantindo o caminho do .env
Em scripts automatizados ou tarefas executadas a partir de diretórios diferentes, o Python pode não encontrar o .env se você usar caminhos relativos. O ideal é resolver o caminho a partir de pathlib.Path:
import os
from pathlib import Path
from dotenv import load_dotenv
# Obtém o caminho absoluto da pasta raiz do projeto
BASE_DIR = Path(__file__).resolve().parent
# Caminho para o .env na raiz
dotenv_path = BASE_DIR / ".env"
# Carrega explicitamente o caminho especificado
load_dotenv(dotenv_path=dotenv_path)
print("DB_USER:", os.getenv("DB_USER"))
Método 3: Lendo diretamente em um dicionário (dotenv_values)
Se você preferir carregar as variáveis sem contaminar o ambiente do sistema operacional (os.environ), pode usar dotenv_values:
from dotenv import dotenv_values
config = dotenv_values(".env")
# config se comporta como um dicionário Python
print(config.get("DB_NAME"))
print(config.get("API_KEY"))
6. Abordagem Moderna: Validação e Tipagem com Pydantic Settings
Para projetos de médio e grande porte, a melhor prática em Python moderno é utilizar o pydantic-settings. Ele carrega o .env, faz a conversão automática de tipos (inteiros, booleanos, listas) e valida campos obrigatórios.
Instalação:
pip install pydantic-settings
Código:
from pydantic import Field, PostgresDsn
from pydantic_settings import BaseSettings, SettingsConfigDict
class AppSettings(BaseSettings):
# Campos obrigatórios: se não existirem no .env, lança ValidationError
db_host: str
db_port: int = 5432
db_user: str
db_password: str
db_name: str
api_key: str
# Campos com valores padrão
debug: bool = False
timeout_seconds: int = 30
# Configuração para ler automaticamente o .env
model_config = SettingsConfigDict(
env_file=".env",
env_file_encoding="utf-8",
case_sensitive=False
)
# Instanciação das configurações
settings = AppSettings()
# Acesso tipado e validado
print(f"Host: {settings.db_host} (Porta: {settings.db_port})")
print(f"Debug está ativo? {settings.debug}")
print(f"Tipo de timeout_seconds: {type(settings.timeout_seconds)}")
Vantagens do Pydantic Settings:
- Tipagem estrita:
timeout_secondsjá é convertido paraintedebugparabool. - Fail-fast: Se uma chave obrigatória faltar no
.env, a aplicação falha na inicialização com uma mensagem clara, em vez de quebrar no meio da execução. - Autocompletar na IDE: Facilita o desenvolvimento com sugestões do editor de código.
7. Boas Práticas e Recomendações de Segurança
| Prática | Descrição |
|---|---|
Nunca commitar o .env |
Mantenha .env no .gitignore para não vazar credenciais em repositórios remotos. |
Disponibilize .env.example |
Ajude outros desenvolvedores listando as variáveis necessárias sem valores reais. |
| Cuidado com Tipagem | Lembre-se que os.getenv() sempre retorna str ou None. bool("False") em Python avalia para True. |
| Produção vs Local | Em servidores de produção (ex.: containers Docker, Kubernetes, Cloud Run, VMs com Systemd), prefira injetar variáveis de ambiente nativas da infraestrutura em vez de usar arquivos .env. |
| Gerenciadores de Segredos | Para projetos corporativos com alta criticidade, utilize serviços como Google Secret Manager, HashiCorp Vault ou AWS Secrets Manager para segredos de produção. |