Skip to main content

palanor

The Python client for Palanor Data: the signals, Custom Indices and refined datasets of the Palanor lattice, with the provenance of every value kept on the result.

  • One typed client over the REST API at https://api.palanor.com/v1
  • Pages are followed for you; max_rows caps a long read
  • Retries with exponential backoff on transient errors (429, 502, 503, 504, database timeouts)
  • to_pandas() on every result, with provenance kept in df.attrs
  • Python 3.9+, one dependency (httpx); pandas is optional

Install

pip install "https://palanor.com/developers/python/palanor-0.1.0-py3-none-any.whl"
# with DataFrames:
pip install "palanor[pandas] @ https://palanor.com/developers/python/palanor-0.1.0-py3-none-any.whl"

Mint a free key at palanor.com/api-tokens (1,000 requests a month, no card), then:

export PALANOR_API_KEY="plnr_..."

Quickstart

from palanor import Palanor

p = Palanor()  # reads PALANOR_API_KEY; or Palanor(api_key="plnr_...")

# A series over a window: every page joined, oldest first
spread = p.signals.observations("rates.spread_2y10y", start="2020-01-01", end="2024-12-31")
print(len(spread), spread.observations[-1])
print(spread.provenance.attribution)      # the credit line owed when you show it

df = spread.to_pandas()                   # DatetimeIndex, one "value" column
df.attrs["provenance"]["license_class"]   # 'public_domain'

# The latest reading, and where it stands in its own record
cpi = p.signals.get("bls_cpi_college_tuition", history=12)
cpi.latest.value, cpi.latest.date, cpi.context["percentile"]

What you can read

Method Endpoint Notes
p.signals.list(category=None) /v1/signals Every public signal the API serves, each row with provenance
p.signals.get(slug, history=30, vintage="latest") /v1/signals/{slug} Definition, latest, context, up to 365 recent observations
p.signals.latest(slug) /v1/signals/{slug} Just the latest observation
p.signals.observations(slug, start, end, vintage="latest") /v1/signals/{slug}/observations Any window, paged in 1,000s
p.indices.list() / p.currents.list() /v1/indices, /v1/currents Palanor Custom Indices; the Currents
p.guidance.list(ticker=, metric=, since=) /v1/guidance Guidance Ledger
p.risk_factors.list(ticker=, since=, category=, change_type=) /v1/risk-factors 10-K risk factor changes
p.events.list(ticker, items=, since=, until=) /v1/events Material events from 8-K item codes
p.insiders.list(ticker, since=, codes=) /v1/insiders Forms 3, 4, 5
p.ownership.get(ticker, period=, limit=) /v1/ownership 13F holders and 13D/G 5% owners
p.compensation.get(ticker) /v1/compensation Pay versus performance
p.fails.get(ticker, since=) /v1/fails SEC fails-to-deliver (not short interest)
p.contracts.get(ticker) / p.lobbying.get(ticker) / p.patents.get(ticker) /v1/contracts, /v1/lobbying, /v1/patents USAspending, LDA, USPTO
p.industries.sectors() / .search(q) / .get(naics) /v1/industries US industry sizing (Census, BEA, BLS)
p.release_calendar.list(start, end) /v1/release-calendar US economic release calendar
p.almanac.list() / p.wire.list() /v1/almanac, /v1/wire Almanac posts; the Wire (Pro keys)
p.get(path, **params) anything Raw access to any endpoint

Company datasets cover the S&P 500 and take a ticker ("AAPL") or cik=.

own = p.ownership.get("AAPL", limit=10)
own.to_pandas()                     # the 13F holders, largest first
own["five_percent_holders"]         # read any field like a dict
own.provenance                      # {"holders": {...}, "five_percent_holders": {...}}

events = p.events.list("MSFT", items=["1.05", "5.02"], since="2024-01-01")
events.to_pandas()[["filed_at", "item_code", "category"]]

tgt = p.guidance.list(ticker="TGT", metric="eps_adjusted")

Provenance

The API serves a value only when its source may be redistributed, and it says so on the value.

  • Signal.provenance and Series.provenance are a Provenance: source, publisher, license_class, license_name, license_url, attribution and redistributable.
  • Result.provenance is the response's block as sent. Rows that carry their own block keep it, and to_pandas() flattens it to provenance.source, provenance.license_class and so on.
  • Result.provenance_blocks() lists every distinct block in a response.

Show the attribution line wherever you display the data. Terms: palanor.com/terms.

First-reported values

vintage="first" asks for each observation as first published, before revisions. Those values come from ALFRED (Federal Reserve Bank of St. Louis), which isn't licensed for redistribution today, so the call raises PermissionDeniedError. They are shown in the Palanor Terminal.

Errors, retries and your allowance

Every call counts against the key's monthly allowance. result.rate_limit (and p.last_rate_limit) show the tier, the cap and what's left.

Exception When
AuthenticationError No key, a wrong key, or a revoked key (401)
PermissionDeniedError The tier doesn't include the endpoint, or the data can't be redistributed (402, 403)
NotFoundError No such signal or company, or a signal whose source is display-only (404)
BadRequestError A malformed parameter (400)
QuotaExceededError The month's cap is spent (429). Not retried.
RateLimitError A transient 429 that outlasted the retries
ServerError / APIConnectionError 5xx, or the API couldn't be reached

Transient failures are retried up to max_retries times (default 3). The wait doubles from backoff seconds (default 0.5) with jitter, and a Retry-After header is honoured.

p = Palanor(max_retries=5, backoff=1.0, timeout=60)

Development

cd packages/palanor-python
python -m venv .venv && . .venv/bin/activate
pip install -e ".[dev]"
pytest -m "not live"                       # offline: transport, retries, paging, DataFrames
PALANOR_API_KEY=plnr_... pytest -m live    # the live API, about 30 requests
mypy                                       # strict

MIT licensed (the client code). The data is governed by palanor.com/terms and by the license in each result's provenance block.

Release files for palanor 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for palanor 0.1.0
File Size Uploaded
palanor-0.1.0.tar.gz 19.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for palanor 0.1.0
File Interpreter ABI Platform
palanor-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 36.2 kB

Release files / palanor-0.1.0.tar.gz

Download URL palanor-0.1.0.tar.gz
Size 19.1 kB
Tags Source
SHA-256 checksum
How to use checksums
0a2fe7658da3fea7dee8c48c1cd6c5d0c2ea937bb6378a5ad3ac642e736a3249
BLAKE2b-256 checksum
How to use checksums
18d4c4ed06cccfd38db13170cd398f54a4bcb18622c26db9dd03a45385ec9453
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.6

Release files / palanor-0.1.0-py3-none-any.whl

Download URL palanor-0.1.0-py3-none-any.whl
Size 17.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
63aba8fb63812fbc49378e0f38b3b8f6b8087e098d177d30d68e27639dee0b5a
BLAKE2b-256 checksum
How to use checksums
b6eef91995a54a6a5d168dce86d5b7420261853ed1e5c822ce72c4a2ee69fdb6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.6

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page