Skip to content
RFrftools.io

rftools Python Library

Programmatic access to all 255 RF & electronics calculators — typed functions, batch mode, async support, and a CLI. Free tier requires no API key.

bash
pip install rftools-io

Python 3.9+. Dependencies: httpx, pydantic, click. View on PyPI

Quick Start (free tier)

Requires an API key. Free tier: 5 calls/month — get one free at rftools.io/pricing.

python
import rftools

result = rftools.calculate('vswr-return-loss', {'vswr': 2.5})
print(f'Return Loss: {result["returnLoss"]:.2f} dB')   # 9.54 dB
print(f'Reflection Coeff: {result["reflectionCoeff"]:.3f}')  # 0.333

rftools.calculate() returns a dict-like CalculatorResult. Access outputs by key.

Typed Category Stubs

IDE-friendly typed functions with parameter names and defaults that match the rftools.io web UI. All 13 categories available.

python
from rftools.calculators import rf, antenna, pcb

# Parameter names and defaults match the rftools.io web UI
fspl = rf.free_space_path_loss(frequency=2400.0, distance=0.1)   # MHz, km
print(f'FSPL: {fspl["fspl_dB"]:.1f} dB')   # 80.1 dB

dipole = antenna.dipole_antenna(frequency=433.0)
print(f'Dipole length: {dipole["length"]:.0f} mm')

result = pcb.trace_width_current(current=2.0, tempRise=10.0, copperWeight=1.0)

Batch API

Run up to 50 calculations in a single HTTP request — ideal for parameter sweeps. Requires an API-tier key (10,000 calls/month). Get a key.

python
import rftools

client = rftools.Client(api_key='rfc_live_xxx')
# or: export RFTOOLS_API_KEY=rfc_live_xxx

distances = [10, 50, 100, 500, 1000]
results = client.batch([
    ('free-space-path-loss', {'frequency': 2400, 'distance': d / 1000})  # km
    for d in distances
])

for d, r in zip(distances, results):
    if r.ok:
        print(f'{d:>6} m  →  {r.values["fspl_dB"]:.1f} dB')

Solve for a Target

client.solve() finds the value of one input that brings an output to a target — the trace width that gives 50 Ω — and returns it with the forward result at exactly that value, computed by POST /api/py/v1/calculate/solve. One metered call. Available from rftools-io 0.4.0.

python
import rftools

client = rftools.Client(api_key='rfc_live_xxx')

# 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(f'{result.value:.3f} mm')                          # 2.781 mm
print(result.reached, result.evaluations)                # True 68
print(f'{result.result.values["impedance"]:.2f} Ω')       # 50.00 Ω
print(result.result.provenance.formula_ref)              # Hammerstad & Jensen (1980); ...

Client.solve(slug, inputs, solve_for, target_output, target_value, grid=None, range=None) returns a SolveResult with .value, .unrounded, .reached, .evaluations, .warnings and .result — the same CalculatorResult client.calculate() returns, provenance included, for the inputs with solve_for set to .value. A target the search cannot reach still returns normally, with .reached is False and the nearest value found, and still costs one call. See /docs/api for the request and response fields, the search range and the refusals.

Async Support

Use AsyncClient for FastAPI services, async Jupyter kernels, or concurrent sweeps.

python
import asyncio
import rftools

async def main():
    async with rftools.AsyncClient(api_key='rfc_live_xxx') as client:
        result = await client.calculate('vswr-return-loss', {'vswr': 2.5})
        print(result['returnLoss'])

asyncio.run(main())

CLI

The rftools command is installed automatically with the package.

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 version

Error Handling

python
from rftools.exceptions import AuthError, RateLimitError, ValidationError, NotFoundError

try:
    result = client.calculate('vswr-return-loss', {'vswr': 2.5})
except RateLimitError as e:
    print(f'Quota exceeded. Retry after {e.retry_after}s')
except AuthError:
    print('Invalid API key')
except NotFoundError:
    print('Unknown calculator slug')
except ValidationError as e:
    print(f'Bad inputs: {e.detail}')
ExceptionWhen
AuthErrorInvalid or missing API key
RateLimitErrorMonthly quota exceeded (has .retry_after attribute)
ValidationErrorBad inputs (HTTP 422) — has .detail attribute
NotFoundErrorUnknown calculator slug
APIErrorUnexpected HTTP error — has .status_code attribute

All 13 Categories

Import from rftools.calculators.

ModuleCount
rf36
pcb36
power23
signal14
antenna11
general24
motor22
protocol11
emc16
thermal6
sensor17
unit_conversion19
audio18
iot2

API Key

Set RFTOOLS_API_KEY to avoid passing it explicitly. The module-level helpers and Client() both read it automatically.

bash
export RFTOOLS_API_KEY=rfc_live_xxx

Get a key at /pricing. API tier: $19/mo, 10,000 calls/month.

Ready to automate?

Install the library, get a free API key, and run your first calculation in under a minute.

Or get a free API key (5 calls/month) — no credit card required.