Lightweight Python client for the SAHMK Developer API.
Project description
SAHMK Python SDK
A lightweight Python client for the SAHMK Developer API — real-time and historical Saudi stock market (Tadawul) data.
Features
- Real-time quotes — live prices for 350+ Tadawul stocks
- Batch quotes — up to 50 stocks in a single request
- Historical data — daily/weekly/monthly OHLCV with custom date ranges
- Market overview — TASI index, gainers, losers, volume/value leaders, sectors
- Company info — fundamentals, technicals, valuation, analyst consensus (by plan)
- Financials — income statements, balance sheets, cash flow
- Dividends — history, yield, upcoming payments
- Events — AI-generated stock event summaries
- WebSocket streaming — real-time price updates pushed to you (Pro+ plan)
Installation
pip install sahmk
Or clone this repo for local development:
git clone https://github.com/sahmk-sa/sahmk-python.git
cd sahmk-python
pip install -r requirements.txt
Quick Start
from sahmk import SahmkClient
client = SahmkClient("your_api_key")
# Get a stock quote
quote = client.quote("2222")
print(f"{quote['name_en']}: {quote['price']} SAR ({quote['change_percent']}%)")
# Get market summary
market = client.market_summary()
print(f"TASI: {market['index_value']} ({market['index_change_percent']}%)")
# Batch quotes (Starter+ plan)
result = client.quotes(["2222", "1120", "4191"])
for q in result["quotes"]:
print(f"{q['symbol']}: {q['price']}")
CLI Quick Start
The package also installs a CLI for instant testing:
export SAHMK_API_KEY="your_api_key"
sahmk quote 2222
sahmk market gainers --limit 5
sahmk historical 2222 --from 2026-01-01 --to 2026-01-28
sahmk company 2222
sahmk financials 2222
sahmk dividends 2222
sahmk events --symbol 2222 --limit 5
sahmk stream 2222,1120
You can also pass the key directly:
sahmk quote 2222 --api-key your_api_key
Typed Responses
All client methods return typed objects with IDE autocompletion — while preserving full backwards compatibility with dict-style access:
quote = client.quote("2222")
# New: typed attribute access
print(quote.price)
print(quote.liquidity.net_value)
# Still works: dict-style access (backwards compatible)
print(quote["price"])
print(quote.get("volume"))
Access the original API response dict via .raw:
raw_dict = quote.raw
Retries and Rate Limits
The client automatically retries transient failures (429 rate-limit and 5xx server errors) with exponential backoff:
# Defaults: 3 retries, 0.5s backoff factor (0.5s, 1s, 2s delays)
client = SahmkClient("your_api_key")
# Customize retry behavior
client = SahmkClient("your_api_key", retries=5, backoff_factor=1.0)
# Disable retries entirely
client = SahmkClient("your_api_key", retries=0)
Rate limit errors include metadata from the API:
from sahmk import SahmkRateLimitError
try:
quote = client.quote("2222")
except SahmkRateLimitError as e:
print(f"Rate limited. Retry after: {e.retry_after}s")
print(f"Remaining: {e.rate_remaining}/{e.rate_limit}")
Get Your API Key
- Sign up at sahmk.sa/developers
- Verify your email
- Go to Dashboard → API Keys → Create Key
- Copy your key (starts with
shmk_live_orshmk_test_)
Plans
| Plan | Price | Requests/Day | WebSocket |
|---|---|---|---|
| Free | 0 SAR | 100 | - |
| Starter | 149 SAR/mo | 5,000 | - |
| Pro | 499 SAR/mo | 50,000 | Yes |
| Enterprise | Contact us |
Unlimited | Yes |
Examples
Check the examples/ directory:
| File | Description |
|---|---|
quote.py |
Get a single stock quote |
batch_quotes.py |
Fetch multiple stocks at once |
historical.py |
Historical price data |
market_summary.py |
Market overview and movers |
websocket_stream.py |
Real-time WebSocket streaming (Pro+) |
API Reference
Base URL: https://app.sahmk.sa/api/v1
| Endpoint | Plan | Description |
|---|---|---|
GET /quote/{symbol}/ |
Free | Stock quote |
GET /quotes/?symbols=... |
Starter+ | Batch quotes (up to 50) |
GET /historical/{symbol}/ |
Starter+ | Historical OHLCV data |
GET /market/summary/ |
Free | Market overview & TASI index |
GET /market/gainers/ |
Free | Top gainers |
GET /market/losers/ |
Free | Top losers |
GET /market/volume/ |
Free | Volume leaders |
GET /market/value/ |
Free | Value leaders |
GET /market/sectors/ |
Free | Sector performance |
GET /company/{symbol}/ |
Free+ | Company info (tiered by plan) |
GET /financials/{symbol}/ |
Starter+ | Financial statements |
GET /dividends/{symbol}/ |
Starter+ | Dividend history & yield |
GET /events/ |
Pro+ | AI-generated stock events |
All endpoints require the X-API-Key header.
Full docs: sahmk.sa/developers/docs
Changelog: CHANGELOG.md
Roadmap: ROADMAP.md
WebSocket Streaming (Pro+)
import asyncio
from sahmk import SahmkClient
client = SahmkClient("your_api_key")
async def on_quote(msg):
symbol = msg["symbol"]
price = msg["data"]["price"]
print(f"{symbol}: {price}")
asyncio.run(client.stream(["2222", "1120"], on_quote=on_quote))
Auto-Reconnect
The streaming client automatically reconnects on disconnect with exponential backoff. All symbols are resubscribed after reconnection.
async def on_disconnect(reason):
print(f"Disconnected: {reason}")
async def on_reconnect(attempt):
print(f"Reconnecting (attempt #{attempt})...")
await client.stream(
["2222", "1120"],
on_quote=on_quote,
on_disconnect=on_disconnect,
on_reconnect=on_reconnect,
# max_reconnect_attempts=0 means unlimited (default)
# Set to -1 to disable reconnect entirely
)
Connection URL: wss://app.sahmk.sa/ws/v1/stocks/?api_key=YOUR_KEY
License
MIT — see LICENSE
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sahmk-0.6.0.tar.gz.
File metadata
- Download URL: sahmk-0.6.0.tar.gz
- Upload date:
- Size: 34.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0556f9792f6f11694286ee198d64b6f130df14140ca0ca40c3a0f15d17712737
|
|
| MD5 |
4a186b1cf14f336a2ca3d8b2749384e8
|
|
| BLAKE2b-256 |
ad36ac7cfac8caab02d479997c2c73ced051903c26370fd99fd9daf8b0be9fbd
|
Provenance
The following attestation bundles were made for sahmk-0.6.0.tar.gz:
Publisher:
publish-pypi.yml on sahmk-sa/sahmk-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sahmk-0.6.0.tar.gz -
Subject digest:
0556f9792f6f11694286ee198d64b6f130df14140ca0ca40c3a0f15d17712737 - Sigstore transparency entry: 1215469368
- Sigstore integration time:
-
Permalink:
sahmk-sa/sahmk-python@5e8cc92fcd3cfd34518724fba42c61168fd6a12a -
Branch / Tag:
refs/tags/v0.6.0 - Owner: https://github.com/sahmk-sa
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@5e8cc92fcd3cfd34518724fba42c61168fd6a12a -
Trigger Event:
release
-
Statement type:
File details
Details for the file sahmk-0.6.0-py3-none-any.whl.
File metadata
- Download URL: sahmk-0.6.0-py3-none-any.whl
- Upload date:
- Size: 16.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
44e127bc234b96ec65ca08ffda13cc5f16b08d01dd5eb269a65019bfa0620d67
|
|
| MD5 |
64317dbacbc31cd28ea39d91920d984b
|
|
| BLAKE2b-256 |
d13bba22cf7d1f37625ce410d658328aea1ec8639b2d4f745db0746251bf71af
|
Provenance
The following attestation bundles were made for sahmk-0.6.0-py3-none-any.whl:
Publisher:
publish-pypi.yml on sahmk-sa/sahmk-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sahmk-0.6.0-py3-none-any.whl -
Subject digest:
44e127bc234b96ec65ca08ffda13cc5f16b08d01dd5eb269a65019bfa0620d67 - Sigstore transparency entry: 1215469424
- Sigstore integration time:
-
Permalink:
sahmk-sa/sahmk-python@5e8cc92fcd3cfd34518724fba42c61168fd6a12a -
Branch / Tag:
refs/tags/v0.6.0 - Owner: https://github.com/sahmk-sa
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@5e8cc92fcd3cfd34518724fba42c61168fd6a12a -
Trigger Event:
release
-
Statement type: