Seções da documentação
Biblioteca Python rftools
Acesso programático a todas as 255 calculadoras de RF e eletrônica e aos trabalhos de simulação: funções tipadas, chamadas em lote, resolução para um valor-alvo, suporte assíncrono e uma CLI. Toda chamada precisa de uma chave; uma gratuita cobre 5 chamadas por mês.
Instalação
pip install rftools-io. Python 3.12 ou mais recente; ela traz httpx, pydantic e click. Ver no PyPI.
Chave de API
rftools login (ou rftools.Client().login()) mostra uma página e um código: abra a página, entre, aprove o código, e a chave é salva no arquivo de credenciais do seu usuário, que só você pode ler. Ou defina RFTOOLS_API_KEY, que tem prioridade. rftools.Client() e os auxiliares no nível do módulo leem qualquer um dos dois; um api_key= explícito tem prioridade sobre ambos. As chaves começam com rfc_; veja Autenticação.
Início rápido
rftools.calculate() devolve um CalculatorResult: leia as saídas pelo nome, ou .values, .warnings e .provenance.
Stubs tipados por categoria
Um módulo por categoria de calculadora, uma função por calculadora, com nomes de parâmetros e padrões iguais aos das páginas web. Um slug vira um nome de função com - trocado por _, e um nome que começaria com um dígito recebe o prefixo calc_.
| Módulo | Calculadoras | Por exemplo |
|---|---|---|
rftools.calculators.rf | 36 | rf.calc_5g_nr_band_lookup(), rf.calc_5g_nr_link_budget() |
rftools.calculators.pcb | 36 | pcb.aperture_diagonal(), pcb.asymmetric_stripline() |
rftools.calculators.power | 23 | power.battery_charge_time(), power.battery_internal_resistance() |
rftools.calculators.signal | 14 | signal.adc_snr(), signal.am_modulation_index() |
rftools.calculators.antenna | 11 | antenna.antenna_beamwidth(), antenna.antenna_downtilt() |
rftools.calculators.general | 24 | general.calc_555_timer(), general.bjt_bias_point() |
rftools.calculators.motor | 22 | motor.battery_runtime_motor(), motor.bldc_efficiency() |
rftools.calculators.protocol | 11 | protocol.can_bus_timing(), protocol.clock_jitter() |
rftools.calculators.emc | 16 | emc.cable_shield_effectiveness(), emc.chassis_resonance() |
rftools.calculators.thermal | 6 | thermal.heatsink_calculator(), thermal.heatsink_selection() |
rftools.calculators.sensor | 17 | sensor.calc_4_20ma_transmitter(), sensor.accelerometer_sensitivity() |
rftools.calculators.unit_conversion | 19 | unit_conversion.angle_units(), unit_conversion.awg_wire() |
rftools.calculators.audio | 18 | audio.amplifier_clipping(), audio.audio_adc_snr() |
rftools.calculators.iot | 2 | iot.ble_link_budget(), iot.lora_link_budget() |
Resolver para um valor-alvo
client.solve() encontra o valor de uma entrada que leva uma saída a um alvo e o devolve com o resultado direto calculado exatamente nesse valor, por POST /api/py/v1/calculate/solve. Uma chamada contabilizada. Disponível a partir do rftools-io 0.4.0.
import rftools
client = rftools.Client()
# The trace width that reaches 50 Ω on 1.51 mm FR-4, rounded to a 0.001 mm grid
result = client.solve(
"microstrip-impedance",
{"substrateHeight": 1.51, "dielectricConstant": 4.5, "copperThickness": 35},
"traceWidth", "impedance", 50,
grid=0.001,
)
print(result.value, result.reached, result.evaluations)
print(result.result.values["impedance"])Client.solve(slug, inputs, solve_for, target_output, target_value, grid=None, range=None) devolve um SolveResult com .value, .unrounded, .reached, .evaluations, .warnings e .result, o mesmo CalculatorResult que client.calculate() devolve para as entradas com solve_for definido como .value. Um alvo que a busca não consegue atingir ainda devolve um resultado, com .reached False e o valor mais próximo encontrado, e ainda custa uma chamada. Veja Resolver para um valor-alvo para os campos, a faixa de busca e as recusas.
Lote
Até 50 cálculos em uma requisição, para varreduras; uma chamada por item calculado. O endpoint em lote faz parte do plano API; veja os preços (API $19 por mês, 10.000 chamadas).
results = client.batch([
("vswr-return-loss", {"vswr": 1.5}),
("vswr-return-loss", {"vswr": 2.0}),
("free-space-path-loss", {"frequency": 2400, "distance": 0.05}),
])
for r in results:
print(r.values if r.ok else r.error)Uso
A cota mensal pertence à conta; todas as chaves da conta consomem dessa mesma cota.
usage = client.usage() # GET /v1/usage, never metered
print(usage.used, "of", usage.allowance, "used; resets", usage.reset_at)
for key in usage.keys:
print(key.key_id, key.label, key.used)
result = client.calculate("vswr-return-loss", {"vswr": 2.5})
print(result.usage.remaining) # from this response's X-Usage-* headersTrabalhos de simulação
Parâmetros e arquivos são verificados localmente contra o contrato do tipo de trabalho antes de qualquer envio. Um trabalho que termina em failed lança JobFailed com o seu errorKind em .kind. Veja Trabalhos de simulação.
job = client.submit_job("sat_link_budget", {"latitude_deg": 40.7, "longitude_deg": -74.0})
job = job.wait(timeout=600) # polls as the web app does
print(job.status, job.result()) # a summary; job.result(full=True) for all of it
est = client.estimate_job("fdtd_sparam", {"traceW": 0.42, "subH": 0.51, "solveMode": "express"})
print(est.lane, est.within_budget) # never charged, no key neededSuporte assíncrono
AsyncClient para serviços FastAPI, notebooks assíncronos ou varreduras concorrentes.
import asyncio
import rftools
async def main():
async with rftools.AsyncClient() as client:
result = await client.calculate("vswr-return-loss", {"vswr": 2.5})
print(result["returnLoss"])
asyncio.run(main())CLI
O comando rftools é instalado junto com o pacote.
rftools login # get a key; saved, never printed
rftools calc vswr-return-loss --vswr 2.5
rftools calc vswr-return-loss --vswr 2.5 --json | jq .values
rftools list --category rf
rftools info free-space-path-loss
rftools solve microstrip-impedance --for traceWidth --target impedance=50 --grid 0.001 \
--param substrateHeight=1.51 --param dielectricConstant=4.5 --param copperThickness=35
rftools sim fdtd_sparam --param solveMode=express --no-wait
rftools estimate fdtd_sparam --param traceW=0.42 --param subH=0.51
rftools versionTratamento de erros
Os erros são classificados pelo status HTTP, nunca pelo texto da mensagem. Um 500, 502, 503, 504 é repetido com espera progressiva antes de ser lançado. Veja Erros.
| Exceção | Lançada para |
|---|---|
| ValidationError | HTTP 400, 422 |
| AuthError | HTTP 401, 403 |
| QuotaError | HTTP 402 |
| NotFound | HTTP 404 |
| APIError | HTTP 409, 500, 503 |
| RateLimitError | HTTP 429 |
| JobFailed | Um trabalho que terminou em failed; .kind é o seu errorKind. |
| LoginError | rftools login não entregou nenhuma chave; .error é access_denied ou expired_token. |
Pronto para automatizar?
Instale a biblioteca, obtenha uma chave gratuita e rode um primeiro cálculo em menos de um minuto. A API REST por trás dela está documentada na referência da API.