Metadata-Version: 2.5
Name: aress-sdk
Version: 0.1.0
Summary: Official Python SDK for the Aress Data API: The Data API for all Iran Capital Markets.
Project-URL: Homepage, https://aressai.com
Author-email: Aress <aressfdp@gmail.com>
License-Expression: MIT
License-File: LICENSE
Keywords: aress,bond,bourse,finance,fund,iran,market-data,sdk,tsetmc
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Office/Business :: Financial
Classifier: Typing :: Typed
Requires-Python: >=3.9
Requires-Dist: httpx<1.0,>=0.27
Requires-Dist: jdatetime>=5.0
Requires-Dist: pydantic<3.0,>=2.7
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == 'dev'
Description-Content-Type: text/markdown

# Aress SDK

Official Python client for the **Aress Data API** — read access to the Iranian
capital market: instruments (TSETMC), bonds, currencies, funds, market lists
and reports.

- Synchronous **and** `asyncio` clients with an identical surface.
- Fully typed [pydantic v2](https://docs.pydantic.dev) models for every response.
- Jalali (Persian) dates parsed into real `jdatetime.date` objects.
- Money kept as `Decimal` (rials) — no float rounding.
- Sensible defaults: timeouts, automatic retries with backoff for transient
  failures, and a clear exception hierarchy.

## Installation

```bash
pip install aress-sdk
```

Requires Python 3.9+. Depends on `httpx`, `pydantic>=2`, and `jdatetime`.

## Quickstart

```python
from aress_sdk import AressClient

# An API key is required. The client talks to aress data backend
# by default and sends the key in the ``X-API-Key`` header on every request.
with AressClient("<your api key>") as client:
    # Currencies
    for currency in client.currencies.list():
        print(currency.symbol, currency.farsi_name)

    usd_history = client.currencies.daily_price_history("USD")
    print(usd_history[-1].trade_jdate, usd_history[-1].close_price)

    # Instruments
    sectors = client.instruments.list_sectors()
    steel = client.instruments.list(sector_code="27")
    trades = client.instruments.daily_trade_history("778253364357513")

    # Bonds
    bonds = client.bonds.list(market=1)
    bond = client.bonds.get(bonds[0].id)
    ytm = client.bonds.daily_trade_history(bond.id)
```

### Async

```python
import asyncio
from aress_sdk import AsyncAressClient

async def main():
    async with AsyncAressClient("<your api key>") as client:
        sectors = await client.instruments.list_sectors()
        usd = await client.currencies.daily_price_history("USD")

asyncio.run(main())
```

## Configuration

```python
client = AressClient(
    "<your api key>",                 # required
    timeout=30.0,            # per-request, seconds
    calculate_timeout=300.0, # report calculation endpoints, seconds
    max_retries=2,           # retries on connection errors / 5xx / 429
    backoff_factor=0.5,      # exponential backoff base, seconds
)
```

Bring your own configured `httpx` client (proxies, custom TLS, connection
pools); the SDK will use it and leave its lifecycle to you:

```python
import httpx
from aress_sdk import AressClient

http = httpx.Client(proxies="http://proxy.example.com:8080")
client = AressClient("<your api key>", http_client=http)  # the key is still sent
```

## Error handling

Every error derives from `AressError`:

```python
from aress_sdk import AressClient, NotFoundError, AressTransportError

with AressClient("<your api key>") as client:
    try:
        bond = client.bonds.get(999999)
    except NotFoundError as exc:
        print(exc.status_code, exc.detail)   # 404 and the error detail
    except AressTransportError as exc:
        print("network problem:", exc)
```

| Exception | When |
|---|---|
| `BadRequestError` | HTTP 400 |
| `AuthenticationError` | HTTP 401 |
| `PermissionDeniedError` | HTTP 403 |
| `NotFoundError` | HTTP 404 |
| `UnprocessableEntityError` | HTTP 422 (request failed validation) |
| `RateLimitError` | HTTP 429 |
| `ServerError` | HTTP 5xx |
| `AressAPIStatusError` | any other non-2xx |
| `AressTimeoutError` / `AressConnectionError` | transport failures |

## Resources & endpoints

| Resource | Method | Endpoint |
|---|---|---|
| `client.instruments` | `list_sectors()` | `GET /sectors` |
| | `get_sector(code)` | `GET /sectors/{code}` |
| | `list(market_flow=, sector_code=, sub_sector_code=, market_code=)` | `GET /instruments` |
| | `adjustments(code)` | `GET /instruments/{code}/adjustments` |
| | `share_changes(code)` | `GET /instruments/{code}/share_changes` |
| | `daily_trade_history(code, from_date_inclusive=, to_date_inclusive=)` | `GET /instruments/{code}/trade_history/daily` |
| | `daily_client_type_history(code, from_date_inclusive=, to_date_inclusive=)` | `GET /instruments/{code}/client_type_history/daily` |
| | `daily_trade_history_on(date)` | `GET /instruments/trade_history/daily?date=` |
| | `daily_client_type_history_on(date)` | `GET /instruments/client_type_history/daily?date=` |
| | `list_indices(market_flow=, is_active=)` | `GET /indices` |
| | `index_daily_history_on(date)` | `GET /indices/history/daily?date=` |
| | `index_return_history(index_id, from_date=, to_date=)` | `GET /indices/{index_id}/return-history` |
| | `realtime_market()` | `GET /instruments/realtime/market/latest` |
| | `realtime_option_market(underlying_instrument_tsetmc_code=, expiration_date_from=, expiration_date_to=, is_active=, only_with_market_data=)` | `GET /instruments/realtime/options/market/latest` |
| `client.bonds` | `list(market=, bond_type=, issuer_type=)` | `GET /bonds` |
| | `get(bond_id)` | `GET /bonds/{bond_id}` |
| | `daily_trade_history(bond_id)` | `GET /bonds/{bond_id}/trade_history/daily` |
| `client.currencies` | `list()` | `GET /currencies` |
| | `daily_price_history(symbol)` | `GET /currencies/{symbol}/price_history/daily` |
| `client.funds` | `list()`, `managers()`, `nav_history(reg_no, sub_fund)`, `videos(...)` | `GET /funds*` |
| | `summary_analysis(...)`, `flows_summary(...)`, `aum_flow_series(...)`, `monthly_returns(...)`, `analysis(...)` | analysis endpoints |
| | `categories_issue_redeem_analysis(from_date=, to_date=)` | `GET /fund-categories/issue-redeem-analysis` |
| `client.market` | `stock_price_changes(window)`, `sector_trade_values(window)`, `realtime_stock_flows()` | `GET /market/*` |
| `client.ime` | `list_cdc_contracts(is_online=)` | `GET /ime/cdc/contracts` |
| | `get_cdc_contract(identifier)` | `GET /ime/cdc/contracts/{identifier}` |
| | `cdc_daily_trade_history(identifier, from_date_inclusive=, to_date_inclusive=)` | `GET /ime/cdc/contracts/{identifier}/trade_history/daily` |
| | `cdc_daily_trade_history_on(date)` | `GET /ime/cdc/trade_history/daily?date=` |
| | `list_option_contracts(underlying_asset_type=, underlying_asset_identifier=, option_type=, expiration_date_from=, expiration_date_to=)` | `GET /ime/options/contracts` |
| | `get_option_contract(identifier)` | `GET /ime/options/contracts/{identifier}` |
| | `realtime_market()` | `GET /ime/realtime/market/latest` |
| | `realtime_option_chain(underlying_ticker=, underlying_identifier=, expiration_date_from=, expiration_date_to=, only_with_market_data=)` | `GET /ime/realtime/options/market/latest` |
| `client.tradingview` | `config()`, `time()` | `GET /tradingview/config`, `GET /tradingview/time` |
| | `search(query, symbol_type=, exchange=, limit=)` | `GET /tradingview/search` |
| | `symbol(symbol)` | `GET /tradingview/symbols` |
| | `history(symbol, resolution, from_, to, countback=, adjusted=, calendar=)` | `GET /tradingview/history` |
| `client.reports` | `list()`, `categories()`, `get(report_id)` | `GET /reports*` |
| | `calculate(...)`, `calculate_batch(requests)` | `POST /reports/calculate*` |
| `client` | `health()` | `GET /health` |

Time-series endpoints return records **sorted by date ascending**.

## Development

The project uses [Hatch](https://hatch.pypa.io) and a `src/` layout.

```bash
hatch test            # pytest against the installed package (in-process httpx mock, no network)
hatch build           # sdist + wheel into dist/
hatch version minor   # bump src/aress_sdk/_version.py
```

## License

MIT, see [LICENSE](LICENSE).
