perexchange
perexchange fetches live PEN/USD rates from Peruvian exchange houses.
Requires Python 3.10 or later.
Install
python -m pip install perexchange
Fetch rates
fetch_rates() runs the selected source adapters concurrently and returns the rates that
were fetched successfully:
import asyncio
import perexchange
async def main() -> None:
rates = await perexchange.fetch_rates(sources=["cambiafx", "tucambista"])
for rate in rates:
print(rate.source, rate.name, rate.buy_price, rate.sell_price)
asyncio.run(main())
With no sources argument, all registered sources are queried. Source names are matched
without regard to case, accents, spaces, or punctuation. kambioonline2 is an alias for
kambioonline.
An unknown or repeated source raises ConfigurationError before any request starts.
Invalid timeout and retry settings raise the same exception.
Fetch settings
async def fetch_rates(
sources: Sequence[str] | None = None,
*,
timeout: float = 10.0,
max_attempts: int = 3,
total_timeout: float | None = 30.0,
client: httpx.AsyncClient | None = None,
) -> list[ExchangeRate]:
timeoutlimits each HTTP request.max_attemptsis the total number of attempts for each source, including the first.total_timeoutlimits one source operation, including retries and backoff. Set it toNoneto disable that limit.- Transport errors and
408,429, and5xxresponses are retried. Other4xxresponses and parse errors are not. - A numeric
Retry-Aftervalue for429is honored up to 30 seconds. - If you pass a client,
perexchangeleaves it open. Otherwise it creates and closes a client for the call.
Some sources need more than one request. One attempt repeats that source's full operation.
Failures
fetch_rates() leaves sources that fail out of its result. Use fetch_rates_report()
when the caller needs to distinguish an empty result from sources that failed:
report = await perexchange.fetch_rates_report()
for failure in report.failures:
print(f"{failure.source}: {failure.message}")
Expected network, timeout, and parse failures are recorded in report.failures. Other
exceptions are raised so programming errors are not hidden.
ConfigurationError is available from the top-level perexchange module for callers that
need to catch invalid source selections or fetch settings.
Results keep source selection order. A repeated (source, name) pair keeps its first
value. The aggregator's rows for sources with a dedicated adapter are removed from the
final result.
Version 2.0 changes
ExchangeRaterequires asourcefield.fetch_rates()andfetch_rates_report()usesourcesinstead ofhouses.max_retriesis nowmax_attempts.- Source failures are available through
fetch_rates_report().
ExchangeRate
ExchangeRate is an immutable dataclass with these fields:
source: the stable source ID, such ascambiafx.name: the display name returned by the source. It can include a quote tier such astkambio_5000.buy_price: PEN needed to buy one USD.sell_price: PEN received for selling one USD.timestamp: a timezone-awaredatetimefrom the source or the time of the fetch.
The spread property is sell_price - buy_price.
Metadata
Release files for perexchange 2.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| perexchange-2.0.0.tar.gz | 22.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| perexchange-2.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 59.0 kB
Release files / perexchange-2.0.0.tar.gz
| Download URL | perexchange-2.0.0.tar.gz |
|---|---|
| Size | 22.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
809895af2ea97076ce81eb4e70c7da3f106c1754793cef78776183dd042fce62
|
|
BLAKE2b-256 checksum How to use checksums |
141566858592dd8abf13a063f6dc6d47cd379a28cb09a6975a35f864a9704e35
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 30, 2026.
Transparency logRelease files / perexchange-2.0.0-py3-none-any.whl
| Download URL | perexchange-2.0.0-py3-none-any.whl |
|---|---|
| Size | 36.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e57e8b0561c5b7ee1035106e6a054bd9492153b0ad1f26993525b390b20abcdf
|
|
BLAKE2b-256 checksum How to use checksums |
25e0e6447f72b1f43c430660ded1dad6bc294329bab9a7d6bacdd68fbd041e74
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 30, 2026.
Transparency log