HTTP automation package for DTP and DAMSP portals.
Project description
botdtp
Pacote de automacao para os portais SGPT e DAMSP da Prefeitura de Sao Paulo.
O que o projeto entrega
SGPTBot: login, alteracao de senha, comprovante de inspecao, aprovacao/reprovacao e relatorios.DAMSPBot: fluxos CPF/CNPJ, emissao de licenca PF/PJ e guia PF/PJ.HTTPClient+HTTPConfig: retry, timeout, proxy, sleep entre requests e sessao.- Persistencia de sessao em arquivo (
SessionStore) com TTL (SGPT). - Janela de acesso configuravel por dia/hora/fuso (SGPT).
Arquitetura (serie 0.3.x)
A arquitetura foi separada por camadas para facilitar manutencao, testes e evolucao:
botdtp.core: contratos centrais (Operacao, contexto), erros compartilhados e politica de acesso SGPT.botdtp.sgpt: autenticacao, operacoes de inspecao e relatorios do SGPT.botdtp.damsp: fluxos CPF/CNPJ, regras de servico/modalidade e resolucao de captcha.http_ops: transporte HTTP generico (session, retry, timeout, proxy e persistencia opcional).aspx_ops: operacoes ASPX reutilizaveis (__VIEWSTATE, postback, timeline e navegacao).
Essa separacao permite evoluir fluxos de negocio sem acoplar com detalhes de transporte e WebForms.
Requisitos
- Python
>=3.11
Instalacao
pip install botdtp
Dependencias
Dependencias diretas do pacote (em pyproject.toml):
requests>=2.32.0beautifulsoup4>=4.12.0lxml>=5.2.0pillow>=10.0.0langchain-core>=0.3.0langchain-openai>=0.2.0validate-docbr>=1.11.1xhtml2pdf>=0.2.17
Contrato padrao de retorno
Toda operacao retorna Operacao:
ok: boolmensagem: strdata: dict
Comportamento em falha:
- Operacoes publicas de
BoteClientretornamOperacao(ok=False, ...). - Nao ha propagacao de excecao para o chamador nesse contrato padrao.
- Em erros,
dataincluioperacao,classeedetalhe.
Uso de alto nivel (recomendado)
SGPTBot
from botdtp import SGPTBot
from botdtp.sgpt import (
SGPTLoginInput,
SGPTAlterarSenhaInput,
SGPTComprovanteInspecaoInput,
SGPTAprovacaoEscolarAnualInput,
SGPTAprovacaoEscolarSemestralInput,
SGPTAprovacaoTaxiInput,
SGPTReprovacaoEscolarAnualInput,
SGPTReprovacaoEscolarSemestralInput,
SGPTReprovacaoTaxiInput,
SGPTReprovacaoItemInput,
SGPTRelatorioInput,
)
login = SGPTLoginInput(
base_url="https://vistoriadtp.prefeitura.sp.gov.br",
codigo_empresa="CODIGO_DA_EMPRESA",
usuario="USUARIO",
senha="SUA_SENHA",
)
sgpt = SGPTBot(login=login, reautenticar=True)
sgpt.autenticar(login)
sgpt.alterar_senha(
SGPTAlterarSenhaInput(
base_url="https://vistoriadtp.prefeitura.sp.gov.br",
codigo_empresa="0035",
usuario="123456",
senha_atual="SENHA_ATUAL",
nova_senha="SENHA_NOVA",
confirmacao_nova_senha="SENHA_NOVA",
)
)
sgpt.gerar_comprovante_inspecao(
SGPTComprovanteInspecaoInput(
numero_guia="055721",
ano_guia="2026",
resultado="APROVADA",
),
destino="tmp",
)
sgpt.aprovar_escolar_anual(
SGPTAprovacaoEscolarAnualInput(
placa="ABC1234",
licenca="12345678",
inspetor_codigo="111",
inspetor_nome="INSPETOR",
rt_codigo="222",
rt_nome="RESPONSAVEL TECNICO",
ano_guia="0000",
numero_guia="00000",
validade_extintor="00/0000",
sn_tacografo="S",
),
destino="tmp",
)
sgpt.aprovar_escolar_semestral(
SGPTAprovacaoEscolarSemestralInput(
placa="ABC1D23",
licenca="12345678",
inspetor_codigo="111",
inspetor_nome="INSPETOR",
rt_codigo="222",
rt_nome="RESPONSAVEL TECNICO",
validade_extintor="12/2026",
sn_tacografo="S",
),
destino="tmp",
)
sgpt.aprovar_taxi(
SGPTAprovacaoTaxiInput(
placa="ABC1234",
licenca="12345678",
inspetor_codigo="111",
inspetor_nome="INSPETOR",
rt_codigo="222",
rt_nome="RESPONSAVEL TECNICO",
ano_guia="2026",
numero_guia="055721",
radio_taxi_cod="",
radio_taxi_nome="",
),
destino_comprovante="tmp",
)
itens = [
SGPTReprovacaoItemInput(
grupo="X",
item="X",
subitem="X",
valor="X",
opcao="X",
descricao="XXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
)
]
sgpt.reprovar_escolar_anual(
SGPTReprovacaoEscolarAnualInput(
placa="ABC1234",
licenca="12345678",
inspetor_codigo="111",
inspetor_nome="INSPETOR",
rt_codigo="222",
rt_nome="RESPONSAVEL TECNICO",
ano_guia="2026",
numero_guia="055721",
itens_reprovacao=itens,
)
)
sgpt.reprovar_escolar_semestral(
SGPTReprovacaoEscolarSemestralInput(
placa="ABC1D23",
licenca="12345678",
inspetor_codigo="111",
inspetor_nome="INSPETOR",
rt_codigo="222",
rt_nome="RESPONSAVEL TECNICO",
itens_reprovacao=itens,
)
)
sgpt.reprovar_taxi(
SGPTReprovacaoTaxiInput(
placa="ABC1234",
licenca="12345678",
inspetor_codigo="111",
inspetor_nome="INSPETOR",
rt_codigo="222",
rt_nome="RESPONSAVEL TECNICO",
ano_guia="2026",
numero_guia="055721",
itens_reprovacao=itens,
)
)
sgpt.gerar_relatorio_inspecoes(
SGPTRelatorioInput(
mes=5,
ano=2026,
modalidade="E", # C, E, F, T ou M
resultado="", # "", A, P ou R
),
destino="tmp",
nome_arquivo="relatorio_sgpt_maio_2026",
salvar_html=True,
)
Politica de autenticacao SGPT:
- Login obrigatorio: passe
login=SGPTLoginInput(...)ao instanciar o bot. - Manual: use
sgpt.autenticar(...)para renovar explicitamente a sessao. - Gerenciada: com
reautenticar=True, o bot tenta reautenticar ao detectarSGPTAuthenticationError. - Sessao:
SGPTBotrestaura/salva cookies viaSessionStore.
DAMSPBot
from botdtp import DAMSPBot
from botdtp.damsp import (
DAMSPCPFInput,
DAMSPCPFGuiaInput,
DAMSPCNPJInput,
DAMSPCNPJGuiaInput,
DAMSPModalidadeVeiculoEnum,
DAMSPServicoEscolarEnum,
DAMSPServicoTaxiEnum,
OpenAICaptchaSolver,
)
damsp = DAMSPBot(captcha_solver=OpenAICaptchaSolver(api_key="SUA_OPENAI_KEY"))
# 1) Iniciar fluxo CPF
damsp.iniciar_fluxo_cpf(
DAMSPCPFInput(
cpf="529.982.247-25",
licenca="123.456-78",
modalidade=DAMSPModalidadeVeiculoEnum.TAXI,
)
)
# 2) Iniciar fluxo CNPJ
damsp.iniciar_fluxo_cnpj(
DAMSPCNPJInput(
cpf_responsavel="529.982.247-25",
numero_empresa="123456",
licenca="123.456-78",
modalidade=DAMSPModalidadeVeiculoEnum.ESCOLAR,
)
)
# 3) Gerar licenca PF
damsp.gerar_licenca_pf(
DAMSPCPFInput(
cpf="529.982.247-25",
licenca="123.456-78",
modalidade=DAMSPModalidadeVeiculoEnum.TAXI,
),
destino="tmp",
)
# 4) Gerar licenca PJ
damsp.gerar_licenca_pj(
DAMSPCNPJInput(
cpf_responsavel="529.982.247-25",
numero_empresa="123456",
licenca="123.456-78",
modalidade=DAMSPModalidadeVeiculoEnum.ESCOLAR,
),
destino="tmp",
)
# 5) Gerar guia PF
damsp.gerar_guia_pf(
DAMSPCPFGuiaInput(
cpf="529.982.247-25",
licenca="123.456-78",
codigo_servico=DAMSPServicoTaxiEnum.RENOVACAO_ALVARA,
modalidade=DAMSPModalidadeVeiculoEnum.TAXI,
),
destino="tmp",
)
# 6) Gerar guia PJ
damsp.gerar_guia_pj(
DAMSPCNPJGuiaInput(
cpf_responsavel="529.982.247-25",
numero_empresa="123456",
licenca="123.456-78",
codigo_servico=DAMSPServicoEscolarEnum.RENOVACAO_CRM,
modalidade=DAMSPModalidadeVeiculoEnum.ESCOLAR,
),
destino="tmp",
)
Uso de baixo nivel (infra)
import requests
from botdtp import HTTPClient, HTTPConfig, DAMSPBot
http = HTTPClient(config=HTTPConfig(), session=requests.Session())
damsp = DAMSPBot(http=http)
Captcha DAMSP
botdtp.damsp.captcha contem:
OpenAICaptchaSolver(automatico via OpenAI/LangChain)ManualCaptchaSolver(entrada manual)OpenAICaptchaConfigconverter_para_bytes_png
Configuracao recomendada:
- Forneca
api_keyexplicitamente emOpenAICaptchaSolver. - Ajuste preset do modelo via
OpenAICaptchaConfig(model=..., max_tokens=..., temperature=...). - Se usar env, resolva no bootstrap da aplicacao e injete os valores no construtor.
Janela de acesso (SGPT) e sessao
Janela padrao: segunda a sabado (1,2,3,4,5,6), 07:00 ate 20:00, fuso America/Sao_Paulo.
Personalizacao via codigo:
- Janela: passe
ControleAcessoConfig(...)ao criarSGPTBot. - Persistencia em arquivo: disponivel no
SGPTBotviaSessionPersistenceConfig(...). DAMSPBot: sem persistencia em disco; cada operacao refaz o fluxo de identificacao do perfil (PF/PJ).- HTTP: use
HTTPConfig(...)com timeout, retry, proxy e trace conforme necessidade.
Scripts de runtime e testes
Exemplos de runtime:
examples/runtime_sgpt_smoke.pyexamples/runtime_sgpt_alterar_senha_smoke.pyexamples/runtime_sgpt_relatorio_smoke.pyexamples/runtime_damsp_licenca_pf_smoke.pyexamples/runtime_damsp_licenca_pj_smoke.pycli/sgpt_menu_cli.pycli/sgpt_menu_config.example.jsoncli/damsp_menu_cli.pycli/damsp_menu_config.example.jsonexamples/django_adapter_example.py
Testes:
pytest -q
Publicacao da versao 0.3.0
Checklist recomendado para publicar a 0.3.0 refletindo a nova arquitetura:
- Atualize versao e metadados no
pyproject.toml(version = "0.3.0"). - Garanta que este README reflita a API publica atual e a divisao por camadas.
- Registre mudancas de migracao no release notes (ex.: rename de metodos DAMSP de guia para
gerar_guia_pfegerar_guia_pj). - Execute a suite local:
pytest -q
- Gere os artefatos:
python -m build
- Valide distribuicoes:
python -m twine check dist/*
- Publique (preferencialmente validando antes no TestPyPI):
python -m twine upload dist/*
- Crie tag e release:
git tag v0.3.0git push origin v0.3.0
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file botdtp-0.3.0.tar.gz.
File metadata
- Download URL: botdtp-0.3.0.tar.gz
- Upload date:
- Size: 71.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7c44064e922f0f1e39a85666e77e499260a93811467e193e94052eb75e9711f4
|
|
| MD5 |
91bf6b0be41f13e6e80c499b5e1a9337
|
|
| BLAKE2b-256 |
9d7a9ac2ffc88ecd0fab78c746db9b989df0019410d5cbc7ecdf609af572e80d
|
File details
Details for the file botdtp-0.3.0-py3-none-any.whl.
File metadata
- Download URL: botdtp-0.3.0-py3-none-any.whl
- Upload date:
- Size: 73.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3db8bdfa2de2f6735c431e56b02700f61241cc546ecd82a18bca4191be2bd7d1
|
|
| MD5 |
c22c22863b669176aa693c41eeafedd1
|
|
| BLAKE2b-256 |
530e74f36f85c06a06eb1253add89160b878887d81e43261875aca7c15c3b6d6
|