Metadata-Version: 2.4
Name: cosmicephemeris-client
Version: 0.4.0
Summary: Synchronous Python client for the Cosmic Ephemeris calculation gateway
Author-email: Cosmic Ephemeris <support@cosmicephemeris.com>
Maintainer-email: Cosmic Ephemeris <support@cosmicephemeris.com>
License-Expression: ISC
Project-URL: Homepage, https://cosmicephemeris.com
Project-URL: Documentation, https://cosmicephemeris.com/docs-developer-platform.html
Project-URL: Support, https://cosmicephemeris.com/contact.html
Keywords: astrology,astronomy,ephemeris,api,sdk
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Typing :: Typed
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE.txt
Provides-Extra: receipts
Requires-Dist: cryptography>=50.0.2; extra == "receipts"
Dynamic: license-file

# Cosmic Ephemeris Python SDK

The official synchronous Python client for the Cosmic Ephemeris calculation API.

- 78 calculation methods
- Python 3.10 or newer
- Typed inputs and route-specific response envelopes
- No required runtime dependencies
- Bounded transport concurrency, responses, and deadlines
- Sanitized errors and no automatic retries

## Install

```sh
python -m pip install cosmicephemeris-client
```

Optional signed-receipt verification uses `cryptography`:

```sh
python -m pip install "cosmicephemeris-client[receipts]>=0.4.0"
```

## Compatibility

Version 0.4.0 adds explicit historical requests for all 77 date-bearing
operations and BCE-safe date/time helpers. Use 0.4.0 or newer for the historical
examples below; earlier packages do not include these helpers.

Version 0.3.3 accepts the current status returned by all 78 calculation contracts.
Upgrade before deploying the matching server contract; 0.3.2 strictly expects the
former status value on promoted routes and can reject otherwise valid responses.

## Quick start

```python
from cosmicephemeris_client import (
    CosmicEphemerisClient,
    HTTPError,
    RequestTimeoutError,
)

client = CosmicEphemerisClient()  # Reads COSMICEPHEMERIS_KEY.

try:
    result = client.birth_chart({
        "date": "1990-01-01",
        "time": "12:00",
        "timezone": "America/New_York",
        "lat": 40.7128,
        "lon": -74.006,
    })
    print(result["chart"]["planets"]["Sun"])
except HTTPError as error:
    print(error.status, error.retry_after)
except RequestTimeoutError:
    print("The deadline expired; admitted work may still consume quota.")
```

You may pass `api_key=` explicitly. An explicit key takes precedence over
`COSMICEPHEMERIS_KEY`.

API keys are server credentials. Never put them in browser code, mobile applications,
URLs, public environment variables, analytics, notebooks intended for sharing, or
source control.

## Methods and typing

Methods use Python snake case and map directly to the documented REST operations.
They return the complete response dictionary without changing its envelope.

The package is marked with `py.typed`. Every public method has a documented input
`TypedDict` and a route-specific response type derived from the maintained OpenAPI
contract. Selected complex responses have additional hand-maintained nested types.

Common groups include:

- Natal charts, houses, aspects, transits, synastry, composite, and Davison charts
- Vedic Vargas, Vimshottari, Panchang, Ashtakoota, and Ashtakavarga
- Moon phases, planetary events, aspect windows, eclipses, and event calendars
- SVG, PNG, reports, and structured export formats
- Place search, timezone resolution, relocation, and astrocartography
- Convention, uncertainty, robustness, and electional audit operations

Use the [full calculation reference](https://cosmicephemeris.com/docs.html),
[copy-paste API examples](https://cosmicephemeris.com/docs-api-examples.html), and
[OpenAPI document](https://cosmicephemeris.com/openapi.json) for every operation's
exact request and response contract. The [developer platform guide](https://cosmicephemeris.com/docs-developer-platform.html)
owns shared authentication, quota, job, and integration rules.

## Transport and deadlines

The client:

- Validates the API key and documented input boundaries before transport.
- Uses verified HTTPS and sends credentials only to the configured origin.
- Ignores proxy environment variables, cookies, and redirects.
- Allows HTTP only through explicit loopback-only test configuration.
- Bounds request size, response size, and outstanding transport workers.
- Rejects compressed, malformed, truncated, duplicate-key, and non-finite JSON.
- Does not retry automatically.

Default deadlines vary by operation. They can be bounded with `timeout=`,
`planetary_events_timeout=`, `aspect_windows_timeout=`, and `timeline_timeout=` when constructing the
client. A timeout may still consume quota if the gateway already accepted the work.

Methods outside the longer route groups use a 20-second default deadline.
Version 0.3.3 gives `event_calendar` the 35-second planetary-event deadline for
its 30-second engine budget. `planetary_events_timeout=` configures that route
group. The client deadline is a safety bound, not a response-time promise.

## Errors

Errors expose only safe structured information. They do not include API keys,
request payloads, response bodies, raw headers, URLs, or underlying transport
exception details.

The primary classes are:

- `ValidationError`
- `HTTPError`
- `RequestTimeoutError`
- `ClientBusyError`
- `TransportError`
- `ResponseError`

## Signed calculation receipts

```python
from cosmicephemeris_client import verify_calculation_receipt

valid = verify_calculation_receipt(response, public_jwk)
```

Receipt verification requires the optional `receipts` dependency. It checks the
Ed25519 signature and canonical hashes. It proves response integrity and service
provenance; it does not independently validate the meaning or correctness of a
calculation.

## Local verification

From `clients/python`:

```sh
python scripts/generate_response_types.py --check
PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=src python -m unittest discover -s tests -v
python -m build
```

Tests use synthetic credentials and local HTTP/TLS servers. They do not call the
production API unless an example is deliberately run with a real key.

## Support and license

- Calculation reference: https://cosmicephemeris.com/docs.html
- API examples: https://cosmicephemeris.com/docs-api-examples.html
- OpenAPI: https://cosmicephemeris.com/openapi.json
- Developer platform: https://cosmicephemeris.com/docs-developer-platform.html
- Support: support@cosmicephemeris.com
- License: ISC

### Explicit historical calculations — 0.4.0

These examples require version 0.4.0 or newer, not PyPI 0.3.3. The package keeps
standard methods, response envelopes, deadlines and no-retry behavior.

All 77 date-bearing operations accept 1000 BCE (BC)–2500 CE (AD) through the `historical` method; `place-search` has no date input. See the public [OpenAPI historical schemas](https://cosmicephemeris.com/openapi.json); repository maintainers also use `contracts/historical-integration.json`. Modern string dates retain their existing 1800–2200 contract. Birth-chart responses retain `chart`; other historical responses retain their original `input` and put the adapter output in `result`.

Every historical date specifies `year`, `era`, `month`, `day`, and `calendar`; timed inputs also require `UT1` or a fixed UT1 offset. Never convert BCE through a native JavaScript Date or Python datetime. Numerology requires `year_convention` set explicitly to `displayed_year_digits` or `astronomical_year_digits`, and an optional personal `year` is `{year, era}`. Its metadata uses `time_standard: "not_applicable"`. Ancient city timezones are not inferred. Search windows, undefined polar geometry, model uncertainty and export limitations remain explicit.

```python
from cosmicephemeris_client import CosmicEphemerisClient, normalize_historical_datetime

api = CosmicEphemerisClient()  # Server-side COSMICEPHEMERIS_KEY.
at = normalize_historical_datetime({
    "date": {"year": 1000, "era": "BCE", "month": 1, "day": 1, "calendar": "proleptic_julian"},
    "time": "12:00", "timezone": "UT1",
})
birth = {**at, "lat": 28.6, "lon": 77.2}
chart = api.historical("birth-chart", birth)
print(chart["chart"]["planets"]["Sun"])

phases = api.historical("moon-phases", {
    "mode": "calendar", "start": at,
    "end": {**at, "date": {**at["date"], "day": 2}}, "include_ical": False,
})
print(phases["result"])  # Historical UT1 records, not fabricated UTC strings.
```

Each call can consume quota; examples are not run by installation. Historical
UT1 calendars do not support iCalendar; use supported JSON/CSV outputs. SDK
transport does not certify astronomical accuracy: retain response warnings and
read the [accuracy evidence](https://cosmicephemeris.com/accuracy.html).
Account-session readings/Tarot are separate products, not extra API-key SDK methods.
