Wilberhg's blog

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?


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:

  1. Uma variável por linha no formato NOME_VARIAVEL=valor.
  2. Linhas iniciadas com # são comentários.
  3. Não use espaços ao redor do sinal de igual (=).
  4. 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:


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.

#.env #automation #env #environment #passwords #python #secrets