shade-sdk
O runtime e o framework dos robôs da ShadeOne. O robô gerado pela plataforma importa este
pacote, na versão fixada pelo requirements.lock da imagem do sandbox, e o robô escrito à mão
importa o mesmo pacote: um runtime só, para os dois. O import é shade_sdk.
from decimal import Decimal
from pydantic import BaseModel, Field
from shade_sdk import Alvo, Item, Pagina, Retentativa, Robo
class Pedido(BaseModel):
cliente: str = Field(min_length=1)
valor: Decimal = Field(gt=0)
class TelaDePedido(Pagina):
url = "/pedidos/novo" # relativa ao [config] base_url
pronta = Alvo(papel="heading", nome="Novo pedido") # abrir() espera por ela
cliente = Alvo(rotulo="Cliente")
salvar = Alvo(papel="button", nome="Salvar")
class CadastroDePedido(Robo):
chave = ("cliente", "pedido") # a chave de negócio do item
modelo = Pedido # o item inválido fica retido antes de abrir o navegador
retentativas = Retentativa(sistema=3) # erro de sistema repete; negócio nunca
def entrar(self, pagina) -> None: # opcional: ao abrir a sessão e se ela cair
...
def processar(self, item: Item[Pedido], pagina) -> None:
tela = TelaDePedido(pagina)
with item.etapa("preencher"): # tempo, resultado e erro no relatório
tela.abrir()
tela.cliente.fill(item.dados.cliente) # item.dados é o Pedido validado
with item.efetivar("salvar pedido"): # o ensaio para aqui; o real registra antes
tela.salvar.click()
main.py na raiz do projeto: CadastroDePedido.main(). Sem flag, roda em modo real, como o
robô gerado; --rehearsal é o ensaio. A entrada é --input <arquivo>, ou data/input.json
(onde a plataforma a deixa), ou [itens] exemplo do shade.toml: JSON, CSV (o delimitador é
detectado) ou XLSX ([itens] aba escolhe a aba). Planilha chega como texto, e o modelo
converte.
Com [itens] fonte = "fila", o run real pega cada item da fila hospedada pelo executor da
plataforma, um por vez, e o fecha com o desfecho (a chave do item é o id que o servidor
entregou). A queda no meio de um item o devolve pelo efeito: sem efeito, volta para a fila; com
o efeito em voo, fica retido para conferência. --input e o ensaio leem o arquivo (o ensaio
nunca pega item da fila do cliente), e o run real sem o executor e sem --input para com
ErroDeContrato.
Robo(uma lista de itens) eTarefa(uma execução única,executar(item, pagina)).Item:item.dados(a instância domodelo, ou a linha),item["campo"](a linha como veio),item.chave,with item.efetivar(nome),with item.etapa(nome),item.saida(**campos),item.reter(motivo),item.log(texto).modelo = <pydantic.BaseModel>: cada item é validado antes de abrir o navegador; o inválido fica retido com o campo e a regra (sem o valor), e sem item válido o navegador nem abre.Pagina(url,pronta,abrir(),esperar_pronta()) eAlvo(papel=, nome=),Alvo(rotulo=),Alvo(test_id=),Alvo(texto=)e, por último,Alvo(css=): oLocatordo Playwright (tela.salvar.click();tela.salvar.locatoré o cru). Quando a ação falha,ErroDoAlvodiz o alvo, a URL (sem a query), se não achou nada, se achou mais de um (e quais) ou em que elemento caiu, e os candidatos parecidos.diagnosticar(pagina, alvo)dá o mesmo texto sem agir.shade_sdk.entradas.ler_entrada(caminho, aba=None): os itens de um JSON, CSV ou XLSX.Retentativa(sistema=N, espera=Exponencial(base, teto), sessao_perdida="reentrar" | "falhar"): a política por classe de falha. Negócio nunca repete, e nada repete depois do__enter__deefetivar().ao_falhar = "seguir" | "parar" | "pausar" | "pausar_run": o que o lote faz com o item que falhou depois daRetentativa."seguir"(o padrão) passa ao próximo;"parar"termina o lote e sai com 1;"pausar"esperaRECOVERY_PAUSE_Ssegundos por uma pessoa e segue;"pausar_run"pausa o run para uma decisão humana na plataforma e sai com 0. Na fila, as duas que saem fecham o item com a falha antes.- O item que falha deixa a tela e o trecho do trace do Playwright em
evidencias/<sha256 da chave>/, com teto por item e por run e os dados do item mascarados (SHADE_MASCARAR_PII=0desliga); o que passa não guarda nada. shade_sdk.http:http.geta qualquer momento;http.post,put,patchedeletesó dentro deefetivar()(fora,ErroDeContrato; no ensaio, nada sai), comIdempotency-Keyderivada da chave do item, do nome da efetivação e da ordem da escrita no bloco (numTarefa, comidempotencia=). Host fora de[hosts] permitidosé recusado antes de qualquer byte, timeout sempre finito, e só repete quando a rede recusou antes do envio.http.NadaSaiu(certamente sem efeito:desfazer_se=(http.NadaSaiu,)devolve o item à fila) ehttp.ResultadoIncerto(pode ter gravado: o item fica retido). É fidelidade, não segurança: na plataforma, quem barra o host é o proxy da allowlist.self.segredo(nome): só a credencial declarada em[credenciais] nomes;self.config: a tabela[config].- Erros:
ErroDeNegocio(não repete),SessaoPerdida(entra de novo e refaz),ErroDeContrato, e os sinaisParadaDoEnsaioeItemRetido(BaseException: umexcept Exceptionnão os engole). shade_sdk.plugins: o contrato dos pacotesshade-plugins-<nome>.Plugin(nome, versao, shade_sdk=..., dono=..., hosts=[...], credenciais=[...])declara o plugin, que se registra no entry pointshade_sdk.plugins;@plugin.operacao(sem efeito) e@plugin.efeito(só dentro deefetivar(), fora deleErroDeContrato; no ensaio nem roda). A operação recebe aChamadaprimeiro:chamada.timeout(toda chamada aceitatimeout=, sempre finito),chamada.idempotencia(derivada da chave do item, do nome da efetivação, do plugin, da operação e da ordem no bloco: a mesma em toda execução do item),chamada.segredo(nome)(só credencial declarada pelo plugin e pelo projeto) echamada.destino(host)(para o protocolo que não é oshade_sdk.http). Dentro da operação, oshade_sdk.httprecusa o host que o plugin não declara. Cada chamada vira um evento no log do run: plugin, operação, hosts, duração e status, sem argumento, corpo nem mensagem de erro.shade_sdk.testing.plugins.ContratoDePlugin: a suíte de contrato que todo plugin passa (declaração, efeito fora deefetivar(), egresso só para os hosts declarados, timeout, credencial só porsegredo(), idempotência, um evento por chamada sem corpo nem credencial e, com o robô em subprocesso, o ensaio sem efeito e o kill no meio do efeito sem duplicata).dentro_de_efetivar(chave)roda uma operação com efeito num teste de unidade.shade_sdk.testing:ExecutorLocal(o lado do executor do protocolo, com o robô em subprocesso, eex.fila, a fila hospedada do lado do servidor) epagina_local(um site local que conta os efeitos, do formulário e da API JSON, com aIdempotency-Keyde cada chamada).
O runtime:
shade_sdk.runtime.laco: o laço por item (ledger, retomada, política de retentativa,efetivar, etapas, resumo).shade_sdk.runtime.evidencia: o trace por item, a tela, a máscara e os tetos.shade_sdk.runtime.ledger: identidade do item por chave de negócio, oincertogravado antes de efetivar e o canal do registro com o executor.shade_sdk.runtime.fila: opegare ofecharda fila hospedada, pelo mesmo canal.shade_sdk.runtime.recovery: classificação da falha, sessão perdida e modal inesperado.shade_sdk.runtime.report: relatório HTML da execução e o histórico.shade_sdk.runtime.config:Settingse a carga do.env.shade_sdk.runtime.output: a planilha de saída, com ou sem mascaramento de PII.shade_sdk.runtime.protocolo: o número e o formato do contrato robô ↔ executor, inclusive a entrada (main.py, argv e ambiente).
Testes do pacote: cd sdk && uv run pytest (Chromium do Playwright instalado).
Licença: Apache-2.0.
Metadata
Release files for shade-sdk 0.13.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| shade_sdk-0.13.0-py3-none-any.whl | Python 3 | none | any | Details |
Release files / shade_sdk-0.13.0-py3-none-any.whl
| Download URL | shade_sdk-0.13.0-py3-none-any.whl |
|---|---|
| Size | 131.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
61545cb31ee61781e9e3474a63688fbcd21c2190df420b5f193e0c7b6f1ff4f9
|
|
BLAKE2b-256 checksum How to use checksums |
8e28e1ace854c9195f1d42012cd46561a188664f3b3fa1c3ba37820f6f393bbc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Security for shade-sdk 0.13.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.