Unofficial Python client for the MarketSurge stock research API
Project description
tickerscope
Unofficial async Python client for the MarketSurge stock research API. Wraps the GraphQL endpoints with typed dataclass models, cookie-based auth, and optional caching.
[!IMPORTANT] This is an unofficial library. You need an active MarketSurge subscription and must be logged in via your browser for authentication to work.
Features
- Sync and async clients (
TickerScopeClient/AsyncTickerScopeClient) - Frozen dataclass models with JSON serialization via mashumaro
- Automatic JWT auth from browser cookies (Firefox/Chrome) via rookiepy
- Optional response caching with aiocache
- Token expiry detection and structured error hierarchy
Installation
pip install tickerscope
With optional caching support:
pip install tickerscope[cache]
Authentication
tickerscope authenticates by extracting cookies from your browser. Log into MarketSurge in Firefox or Chrome first, then:
from tickerscope import TickerScopeClient
# Reads cookies from Firefox by default
client = TickerScopeClient()
# Or specify Chrome
client = TickerScopeClient(browser="chrome")
You can also pass a JWT directly or set the TICKERSCOPE_JWT environment variable:
client = TickerScopeClient(jwt="your-jwt-token")
Usage
Sync client
from tickerscope import TickerScopeClient
with TickerScopeClient() as client:
stock = client.get_stock("AAPL")
print(stock.ratings.composite)
print(stock.pricing.price)
chart = client.get_chart_data(
"AAPL",
start_date="2025-01-01",
end_date="2025-03-01",
)
for point in chart.time_series.data_points[:5]:
print(point.close, point.volume)
Async client
import asyncio
from tickerscope import AsyncTickerScopeClient
async def main():
async with AsyncTickerScopeClient(cache_ttl=300) as client:
stock = await client.get_stock("NVDA")
print(stock.company.name, stock.ratings.composite)
fundamentals = await client.get_fundamentals("NVDA")
for period in fundamentals.reported_earnings:
print(period.period_label, period.value)
asyncio.run(main())
Async client (fully async construction)
Use the create() factory for fully async initialization, including the auth
HTTP request:
async def main():
client = await AsyncTickerScopeClient.create(cache_ttl=300)
try:
stock = await client.get_stock("TSLA")
print(stock.ratings)
finally:
await client.aclose()
Available methods
| Method | Returns | Description |
|---|---|---|
get_stock(symbol) |
StockData |
Ratings, pricing, financials, patterns |
get_chart_data(symbol, ...) |
ChartData |
OHLCV time series and quotes |
get_fundamentals(symbol) |
FundamentalData |
Earnings/sales reported and estimates |
get_ownership(symbol) |
OwnershipData |
Institutional fund ownership |
get_watchlist(list_id) |
list[WatchlistEntry] |
Watchlist entries by list ID |
get_watchlist_names() |
list[WatchlistSummary] |
All watchlist names |
get_watchlist_items(id) |
WatchlistDetail |
Watchlist items by watchlist ID |
get_watchlist_by_name(name) |
WatchlistDetail |
Look up watchlist by name |
get_screens() |
list[Screen] |
Saved stock screens |
get_screen_by_name(name) |
Screen |
Look up screen by name |
run_screen(name, params) |
ScreenResult |
Execute a stock screen |
get_active_alerts() |
AlertSubscriptionList |
Active alert subscriptions |
get_triggered_alerts() |
TriggeredAlertList |
Recently triggered alerts |
get_layouts() |
list[Layout] |
Saved chart layouts |
get_chart_markups(symbol) |
ChartMarkupList |
Chart annotations/markups |
Most async methods accept use_cache=True (default) when caching is enabled via cache_ttl.
Error handling
All exceptions inherit from TickerScopeError and include a to_dict() method
for structured error reporting:
from tickerscope import (
TickerScopeError,
AuthenticationError,
CookieExtractionError,
TokenExpiredError,
APIError,
SymbolNotFoundError,
)
try:
stock = client.get_stock("INVALID")
except SymbolNotFoundError as exc:
print(exc.symbol)
print(exc.to_dict())
except TokenExpiredError:
# Re-authenticate and retry
...
Development
Requires uv for dependency management:
uv sync --all-extras --dev
make lint # ruff check
make typecheck # ty check
make radon # cyclomatic complexity gate (A/B only)
make test # pytest with coverage
make ci # all of the above
License
MIT
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
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 tickerscope-0.1.1.tar.gz.
File metadata
- Download URL: tickerscope-0.1.1.tar.gz
- Upload date:
- Size: 29.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b1af4f5a7bc1845d4afba423247f0f8a53818f77898fbf7d29ce217152726b04
|
|
| MD5 |
bc82d16f42669b4dc86356627f5b050a
|
|
| BLAKE2b-256 |
0ef01f5664876f4c7b6f99f297cbcf8ae3ca2ebaf579ef3451ce6c2d3371cce5
|
Provenance
The following attestation bundles were made for tickerscope-0.1.1.tar.gz:
Publisher:
release.yml on major/tickerscope
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tickerscope-0.1.1.tar.gz -
Subject digest:
b1af4f5a7bc1845d4afba423247f0f8a53818f77898fbf7d29ce217152726b04 - Sigstore transparency entry: 1173394726
- Sigstore integration time:
-
Permalink:
major/tickerscope@7d6b08542649726963b136b661f146e496f777fd -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/major
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@7d6b08542649726963b136b661f146e496f777fd -
Trigger Event:
push
-
Statement type:
File details
Details for the file tickerscope-0.1.1-py3-none-any.whl.
File metadata
- Download URL: tickerscope-0.1.1-py3-none-any.whl
- Upload date:
- Size: 37.1 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 |
d968ced76aa6ad2f9df9db8a21a94dd31e2c70b2df4bd1be8d9ae471d3d7a1dd
|
|
| MD5 |
763ecf4b20963a83e059b96999756a89
|
|
| BLAKE2b-256 |
b161f7ce505a415dea5c25fffe5f738f8f2e280a34811f8e7f73ff507246aa09
|
Provenance
The following attestation bundles were made for tickerscope-0.1.1-py3-none-any.whl:
Publisher:
release.yml on major/tickerscope
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tickerscope-0.1.1-py3-none-any.whl -
Subject digest:
d968ced76aa6ad2f9df9db8a21a94dd31e2c70b2df4bd1be8d9ae471d3d7a1dd - Sigstore transparency entry: 1173394774
- Sigstore integration time:
-
Permalink:
major/tickerscope@7d6b08542649726963b136b661f146e496f777fd -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/major
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@7d6b08542649726963b136b661f146e496f777fd -
Trigger Event:
push
-
Statement type: