Skip to main content

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:

  1. Discover valid symbols with companies().
  2. 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

All methods return typed objects with IDE autocomplete while preserving dict-style access.

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")

Market Index Scoping

Supported values:

  • TASI
  • NOMU
  • NOMUC alias (normalized to NOMU)
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 /ratios/{symbol}/ Starter+ Analytics ratios for one company
GET /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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sahmk-0.9.0.tar.gz (43.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

sahmk-0.9.0-py3-none-any.whl (20.8 kB view details)

Uploaded Python 3

File details

Details for the file sahmk-0.9.0.tar.gz.

File metadata

  • Download URL: sahmk-0.9.0.tar.gz
  • Upload date:
  • Size: 43.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for sahmk-0.9.0.tar.gz
Algorithm Hash digest
SHA256 f6165b4afab46b7f77cab3c70f78759c96fa2a28b5c4c058a6ee1e8a19d55ac8
MD5 b11dce9ac30703d43c6db3cd818e28cd
BLAKE2b-256 09027398a9348af1535b412cd0f3543c50f76dcde580c10c6bbcda7aa4b5e740

See more details on using hashes here.

Provenance

The following attestation bundles were made for sahmk-0.9.0.tar.gz:

Publisher: publish-pypi.yml on sahmk-sa/sahmk-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file sahmk-0.9.0-py3-none-any.whl.

File metadata

  • Download URL: sahmk-0.9.0-py3-none-any.whl
  • Upload date:
  • Size: 20.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for sahmk-0.9.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a62edb1503f882243a9f309d0f4561d4bfef6e1affd430a009898d6da44e4848
MD5 a815118c6acace378ac173769228d714
BLAKE2b-256 f1ff15c9c90eb37f378a6d62fa922f345613865f4a4ffbbb6308b532867a82af

See more details on using hashes here.

Provenance

The following attestation bundles were made for sahmk-0.9.0-py3-none-any.whl:

Publisher: publish-pypi.yml on sahmk-sa/sahmk-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page