Official Python SDK for Sahmk — Saudi market data and richer market workflows for developers.
Project description
SAHMK Python SDK
Official Python SDK for Sahmk — Saudi market data and richer market workflows for developers.
Use one client for live Tadawul quotes, market-level insights, company/fundamental data, financials, events, and historical series.
Features
- Real-time quotes for 350+ Tadawul stocks
- Batch quotes for up to 50 symbols per request
- Historical OHLCV data with date-range support
- Market overview with index scoping (
TASI/NOMU) - Company directory endpoint for symbol discovery
- Company/fundamental data (plan-dependent fields)
- Financials, dividends, and events endpoints (by plan)
- WebSocket streaming for real-time updates (Pro+)
Installation
pip install sahmk
For local development:
git clone https://github.com/sahmk-sa/sahmk-python.git
cd sahmk-python
pip install -r requirements.txt
Security
- Use environment variables for API keys (recommended:
SAHMK_API_KEY). - Never commit API keys to source control, notebooks, or logs.
- If a key is exposed, rotate it immediately from your Sahmk dashboard.
Quick Start
import os
from sahmk import SahmkClient
client = SahmkClient(os.environ["SAHMK_API_KEY"])
quote = client.quote("2222")
print(f"{quote['name_en']}: {quote['price']} SAR ({quote['change_percent']}%)")
market = client.market_summary(index="TASI")
print(f"TASI: {market['index_value']} ({market['index_change_percent']}%)")
# Batch quotes are Starter+ plan.
for q in client.quotes(["2222", "1120", "7010"])["quotes"]:
print(f"{q['symbol']}: {q['price']}")
Identifier Resolution (Quotes)
quote() and quotes() accept either traditional symbols or resolvable identifiers:
- Symbol:
"2222" - Arabic company name:
"أرامكو السعودية" - English company name/alias:
"Aramco"
Symbol input always works. Name/alias input requires backend identifier-resolution support.
For batch quotes, the SDK first tries identifiers=..., then automatically falls back to
legacy symbols=... when connected to older backends.
q1 = client.quote("2222") # classic symbol usage
q2 = client.quote("أرامكو السعودية") # Arabic identifier
q3 = client.quote("Aramco") # English alias
batch = client.quotes(["2222", "الراجحي", "SABIC"])
for q in batch.quotes:
print(q.requested_identifier, "=>", q.symbol)
if batch.ambiguous:
print("Ambiguous:", batch.ambiguous)
if batch.unknown:
print("Unknown:", batch.unknown)
When the backend returns resolution metadata, it is exposed on typed objects:
quote = client.quote("Aramco")
print(quote.requested_identifier) # Aramco
print(quote.resolved_symbol) # 2222
print(quote.resolution.matched_by) # alias (if provided by API)
Company Directory / Symbol Discovery
Use companies() as the canonical symbol-discovery path before calling
quote() or company().
# Search by symbol or name
directory = client.companies(search="aram")
for row in directory["results"]:
print(row["symbol"], row.get("name_en") or row.get("name"))
# Filter by market (TASI / NOMU, NOMUC alias is accepted)
nomu_companies = client.companies(market="NOMUC", limit=20)
print(nomu_companies["count"])
# Pagination loop with offset
offset = 0
page_size = 100
while True:
page = client.companies(limit=page_size, offset=offset)
for company in page["results"]:
print(company["symbol"])
offset += page_size
if offset >= page["total"]:
break
Recommended flow:
- Discover valid symbols with
companies(). - Call
quote(symbol)/company(symbol)with a validated symbol.
Production Reliability
- The client retries transient failures: HTTP 429 and 5xx errors.
- Defaults:
retries=3,backoff_factor=0.5(0.5s, 1s, 2s). - Invalid symbols, authentication failures, and plan-access errors are not retryable.
from sahmk import SahmkClient
client = SahmkClient("your_api_key", retries=3, backoff_factor=0.5)
Plan Behavior
Some methods are plan-gated (for example quotes, historical, financials, dividends, events).
When your plan does not include an endpoint, the API returns an error response (not retried automatically).
CLI Quick Start
export SAHMK_API_KEY="your_api_key"
sahmk quote 2222
sahmk market summary --index NOMU
sahmk market gainers --limit 5 --index NOMUC
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
Most methods return typed objects with IDE autocomplete while preserving dict-style access.
Analytics methods (ratios, compare) return raw API dict responses to match the
production contract exactly.
quote = client.quote("2222")
print(quote.price)
print(quote.liquidity.net_value)
# Backwards-compatible dict access
print(quote["price"])
print(quote.get("volume"))
print(quote.raw)
Financials & Analytics
client.financials("1120", history="3y", result="latest")
client.ratios("1120")
client.ratios("1120", history="5y", period="quarterly", metrics="extended")
client.compare(["1120", "1180", "1010"])
client.compare(["1120", "1180", "1010", "2222"], metrics="extended")
Financials responses no longer include meta. Existing financial statement sections
(income_statements, balance_sheets, cash_flows) are unchanged.
Analytics meta remains minimal and includes only:
periodmetricswarnings
Market Index Scoping
Supported values:
TASINOMUNOMUCalias (normalized toNOMU)
summary = client.market_summary(index="NOMUC")
print(summary.index) # NOMU
print(summary.is_delayed) # True/False by entitlement
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 |
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 /companies/ |
Free | Company directory and symbol discovery |
GET /company/{symbol}/ |
Free+ | Company info (tiered by plan) |
GET /financials/{symbol}/ |
Starter+ | Financial statements |
GET /analytics/ratios/{symbol}/ |
Starter+ | Analytics ratios for one company |
GET /analytics/compare/ |
Starter+ | Analytics comparison across companies |
GET /dividends/{symbol}/ |
Starter+ | Dividend history and yield |
GET /events/ |
Pro+ | AI-generated stock events |
All endpoints require X-API-Key.
Full docs: sahmk.sa/developers/docs
Examples
Example scripts:
WebSocket Streaming (Pro+)
import asyncio
from sahmk import SahmkClient
client = SahmkClient("your_api_key")
async def on_quote(msg):
print(f"{msg['symbol']}: {msg['data']['price']}")
asyncio.run(client.stream(["2222", "1120"], on_quote=on_quote))
The streaming client auto-reconnects with exponential backoff and resubscribes symbols.
Changelog: CHANGELOG.md
Roadmap: ROADMAP.md
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.9.2.tar.gz.
File metadata
- Download URL: sahmk-0.9.2.tar.gz
- Upload date:
- Size: 44.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0e7832f1822a78265264f6ab5defe87b49a48dc64f7fed4de818bf58fe5b98d9
|
|
| MD5 |
af2caf90b046e06401ca2ddbb8beb62f
|
|
| BLAKE2b-256 |
bbdf81204958a2401ff8af45703f15f65d01a5e3c5ad6f3fd9993521ef63241c
|
Provenance
The following attestation bundles were made for sahmk-0.9.2.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.9.2.tar.gz -
Subject digest:
0e7832f1822a78265264f6ab5defe87b49a48dc64f7fed4de818bf58fe5b98d9 - Sigstore transparency entry: 1406070609
- Sigstore integration time:
-
Permalink:
sahmk-sa/sahmk-python@c9c65768f35388f9ed4b043c4b571ea58dc038cb -
Branch / Tag:
refs/heads/main - Owner: https://github.com/sahmk-sa
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@c9c65768f35388f9ed4b043c4b571ea58dc038cb -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file sahmk-0.9.2-py3-none-any.whl.
File metadata
- Download URL: sahmk-0.9.2-py3-none-any.whl
- Upload date:
- Size: 21.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ee106f4772d182f8472c6f7d475ae1c144df74503250cdba498147b1dbe86302
|
|
| MD5 |
26f97ab7dcd45d34afc279351eb630d4
|
|
| BLAKE2b-256 |
1cf0dd852bceaf0a19db2dab6cef31b79bd720505321af24b4919482f8694ac5
|
Provenance
The following attestation bundles were made for sahmk-0.9.2-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.9.2-py3-none-any.whl -
Subject digest:
ee106f4772d182f8472c6f7d475ae1c144df74503250cdba498147b1dbe86302 - Sigstore transparency entry: 1406070626
- Sigstore integration time:
-
Permalink:
sahmk-sa/sahmk-python@c9c65768f35388f9ed4b043c4b571ea58dc038cb -
Branch / Tag:
refs/heads/main - Owner: https://github.com/sahmk-sa
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@c9c65768f35388f9ed4b043c4b571ea58dc038cb -
Trigger Event:
workflow_dispatch
-
Statement type: