aress-sdk 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- aress_sdk-0.1.0/.gitignore +11 -0
- aress_sdk-0.1.0/CHANGELOG.md +33 -0
- aress_sdk-0.1.0/LICENSE +21 -0
- aress_sdk-0.1.0/PKG-INFO +200 -0
- aress_sdk-0.1.0/README.md +170 -0
- aress_sdk-0.1.0/pyproject.toml +67 -0
- aress_sdk-0.1.0/src/aress_sdk/__init__.py +278 -0
- aress_sdk-0.1.0/src/aress_sdk/_resource.py +40 -0
- aress_sdk-0.1.0/src/aress_sdk/_transport.py +271 -0
- aress_sdk-0.1.0/src/aress_sdk/_types.py +71 -0
- aress_sdk-0.1.0/src/aress_sdk/_version.py +3 -0
- aress_sdk-0.1.0/src/aress_sdk/bonds/__init__.py +11 -0
- aress_sdk-0.1.0/src/aress_sdk/bonds/models.py +63 -0
- aress_sdk-0.1.0/src/aress_sdk/bonds/resource.py +70 -0
- aress_sdk-0.1.0/src/aress_sdk/client.py +184 -0
- aress_sdk-0.1.0/src/aress_sdk/config.py +79 -0
- aress_sdk-0.1.0/src/aress_sdk/currencies/__init__.py +11 -0
- aress_sdk-0.1.0/src/aress_sdk/currencies/models.py +31 -0
- aress_sdk-0.1.0/src/aress_sdk/currencies/resource.py +41 -0
- aress_sdk-0.1.0/src/aress_sdk/exceptions.py +167 -0
- aress_sdk-0.1.0/src/aress_sdk/funds/__init__.py +87 -0
- aress_sdk-0.1.0/src/aress_sdk/funds/models.py +686 -0
- aress_sdk-0.1.0/src/aress_sdk/funds/resource.py +594 -0
- aress_sdk-0.1.0/src/aress_sdk/ime/__init__.py +36 -0
- aress_sdk-0.1.0/src/aress_sdk/ime/models.py +296 -0
- aress_sdk-0.1.0/src/aress_sdk/ime/resource.py +218 -0
- aress_sdk-0.1.0/src/aress_sdk/instruments/__init__.py +50 -0
- aress_sdk-0.1.0/src/aress_sdk/instruments/models.py +364 -0
- aress_sdk-0.1.0/src/aress_sdk/instruments/resource.py +399 -0
- aress_sdk-0.1.0/src/aress_sdk/market/__init__.py +24 -0
- aress_sdk-0.1.0/src/aress_sdk/market/models.py +94 -0
- aress_sdk-0.1.0/src/aress_sdk/market/resource.py +56 -0
- aress_sdk-0.1.0/src/aress_sdk/py.typed +0 -0
- aress_sdk-0.1.0/src/aress_sdk/reports/__init__.py +30 -0
- aress_sdk-0.1.0/src/aress_sdk/reports/models.py +160 -0
- aress_sdk-0.1.0/src/aress_sdk/reports/resource.py +131 -0
- aress_sdk-0.1.0/src/aress_sdk/reports/result_types.py +1855 -0
- aress_sdk-0.1.0/src/aress_sdk/tradingview/__init__.py +24 -0
- aress_sdk-0.1.0/src/aress_sdk/tradingview/models.py +131 -0
- aress_sdk-0.1.0/src/aress_sdk/tradingview/resource.py +148 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## Unreleased
|
|
4
|
+
|
|
5
|
+
- `client.instruments.list_indices(market_flow=, is_active=)` lists TSETMC indices
|
|
6
|
+
(`GET /indices`), with the codes the index history methods accept.
|
|
7
|
+
- `client.instruments.realtime_market()` returns the latest intraday quote of every
|
|
8
|
+
instrument and index (`GET /instruments/realtime/market/latest`).
|
|
9
|
+
- `client.instruments.realtime_option_market(...)` returns option chains with the
|
|
10
|
+
intraday quote of every contract and underlying
|
|
11
|
+
(`GET /instruments/realtime/options/market/latest`).
|
|
12
|
+
- `client.ime.list_cdc_contracts()` / `get_cdc_contract(identifier)` and
|
|
13
|
+
`client.ime.list_option_contracts(...)` / `get_option_contract(identifier)` return Iran
|
|
14
|
+
Mercantile Exchange CDC and option contracts (`GET /ime/cdc/contracts*`,
|
|
15
|
+
`GET /ime/options/contracts*`).
|
|
16
|
+
- `client.ime.cdc_daily_trade_history(identifier, ...)` and `cdc_daily_trade_history_on(date)`
|
|
17
|
+
return CDC daily trade history (`GET /ime/cdc/contracts/{identifier}/trade_history/daily`,
|
|
18
|
+
`GET /ime/cdc/trade_history/daily`).
|
|
19
|
+
- `client.ime.realtime_market()` returns the latest quote of every Iran Mercantile
|
|
20
|
+
Exchange CDC (with its market value), commodity fund and listed CDC
|
|
21
|
+
(`GET /ime/realtime/market/latest`).
|
|
22
|
+
- `client.ime.realtime_option_chain(...)` returns the whole live IME option board as
|
|
23
|
+
chains, each with its underlying's latest quote (`GET /ime/realtime/options/market/latest`).
|
|
24
|
+
|
|
25
|
+
## 0.1.0
|
|
26
|
+
|
|
27
|
+
First public release on PyPI.
|
|
28
|
+
|
|
29
|
+
- Sync (`AressClient`) and asyncio (`AsyncAressClient`) clients for instruments, bonds,
|
|
30
|
+
currencies, funds, market lists and reports.
|
|
31
|
+
- An API key is required: `AressClient(api_key)`. It is sent in the
|
|
32
|
+
`X-API-Key` header on every request, including through a caller-supplied
|
|
33
|
+
`httpx` client, and kept out of `repr`. Passing `None` or a blank key raises `ValueError`.
|
aress_sdk-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Aress
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
aress_sdk-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: aress-sdk
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Official Python SDK for the Aress Data API: The Data API for all Iran Capital Markets.
|
|
5
|
+
Project-URL: Homepage, https://aressai.com
|
|
6
|
+
Author-email: Aress <aressfdp@gmail.com>
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Keywords: aress,bond,bourse,finance,fund,iran,market-data,sdk,tsetmc
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Intended Audience :: Financial and Insurance Industry
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Topic :: Office/Business :: Financial
|
|
22
|
+
Classifier: Typing :: Typed
|
|
23
|
+
Requires-Python: >=3.9
|
|
24
|
+
Requires-Dist: httpx<1.0,>=0.27
|
|
25
|
+
Requires-Dist: jdatetime>=5.0
|
|
26
|
+
Requires-Dist: pydantic<3.0,>=2.7
|
|
27
|
+
Provides-Extra: dev
|
|
28
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
29
|
+
Description-Content-Type: text/markdown
|
|
30
|
+
|
|
31
|
+
# Aress SDK
|
|
32
|
+
|
|
33
|
+
Official Python client for the **Aress Data API** — read access to the Iranian
|
|
34
|
+
capital market: instruments (TSETMC), bonds, currencies, funds, market lists
|
|
35
|
+
and reports.
|
|
36
|
+
|
|
37
|
+
- Synchronous **and** `asyncio` clients with an identical surface.
|
|
38
|
+
- Fully typed [pydantic v2](https://docs.pydantic.dev) models for every response.
|
|
39
|
+
- Jalali (Persian) dates parsed into real `jdatetime.date` objects.
|
|
40
|
+
- Money kept as `Decimal` (rials) — no float rounding.
|
|
41
|
+
- Sensible defaults: timeouts, automatic retries with backoff for transient
|
|
42
|
+
failures, and a clear exception hierarchy.
|
|
43
|
+
|
|
44
|
+
## Installation
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
pip install aress-sdk
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Requires Python 3.9+. Depends on `httpx`, `pydantic>=2`, and `jdatetime`.
|
|
51
|
+
|
|
52
|
+
## Quickstart
|
|
53
|
+
|
|
54
|
+
```python
|
|
55
|
+
from aress_sdk import AressClient
|
|
56
|
+
|
|
57
|
+
# An API key is required. The client talks to aress data backend
|
|
58
|
+
# by default and sends the key in the ``X-API-Key`` header on every request.
|
|
59
|
+
with AressClient("<your api key>") as client:
|
|
60
|
+
# Currencies
|
|
61
|
+
for currency in client.currencies.list():
|
|
62
|
+
print(currency.symbol, currency.farsi_name)
|
|
63
|
+
|
|
64
|
+
usd_history = client.currencies.daily_price_history("USD")
|
|
65
|
+
print(usd_history[-1].trade_jdate, usd_history[-1].close_price)
|
|
66
|
+
|
|
67
|
+
# Instruments
|
|
68
|
+
sectors = client.instruments.list_sectors()
|
|
69
|
+
steel = client.instruments.list(sector_code="27")
|
|
70
|
+
trades = client.instruments.daily_trade_history("778253364357513")
|
|
71
|
+
|
|
72
|
+
# Bonds
|
|
73
|
+
bonds = client.bonds.list(market=1)
|
|
74
|
+
bond = client.bonds.get(bonds[0].id)
|
|
75
|
+
ytm = client.bonds.daily_trade_history(bond.id)
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Async
|
|
79
|
+
|
|
80
|
+
```python
|
|
81
|
+
import asyncio
|
|
82
|
+
from aress_sdk import AsyncAressClient
|
|
83
|
+
|
|
84
|
+
async def main():
|
|
85
|
+
async with AsyncAressClient("<your api key>") as client:
|
|
86
|
+
sectors = await client.instruments.list_sectors()
|
|
87
|
+
usd = await client.currencies.daily_price_history("USD")
|
|
88
|
+
|
|
89
|
+
asyncio.run(main())
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Configuration
|
|
93
|
+
|
|
94
|
+
```python
|
|
95
|
+
client = AressClient(
|
|
96
|
+
"<your api key>", # required
|
|
97
|
+
timeout=30.0, # per-request, seconds
|
|
98
|
+
calculate_timeout=300.0, # report calculation endpoints, seconds
|
|
99
|
+
max_retries=2, # retries on connection errors / 5xx / 429
|
|
100
|
+
backoff_factor=0.5, # exponential backoff base, seconds
|
|
101
|
+
)
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Bring your own configured `httpx` client (proxies, custom TLS, connection
|
|
105
|
+
pools); the SDK will use it and leave its lifecycle to you:
|
|
106
|
+
|
|
107
|
+
```python
|
|
108
|
+
import httpx
|
|
109
|
+
from aress_sdk import AressClient
|
|
110
|
+
|
|
111
|
+
http = httpx.Client(proxies="http://proxy.example.com:8080")
|
|
112
|
+
client = AressClient("<your api key>", http_client=http) # the key is still sent
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Error handling
|
|
116
|
+
|
|
117
|
+
Every error derives from `AressError`:
|
|
118
|
+
|
|
119
|
+
```python
|
|
120
|
+
from aress_sdk import AressClient, NotFoundError, AressTransportError
|
|
121
|
+
|
|
122
|
+
with AressClient("<your api key>") as client:
|
|
123
|
+
try:
|
|
124
|
+
bond = client.bonds.get(999999)
|
|
125
|
+
except NotFoundError as exc:
|
|
126
|
+
print(exc.status_code, exc.detail) # 404 and the error detail
|
|
127
|
+
except AressTransportError as exc:
|
|
128
|
+
print("network problem:", exc)
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
| Exception | When |
|
|
132
|
+
|---|---|
|
|
133
|
+
| `BadRequestError` | HTTP 400 |
|
|
134
|
+
| `AuthenticationError` | HTTP 401 |
|
|
135
|
+
| `PermissionDeniedError` | HTTP 403 |
|
|
136
|
+
| `NotFoundError` | HTTP 404 |
|
|
137
|
+
| `UnprocessableEntityError` | HTTP 422 (request failed validation) |
|
|
138
|
+
| `RateLimitError` | HTTP 429 |
|
|
139
|
+
| `ServerError` | HTTP 5xx |
|
|
140
|
+
| `AressAPIStatusError` | any other non-2xx |
|
|
141
|
+
| `AressTimeoutError` / `AressConnectionError` | transport failures |
|
|
142
|
+
|
|
143
|
+
## Resources & endpoints
|
|
144
|
+
|
|
145
|
+
| Resource | Method | Endpoint |
|
|
146
|
+
|---|---|---|
|
|
147
|
+
| `client.instruments` | `list_sectors()` | `GET /sectors` |
|
|
148
|
+
| | `get_sector(code)` | `GET /sectors/{code}` |
|
|
149
|
+
| | `list(market_flow=, sector_code=, sub_sector_code=, market_code=)` | `GET /instruments` |
|
|
150
|
+
| | `adjustments(code)` | `GET /instruments/{code}/adjustments` |
|
|
151
|
+
| | `share_changes(code)` | `GET /instruments/{code}/share_changes` |
|
|
152
|
+
| | `daily_trade_history(code, from_date_inclusive=, to_date_inclusive=)` | `GET /instruments/{code}/trade_history/daily` |
|
|
153
|
+
| | `daily_client_type_history(code, from_date_inclusive=, to_date_inclusive=)` | `GET /instruments/{code}/client_type_history/daily` |
|
|
154
|
+
| | `daily_trade_history_on(date)` | `GET /instruments/trade_history/daily?date=` |
|
|
155
|
+
| | `daily_client_type_history_on(date)` | `GET /instruments/client_type_history/daily?date=` |
|
|
156
|
+
| | `list_indices(market_flow=, is_active=)` | `GET /indices` |
|
|
157
|
+
| | `index_daily_history_on(date)` | `GET /indices/history/daily?date=` |
|
|
158
|
+
| | `index_return_history(index_id, from_date=, to_date=)` | `GET /indices/{index_id}/return-history` |
|
|
159
|
+
| | `realtime_market()` | `GET /instruments/realtime/market/latest` |
|
|
160
|
+
| | `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` |
|
|
161
|
+
| `client.bonds` | `list(market=, bond_type=, issuer_type=)` | `GET /bonds` |
|
|
162
|
+
| | `get(bond_id)` | `GET /bonds/{bond_id}` |
|
|
163
|
+
| | `daily_trade_history(bond_id)` | `GET /bonds/{bond_id}/trade_history/daily` |
|
|
164
|
+
| `client.currencies` | `list()` | `GET /currencies` |
|
|
165
|
+
| | `daily_price_history(symbol)` | `GET /currencies/{symbol}/price_history/daily` |
|
|
166
|
+
| `client.funds` | `list()`, `managers()`, `nav_history(reg_no, sub_fund)`, `videos(...)` | `GET /funds*` |
|
|
167
|
+
| | `summary_analysis(...)`, `flows_summary(...)`, `aum_flow_series(...)`, `monthly_returns(...)`, `analysis(...)` | analysis endpoints |
|
|
168
|
+
| | `categories_issue_redeem_analysis(from_date=, to_date=)` | `GET /fund-categories/issue-redeem-analysis` |
|
|
169
|
+
| `client.market` | `stock_price_changes(window)`, `sector_trade_values(window)`, `realtime_stock_flows()` | `GET /market/*` |
|
|
170
|
+
| `client.ime` | `list_cdc_contracts(is_online=)` | `GET /ime/cdc/contracts` |
|
|
171
|
+
| | `get_cdc_contract(identifier)` | `GET /ime/cdc/contracts/{identifier}` |
|
|
172
|
+
| | `cdc_daily_trade_history(identifier, from_date_inclusive=, to_date_inclusive=)` | `GET /ime/cdc/contracts/{identifier}/trade_history/daily` |
|
|
173
|
+
| | `cdc_daily_trade_history_on(date)` | `GET /ime/cdc/trade_history/daily?date=` |
|
|
174
|
+
| | `list_option_contracts(underlying_asset_type=, underlying_asset_identifier=, option_type=, expiration_date_from=, expiration_date_to=)` | `GET /ime/options/contracts` |
|
|
175
|
+
| | `get_option_contract(identifier)` | `GET /ime/options/contracts/{identifier}` |
|
|
176
|
+
| | `realtime_market()` | `GET /ime/realtime/market/latest` |
|
|
177
|
+
| | `realtime_option_chain(underlying_ticker=, underlying_identifier=, expiration_date_from=, expiration_date_to=, only_with_market_data=)` | `GET /ime/realtime/options/market/latest` |
|
|
178
|
+
| `client.tradingview` | `config()`, `time()` | `GET /tradingview/config`, `GET /tradingview/time` |
|
|
179
|
+
| | `search(query, symbol_type=, exchange=, limit=)` | `GET /tradingview/search` |
|
|
180
|
+
| | `symbol(symbol)` | `GET /tradingview/symbols` |
|
|
181
|
+
| | `history(symbol, resolution, from_, to, countback=, adjusted=, calendar=)` | `GET /tradingview/history` |
|
|
182
|
+
| `client.reports` | `list()`, `categories()`, `get(report_id)` | `GET /reports*` |
|
|
183
|
+
| | `calculate(...)`, `calculate_batch(requests)` | `POST /reports/calculate*` |
|
|
184
|
+
| `client` | `health()` | `GET /health` |
|
|
185
|
+
|
|
186
|
+
Time-series endpoints return records **sorted by date ascending**.
|
|
187
|
+
|
|
188
|
+
## Development
|
|
189
|
+
|
|
190
|
+
The project uses [Hatch](https://hatch.pypa.io) and a `src/` layout.
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
hatch test # pytest against the installed package (in-process httpx mock, no network)
|
|
194
|
+
hatch build # sdist + wheel into dist/
|
|
195
|
+
hatch version minor # bump src/aress_sdk/_version.py
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## License
|
|
199
|
+
|
|
200
|
+
MIT, see [LICENSE](LICENSE).
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
# Aress SDK
|
|
2
|
+
|
|
3
|
+
Official Python client for the **Aress Data API** — read access to the Iranian
|
|
4
|
+
capital market: instruments (TSETMC), bonds, currencies, funds, market lists
|
|
5
|
+
and reports.
|
|
6
|
+
|
|
7
|
+
- Synchronous **and** `asyncio` clients with an identical surface.
|
|
8
|
+
- Fully typed [pydantic v2](https://docs.pydantic.dev) models for every response.
|
|
9
|
+
- Jalali (Persian) dates parsed into real `jdatetime.date` objects.
|
|
10
|
+
- Money kept as `Decimal` (rials) — no float rounding.
|
|
11
|
+
- Sensible defaults: timeouts, automatic retries with backoff for transient
|
|
12
|
+
failures, and a clear exception hierarchy.
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pip install aress-sdk
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Requires Python 3.9+. Depends on `httpx`, `pydantic>=2`, and `jdatetime`.
|
|
21
|
+
|
|
22
|
+
## Quickstart
|
|
23
|
+
|
|
24
|
+
```python
|
|
25
|
+
from aress_sdk import AressClient
|
|
26
|
+
|
|
27
|
+
# An API key is required. The client talks to aress data backend
|
|
28
|
+
# by default and sends the key in the ``X-API-Key`` header on every request.
|
|
29
|
+
with AressClient("<your api key>") as client:
|
|
30
|
+
# Currencies
|
|
31
|
+
for currency in client.currencies.list():
|
|
32
|
+
print(currency.symbol, currency.farsi_name)
|
|
33
|
+
|
|
34
|
+
usd_history = client.currencies.daily_price_history("USD")
|
|
35
|
+
print(usd_history[-1].trade_jdate, usd_history[-1].close_price)
|
|
36
|
+
|
|
37
|
+
# Instruments
|
|
38
|
+
sectors = client.instruments.list_sectors()
|
|
39
|
+
steel = client.instruments.list(sector_code="27")
|
|
40
|
+
trades = client.instruments.daily_trade_history("778253364357513")
|
|
41
|
+
|
|
42
|
+
# Bonds
|
|
43
|
+
bonds = client.bonds.list(market=1)
|
|
44
|
+
bond = client.bonds.get(bonds[0].id)
|
|
45
|
+
ytm = client.bonds.daily_trade_history(bond.id)
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Async
|
|
49
|
+
|
|
50
|
+
```python
|
|
51
|
+
import asyncio
|
|
52
|
+
from aress_sdk import AsyncAressClient
|
|
53
|
+
|
|
54
|
+
async def main():
|
|
55
|
+
async with AsyncAressClient("<your api key>") as client:
|
|
56
|
+
sectors = await client.instruments.list_sectors()
|
|
57
|
+
usd = await client.currencies.daily_price_history("USD")
|
|
58
|
+
|
|
59
|
+
asyncio.run(main())
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Configuration
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
client = AressClient(
|
|
66
|
+
"<your api key>", # required
|
|
67
|
+
timeout=30.0, # per-request, seconds
|
|
68
|
+
calculate_timeout=300.0, # report calculation endpoints, seconds
|
|
69
|
+
max_retries=2, # retries on connection errors / 5xx / 429
|
|
70
|
+
backoff_factor=0.5, # exponential backoff base, seconds
|
|
71
|
+
)
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Bring your own configured `httpx` client (proxies, custom TLS, connection
|
|
75
|
+
pools); the SDK will use it and leave its lifecycle to you:
|
|
76
|
+
|
|
77
|
+
```python
|
|
78
|
+
import httpx
|
|
79
|
+
from aress_sdk import AressClient
|
|
80
|
+
|
|
81
|
+
http = httpx.Client(proxies="http://proxy.example.com:8080")
|
|
82
|
+
client = AressClient("<your api key>", http_client=http) # the key is still sent
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Error handling
|
|
86
|
+
|
|
87
|
+
Every error derives from `AressError`:
|
|
88
|
+
|
|
89
|
+
```python
|
|
90
|
+
from aress_sdk import AressClient, NotFoundError, AressTransportError
|
|
91
|
+
|
|
92
|
+
with AressClient("<your api key>") as client:
|
|
93
|
+
try:
|
|
94
|
+
bond = client.bonds.get(999999)
|
|
95
|
+
except NotFoundError as exc:
|
|
96
|
+
print(exc.status_code, exc.detail) # 404 and the error detail
|
|
97
|
+
except AressTransportError as exc:
|
|
98
|
+
print("network problem:", exc)
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
| Exception | When |
|
|
102
|
+
|---|---|
|
|
103
|
+
| `BadRequestError` | HTTP 400 |
|
|
104
|
+
| `AuthenticationError` | HTTP 401 |
|
|
105
|
+
| `PermissionDeniedError` | HTTP 403 |
|
|
106
|
+
| `NotFoundError` | HTTP 404 |
|
|
107
|
+
| `UnprocessableEntityError` | HTTP 422 (request failed validation) |
|
|
108
|
+
| `RateLimitError` | HTTP 429 |
|
|
109
|
+
| `ServerError` | HTTP 5xx |
|
|
110
|
+
| `AressAPIStatusError` | any other non-2xx |
|
|
111
|
+
| `AressTimeoutError` / `AressConnectionError` | transport failures |
|
|
112
|
+
|
|
113
|
+
## Resources & endpoints
|
|
114
|
+
|
|
115
|
+
| Resource | Method | Endpoint |
|
|
116
|
+
|---|---|---|
|
|
117
|
+
| `client.instruments` | `list_sectors()` | `GET /sectors` |
|
|
118
|
+
| | `get_sector(code)` | `GET /sectors/{code}` |
|
|
119
|
+
| | `list(market_flow=, sector_code=, sub_sector_code=, market_code=)` | `GET /instruments` |
|
|
120
|
+
| | `adjustments(code)` | `GET /instruments/{code}/adjustments` |
|
|
121
|
+
| | `share_changes(code)` | `GET /instruments/{code}/share_changes` |
|
|
122
|
+
| | `daily_trade_history(code, from_date_inclusive=, to_date_inclusive=)` | `GET /instruments/{code}/trade_history/daily` |
|
|
123
|
+
| | `daily_client_type_history(code, from_date_inclusive=, to_date_inclusive=)` | `GET /instruments/{code}/client_type_history/daily` |
|
|
124
|
+
| | `daily_trade_history_on(date)` | `GET /instruments/trade_history/daily?date=` |
|
|
125
|
+
| | `daily_client_type_history_on(date)` | `GET /instruments/client_type_history/daily?date=` |
|
|
126
|
+
| | `list_indices(market_flow=, is_active=)` | `GET /indices` |
|
|
127
|
+
| | `index_daily_history_on(date)` | `GET /indices/history/daily?date=` |
|
|
128
|
+
| | `index_return_history(index_id, from_date=, to_date=)` | `GET /indices/{index_id}/return-history` |
|
|
129
|
+
| | `realtime_market()` | `GET /instruments/realtime/market/latest` |
|
|
130
|
+
| | `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` |
|
|
131
|
+
| `client.bonds` | `list(market=, bond_type=, issuer_type=)` | `GET /bonds` |
|
|
132
|
+
| | `get(bond_id)` | `GET /bonds/{bond_id}` |
|
|
133
|
+
| | `daily_trade_history(bond_id)` | `GET /bonds/{bond_id}/trade_history/daily` |
|
|
134
|
+
| `client.currencies` | `list()` | `GET /currencies` |
|
|
135
|
+
| | `daily_price_history(symbol)` | `GET /currencies/{symbol}/price_history/daily` |
|
|
136
|
+
| `client.funds` | `list()`, `managers()`, `nav_history(reg_no, sub_fund)`, `videos(...)` | `GET /funds*` |
|
|
137
|
+
| | `summary_analysis(...)`, `flows_summary(...)`, `aum_flow_series(...)`, `monthly_returns(...)`, `analysis(...)` | analysis endpoints |
|
|
138
|
+
| | `categories_issue_redeem_analysis(from_date=, to_date=)` | `GET /fund-categories/issue-redeem-analysis` |
|
|
139
|
+
| `client.market` | `stock_price_changes(window)`, `sector_trade_values(window)`, `realtime_stock_flows()` | `GET /market/*` |
|
|
140
|
+
| `client.ime` | `list_cdc_contracts(is_online=)` | `GET /ime/cdc/contracts` |
|
|
141
|
+
| | `get_cdc_contract(identifier)` | `GET /ime/cdc/contracts/{identifier}` |
|
|
142
|
+
| | `cdc_daily_trade_history(identifier, from_date_inclusive=, to_date_inclusive=)` | `GET /ime/cdc/contracts/{identifier}/trade_history/daily` |
|
|
143
|
+
| | `cdc_daily_trade_history_on(date)` | `GET /ime/cdc/trade_history/daily?date=` |
|
|
144
|
+
| | `list_option_contracts(underlying_asset_type=, underlying_asset_identifier=, option_type=, expiration_date_from=, expiration_date_to=)` | `GET /ime/options/contracts` |
|
|
145
|
+
| | `get_option_contract(identifier)` | `GET /ime/options/contracts/{identifier}` |
|
|
146
|
+
| | `realtime_market()` | `GET /ime/realtime/market/latest` |
|
|
147
|
+
| | `realtime_option_chain(underlying_ticker=, underlying_identifier=, expiration_date_from=, expiration_date_to=, only_with_market_data=)` | `GET /ime/realtime/options/market/latest` |
|
|
148
|
+
| `client.tradingview` | `config()`, `time()` | `GET /tradingview/config`, `GET /tradingview/time` |
|
|
149
|
+
| | `search(query, symbol_type=, exchange=, limit=)` | `GET /tradingview/search` |
|
|
150
|
+
| | `symbol(symbol)` | `GET /tradingview/symbols` |
|
|
151
|
+
| | `history(symbol, resolution, from_, to, countback=, adjusted=, calendar=)` | `GET /tradingview/history` |
|
|
152
|
+
| `client.reports` | `list()`, `categories()`, `get(report_id)` | `GET /reports*` |
|
|
153
|
+
| | `calculate(...)`, `calculate_batch(requests)` | `POST /reports/calculate*` |
|
|
154
|
+
| `client` | `health()` | `GET /health` |
|
|
155
|
+
|
|
156
|
+
Time-series endpoints return records **sorted by date ascending**.
|
|
157
|
+
|
|
158
|
+
## Development
|
|
159
|
+
|
|
160
|
+
The project uses [Hatch](https://hatch.pypa.io) and a `src/` layout.
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
hatch test # pytest against the installed package (in-process httpx mock, no network)
|
|
164
|
+
hatch build # sdist + wheel into dist/
|
|
165
|
+
hatch version minor # bump src/aress_sdk/_version.py
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
## License
|
|
169
|
+
|
|
170
|
+
MIT, see [LICENSE](LICENSE).
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling>=1.27"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "aress-sdk"
|
|
7
|
+
dynamic = ["version"]
|
|
8
|
+
description = "Official Python SDK for the Aress Data API: The Data API for all Iran Capital Markets."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.9"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
license-files = ["LICENSE"]
|
|
13
|
+
authors = [{ name = "Aress", email = "aressfdp@gmail.com" }]
|
|
14
|
+
keywords = ["aress", "tsetmc", "finance", "bourse", "iran", "market-data", "sdk", "bond", "fund"]
|
|
15
|
+
classifiers = [
|
|
16
|
+
"Development Status :: 3 - Alpha",
|
|
17
|
+
"Programming Language :: Python :: 3",
|
|
18
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
19
|
+
"Programming Language :: Python :: 3.9",
|
|
20
|
+
"Programming Language :: Python :: 3.10",
|
|
21
|
+
"Programming Language :: Python :: 3.11",
|
|
22
|
+
"Programming Language :: Python :: 3.12",
|
|
23
|
+
"Programming Language :: Python :: 3.13",
|
|
24
|
+
"Operating System :: OS Independent",
|
|
25
|
+
"Intended Audience :: Developers",
|
|
26
|
+
"Intended Audience :: Financial and Insurance Industry",
|
|
27
|
+
"Topic :: Office/Business :: Financial",
|
|
28
|
+
"Typing :: Typed",
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
dependencies = [
|
|
32
|
+
"httpx>=0.27,<1.0",
|
|
33
|
+
"pydantic>=2.7,<3.0",
|
|
34
|
+
"jdatetime>=5.0",
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
[project.optional-dependencies]
|
|
38
|
+
dev = [
|
|
39
|
+
"pytest>=8.0",
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
[project.urls]
|
|
43
|
+
Homepage = "https://aressai.com"
|
|
44
|
+
|
|
45
|
+
[tool.hatch.version]
|
|
46
|
+
# Single source of truth; ``hatch version patch|minor|major`` rewrites it.
|
|
47
|
+
path = "src/aress_sdk/_version.py"
|
|
48
|
+
|
|
49
|
+
[tool.hatch.build.targets.wheel]
|
|
50
|
+
packages = ["src/aress_sdk"]
|
|
51
|
+
exclude = ["readme_*.md"]
|
|
52
|
+
|
|
53
|
+
[tool.hatch.build.targets.sdist]
|
|
54
|
+
include = [
|
|
55
|
+
"src/aress_sdk",
|
|
56
|
+
"README.md",
|
|
57
|
+
"LICENSE",
|
|
58
|
+
"CHANGELOG.md",
|
|
59
|
+
]
|
|
60
|
+
# Internal docs (e.g. readme_publish.md) never ship.
|
|
61
|
+
exclude = ["readme_*.md"]
|
|
62
|
+
|
|
63
|
+
[tool.hatch.envs.hatch-test]
|
|
64
|
+
dependencies = ["pytest>=8.0"]
|
|
65
|
+
|
|
66
|
+
[tool.pytest.ini_options]
|
|
67
|
+
testpaths = ["tests"]
|