marketstack-python-client 1.0.0__py3-none-any.whl
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.
- marketstack/__init__.py +1 -0
- marketstack/client/__init__.py +0 -0
- marketstack/client/http.py +36 -0
- marketstack/client/marketstack.py +148 -0
- marketstack/models/__init__.py +0 -0
- marketstack/models/bond.py +47 -0
- marketstack/models/cik_code.py +26 -0
- marketstack/models/commodity.py +83 -0
- marketstack/models/company.py +278 -0
- marketstack/models/concept.py +65 -0
- marketstack/models/currency.py +23 -0
- marketstack/models/dividend.py +27 -0
- marketstack/models/eod.py +48 -0
- marketstack/models/etf.py +129 -0
- marketstack/models/exchange.py +117 -0
- marketstack/models/index.py +47 -0
- marketstack/models/intraday.py +43 -0
- marketstack/models/pagination.py +42 -0
- marketstack/models/split.py +24 -0
- marketstack/models/stockprice.py +31 -0
- marketstack/models/ticker.py +159 -0
- marketstack/models/ticker_info.py +197 -0
- marketstack/models/timezone.py +21 -0
- marketstack/namespaces/__init__.py +0 -0
- marketstack/namespaces/bond/__init__.py +1 -0
- marketstack/namespaces/bond/bond.py +12 -0
- marketstack/namespaces/bondlist/__init__.py +1 -0
- marketstack/namespaces/bondlist/bondlist.py +12 -0
- marketstack/namespaces/cikcode/__init__.py +1 -0
- marketstack/namespaces/cikcode/cikcode.py +12 -0
- marketstack/namespaces/commodities/__init__.py +1 -0
- marketstack/namespaces/commodities/commodities.py +12 -0
- marketstack/namespaces/commoditieshistory/__init__.py +1 -0
- marketstack/namespaces/commoditieshistory/commoditieshistory.py +12 -0
- marketstack/namespaces/company_facts/__init__.py +1 -0
- marketstack/namespaces/company_facts/company_facts.py +12 -0
- marketstack/namespaces/companyname/__init__.py +1 -0
- marketstack/namespaces/companyname/companyname.py +12 -0
- marketstack/namespaces/companyratings/__init__.py +1 -0
- marketstack/namespaces/companyratings/companyratings.py +12 -0
- marketstack/namespaces/concept/__init__.py +1 -0
- marketstack/namespaces/concept/concept.py +12 -0
- marketstack/namespaces/currencies/__init__.py +1 -0
- marketstack/namespaces/currencies/currencies.py +12 -0
- marketstack/namespaces/dividends/__init__.py +1 -0
- marketstack/namespaces/dividends/dividends.py +12 -0
- marketstack/namespaces/eod/__init__.py +1 -0
- marketstack/namespaces/eod/eod.py +20 -0
- marketstack/namespaces/etfholdings/__init__.py +1 -0
- marketstack/namespaces/etfholdings/etfholdings.py +12 -0
- marketstack/namespaces/etflist/__init__.py +1 -0
- marketstack/namespaces/etflist/etflist.py +12 -0
- marketstack/namespaces/exchanges/__init__.py +1 -0
- marketstack/namespaces/exchanges/exchanges.py +109 -0
- marketstack/namespaces/frames/__init__.py +1 -0
- marketstack/namespaces/frames/frames.py +12 -0
- marketstack/namespaces/indexinfo/__init__.py +1 -0
- marketstack/namespaces/indexinfo/indexinfo.py +12 -0
- marketstack/namespaces/indexlist/__init__.py +1 -0
- marketstack/namespaces/indexlist/indexlist.py +12 -0
- marketstack/namespaces/intraday/__init__.py +1 -0
- marketstack/namespaces/intraday/intraday.py +20 -0
- marketstack/namespaces/splits/__init__.py +1 -0
- marketstack/namespaces/splits/splits.py +12 -0
- marketstack/namespaces/stockprice/__init__.py +1 -0
- marketstack/namespaces/stockprice/stockprice.py +12 -0
- marketstack/namespaces/submissions/__init__.py +1 -0
- marketstack/namespaces/submissions/submissions.py +12 -0
- marketstack/namespaces/tickerinfo/__init__.py +1 -0
- marketstack/namespaces/tickerinfo/tickerinfo.py +12 -0
- marketstack/namespaces/tickers/__init__.py +1 -0
- marketstack/namespaces/tickers/tickers.py +150 -0
- marketstack/namespaces/tickerslist/__init__.py +1 -0
- marketstack/namespaces/tickerslist/tickerslist.py +12 -0
- marketstack/namespaces/timezones/__init__.py +1 -0
- marketstack/namespaces/timezones/timezones.py +12 -0
- marketstack_python_client-1.0.0.dist-info/METADATA +182 -0
- marketstack_python_client-1.0.0.dist-info/RECORD +81 -0
- marketstack_python_client-1.0.0.dist-info/WHEEL +5 -0
- marketstack_python_client-1.0.0.dist-info/licenses/LICENSE +21 -0
- marketstack_python_client-1.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
from marketstack.client.http import HTTPClient
|
|
2
|
+
from typing import Unpack
|
|
3
|
+
from marketstack.models.exchange import (
|
|
4
|
+
Exchange,
|
|
5
|
+
ExchangesResponse,
|
|
6
|
+
ExchangeMicTickersResponse,
|
|
7
|
+
ExchangesMicEod,
|
|
8
|
+
ExchangesMicIntraday,
|
|
9
|
+
ExchangesMicIntradayLatest,
|
|
10
|
+
ExchangesRequest,
|
|
11
|
+
ExchangeTickersRequest,
|
|
12
|
+
)
|
|
13
|
+
from marketstack.models.eod import EODRequest, EODLatestRequest
|
|
14
|
+
from marketstack.models.intraday import IntradayResponse, IntradayRequest
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class Exchanges:
|
|
18
|
+
def __init__(self, http_client: HTTPClient):
|
|
19
|
+
self.http_client = http_client
|
|
20
|
+
|
|
21
|
+
def list(self, **params: Unpack[ExchangesRequest]) -> ExchangesResponse:
|
|
22
|
+
"""List stock exchanges."""
|
|
23
|
+
return ExchangesResponse.model_validate(self.http_client.get("/v2/exchanges", params=params))
|
|
24
|
+
|
|
25
|
+
def __call__(self, mic: str) -> "ExchangeInstance":
|
|
26
|
+
return ExchangeInstance(http_client=self.http_client, mic=mic)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class ExchangeInstance:
|
|
30
|
+
def __init__(self, http_client: HTTPClient, mic: str):
|
|
31
|
+
self.http_client = http_client
|
|
32
|
+
self.mic = mic
|
|
33
|
+
|
|
34
|
+
def get(self) -> Exchange:
|
|
35
|
+
"""Obtain stock exchange by MIC."""
|
|
36
|
+
res = self.http_client.get(f"/v2/exchanges/{self.mic}")
|
|
37
|
+
return Exchange.model_validate(res["data"])
|
|
38
|
+
|
|
39
|
+
@property
|
|
40
|
+
def eod(self) -> "ExchangeEOD":
|
|
41
|
+
return ExchangeEOD(http_client=self.http_client, mic=self.mic)
|
|
42
|
+
|
|
43
|
+
@property
|
|
44
|
+
def intraday(self) -> "ExchangeIntraday":
|
|
45
|
+
return ExchangeIntraday(http_client=self.http_client, mic=self.mic)
|
|
46
|
+
|
|
47
|
+
@property
|
|
48
|
+
def tickers(self) -> "ExchangeTickers":
|
|
49
|
+
return ExchangeTickers(http_client=self.http_client, mic=self.mic)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class ExchangeEOD:
|
|
53
|
+
def __init__(self, http_client: HTTPClient, mic: str):
|
|
54
|
+
self.http_client = http_client
|
|
55
|
+
self.mic = mic
|
|
56
|
+
|
|
57
|
+
def list(self, **params: Unpack[EODRequest]) -> ExchangesMicEod:
|
|
58
|
+
"""Obtain exchange end-of-day data."""
|
|
59
|
+
return ExchangesMicEod.model_validate(
|
|
60
|
+
self.http_client.get(f"/v2/exchanges/{self.mic}/eod", params=params)
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
def latest(self, **params: Unpack[EODLatestRequest]) -> ExchangesMicEod:
|
|
64
|
+
"""Obtain exchange latest end-of-day data."""
|
|
65
|
+
return ExchangesMicEod.model_validate(
|
|
66
|
+
self.http_client.get(f"/v2/exchanges/{self.mic}/eod/latest", params=params)
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
def for_a_date(self, date: str, **params: Unpack[EODLatestRequest]) -> ExchangesMicEod:
|
|
70
|
+
"""Obtain exchange end-of-day data for a date."""
|
|
71
|
+
return ExchangesMicEod.model_validate(
|
|
72
|
+
self.http_client.get(f"/v2/exchanges/{self.mic}/eod/{date}", params=params)
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
class ExchangeIntraday:
|
|
77
|
+
def __init__(self, http_client: HTTPClient, mic: str):
|
|
78
|
+
self.http_client = http_client
|
|
79
|
+
self.mic = mic
|
|
80
|
+
|
|
81
|
+
def list(self, **params: Unpack[IntradayRequest]) -> ExchangesMicIntraday:
|
|
82
|
+
"""Obtain exchange intraday data."""
|
|
83
|
+
return ExchangesMicIntraday.model_validate(
|
|
84
|
+
self.http_client.get(f"/v2/exchanges/{self.mic}/intraday", params=params)
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
def latest(self, **params: Unpack[IntradayRequest]) -> ExchangesMicIntradayLatest:
|
|
88
|
+
"""Obtain exchange latest intraday data."""
|
|
89
|
+
return ExchangesMicIntradayLatest.model_validate(
|
|
90
|
+
self.http_client.get(f"/v2/exchanges/{self.mic}/intraday/latest", params=params)
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
def for_a_date(self, date: str, **params: Unpack[IntradayRequest]) -> ExchangesMicIntradayLatest:
|
|
94
|
+
"""Obtain exchange intraday data for a date."""
|
|
95
|
+
return ExchangesMicIntradayLatest.model_validate(
|
|
96
|
+
self.http_client.get(f"/v2/exchanges/{self.mic}/intraday/{date}", params=params)
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
class ExchangeTickers:
|
|
101
|
+
def __init__(self, http_client: HTTPClient, mic: str):
|
|
102
|
+
self.http_client = http_client
|
|
103
|
+
self.mic = mic
|
|
104
|
+
|
|
105
|
+
def list(self, **params: Unpack[ExchangeTickersRequest]) -> ExchangeMicTickersResponse:
|
|
106
|
+
"""List tickers for an exchange."""
|
|
107
|
+
return ExchangeMicTickersResponse.model_validate(
|
|
108
|
+
self.http_client.get(f"/v2/exchanges/{self.mic}/tickers", params=params)
|
|
109
|
+
)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .frames import Frames
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from marketstack.client.http import HTTPClient
|
|
2
|
+
from typing import Unpack
|
|
3
|
+
from marketstack.models.concept import FrameResponse, FramesRequest
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Frames:
|
|
7
|
+
def __init__(self, http_client: HTTPClient):
|
|
8
|
+
self.http_client = http_client
|
|
9
|
+
|
|
10
|
+
def get_accounts_payable(self, unit: str, **params: Unpack[FramesRequest]) -> FrameResponse:
|
|
11
|
+
"""Obtain Accounts Payable Frames."""
|
|
12
|
+
return FrameResponse.model_validate(self.http_client.get(f"/v2/frames/accounts_payable/{unit}", params=params))
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .indexinfo import IndexInfo
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from marketstack.client.http import HTTPClient
|
|
2
|
+
from typing import Unpack
|
|
3
|
+
from marketstack.models.index import IndexInfoResponse, IndexInfoRequest
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class IndexInfo:
|
|
7
|
+
def __init__(self, http_client: HTTPClient):
|
|
8
|
+
self.http_client = http_client
|
|
9
|
+
|
|
10
|
+
def get(self, **params: Unpack[IndexInfoRequest]) -> IndexInfoResponse:
|
|
11
|
+
"""Obtain market index information."""
|
|
12
|
+
return IndexInfoResponse.model_validate(self.http_client.get("/v2/indexinfo", params=params))
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .indexlist import IndexList
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from marketstack.client.http import HTTPClient
|
|
2
|
+
from typing import Unpack
|
|
3
|
+
from marketstack.models.index import IndexListResponse, IndexListRequest
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class IndexList:
|
|
7
|
+
def __init__(self, http_client: HTTPClient):
|
|
8
|
+
self.http_client = http_client
|
|
9
|
+
|
|
10
|
+
def list(self, **params: Unpack[IndexListRequest]) -> IndexListResponse:
|
|
11
|
+
"""List market indices."""
|
|
12
|
+
return IndexListResponse.model_validate(self.http_client.get("/v2/indexlist", params=params))
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .intraday import Intraday
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
from marketstack.client.http import HTTPClient
|
|
2
|
+
from typing import Unpack
|
|
3
|
+
from marketstack.models.intraday import IntradayResponse, IntradayRequest
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Intraday:
|
|
7
|
+
def __init__(self, http_client: HTTPClient):
|
|
8
|
+
self.http_client = http_client
|
|
9
|
+
|
|
10
|
+
def list(self, **params: Unpack[IntradayRequest]) -> IntradayResponse:
|
|
11
|
+
"""Obtain intraday data."""
|
|
12
|
+
return IntradayResponse.model_validate(self.http_client.get("/v2/intraday", params=params))
|
|
13
|
+
|
|
14
|
+
def latest(self, **params: Unpack[IntradayRequest]) -> IntradayResponse:
|
|
15
|
+
"""Obtain latest intraday data."""
|
|
16
|
+
return IntradayResponse.model_validate(self.http_client.get("/v2/intraday/latest", params=params))
|
|
17
|
+
|
|
18
|
+
def for_a_date(self, date: str, **params: Unpack[IntradayRequest]) -> IntradayResponse:
|
|
19
|
+
"""Obtain intraday data for a specific date."""
|
|
20
|
+
return IntradayResponse.model_validate(self.http_client.get(f"/v2/intraday/{date}", params=params))
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .splits import Splits
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from marketstack.client.http import HTTPClient
|
|
2
|
+
from typing import Unpack
|
|
3
|
+
from marketstack.models.split import SplitsResponse, SplitsRequest
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Splits:
|
|
7
|
+
def __init__(self, http_client: HTTPClient):
|
|
8
|
+
self.http_client = http_client
|
|
9
|
+
|
|
10
|
+
def list(self, **params: Unpack[SplitsRequest]) -> SplitsResponse:
|
|
11
|
+
"""List stock splits."""
|
|
12
|
+
return SplitsResponse.model_validate(self.http_client.get("/v2/splits", params=params))
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .stockprice import StockPrice
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from marketstack.client.http import HTTPClient
|
|
2
|
+
from typing import Unpack
|
|
3
|
+
from marketstack.models.stockprice import StockPriceResponse, StockPriceRequest
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class StockPrice:
|
|
7
|
+
def __init__(self, http_client: HTTPClient):
|
|
8
|
+
self.http_client = http_client
|
|
9
|
+
|
|
10
|
+
def get(self, **params: Unpack[StockPriceRequest]) -> StockPriceResponse:
|
|
11
|
+
"""Obtain real-time stock price."""
|
|
12
|
+
return StockPriceResponse.model_validate(self.http_client.get("/v2/stockprice", params=params))
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .submissions import Submissions
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from marketstack.client.http import HTTPClient
|
|
2
|
+
from typing import Unpack
|
|
3
|
+
from marketstack.models.company import SubmissionsByCIKResponse, SubmissionsRequest
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Submissions:
|
|
7
|
+
def __init__(self, http_client: HTTPClient):
|
|
8
|
+
self.http_client = http_client
|
|
9
|
+
|
|
10
|
+
def get(self, **params: Unpack[SubmissionsRequest]) -> SubmissionsByCIKResponse:
|
|
11
|
+
"""Obtain SEC Submissions."""
|
|
12
|
+
return SubmissionsByCIKResponse.model_validate(self.http_client.get("/v2/submissions", params=params))
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .tickerinfo import TickerInfo
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from marketstack.client.http import HTTPClient
|
|
2
|
+
from typing import Unpack
|
|
3
|
+
from marketstack.models.ticker_info import TickerInfoResponse, TickerInfoRequest
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class TickerInfo:
|
|
7
|
+
def __init__(self, http_client: HTTPClient):
|
|
8
|
+
self.http_client = http_client
|
|
9
|
+
|
|
10
|
+
def get(self, **params: Unpack[TickerInfoRequest]) -> TickerInfoResponse:
|
|
11
|
+
"""Obtain ticker information."""
|
|
12
|
+
return TickerInfoResponse.model_validate(self.http_client.get("/v2/tickerinfo", params=params))
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .tickers import Tickers
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
from marketstack.client.http import HTTPClient
|
|
2
|
+
from marketstack.models.ticker import (
|
|
3
|
+
TickerResponse,
|
|
4
|
+
TickerSplitsRequest,
|
|
5
|
+
TickerSplitsResponse,
|
|
6
|
+
TickerEODRequest,
|
|
7
|
+
TickerEODResponse,
|
|
8
|
+
TickerEODLatestRequest,
|
|
9
|
+
TickerIntradayRequest,
|
|
10
|
+
TickerDividendsRequest,
|
|
11
|
+
)
|
|
12
|
+
from marketstack.models.ticker_info import (
|
|
13
|
+
TickerIntradayResponse,
|
|
14
|
+
TickerDividendsResponse,
|
|
15
|
+
)
|
|
16
|
+
from marketstack.models.intraday import IntradayBar, IntradayResponse
|
|
17
|
+
from typing import Unpack
|
|
18
|
+
from marketstack.models.eod import EODBar
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class Tickers:
|
|
22
|
+
def __init__(self, http_client: HTTPClient):
|
|
23
|
+
self.http_client = http_client
|
|
24
|
+
|
|
25
|
+
def __call__(self, symbol: str) -> "Ticker":
|
|
26
|
+
return Ticker(http_client=self.http_client, symbol=symbol)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class Ticker:
|
|
30
|
+
def __init__(self, http_client: HTTPClient, symbol: str):
|
|
31
|
+
self.http_client = http_client
|
|
32
|
+
self.symbol = symbol
|
|
33
|
+
|
|
34
|
+
def get(self) -> TickerResponse:
|
|
35
|
+
"""Using the API's Tickers endpoint you will be able to look up information about one or multiple stock ticker symbols as well as obtain end-of-day, real-time and intraday market data for single tickers."""
|
|
36
|
+
return TickerResponse.model_validate(self.http_client.get(f"/v2/tickers/{self.symbol}"))
|
|
37
|
+
|
|
38
|
+
@property
|
|
39
|
+
def eod(self) -> "TickerEOD":
|
|
40
|
+
return TickerEOD(http_client=self.http_client, symbol=self.symbol)
|
|
41
|
+
|
|
42
|
+
@property
|
|
43
|
+
def splits(self) -> "TickerSplits":
|
|
44
|
+
return TickerSplits(http_client=self.http_client, symbol=self.symbol)
|
|
45
|
+
|
|
46
|
+
@property
|
|
47
|
+
def intraday(self) -> "TickerIntraday":
|
|
48
|
+
return TickerIntraday(http_client=self.http_client, symbol=self.symbol)
|
|
49
|
+
|
|
50
|
+
@property
|
|
51
|
+
def dividends(self) -> "TickerDividends":
|
|
52
|
+
return TickerDividends(http_client=self.http_client, symbol=self.symbol)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class TickerEOD:
|
|
56
|
+
def __init__(self, http_client: HTTPClient, symbol: str):
|
|
57
|
+
self.http_client = http_client
|
|
58
|
+
self.symbol = symbol
|
|
59
|
+
|
|
60
|
+
def list(
|
|
61
|
+
self,
|
|
62
|
+
**params: Unpack[TickerEODRequest],
|
|
63
|
+
) -> TickerEODResponse:
|
|
64
|
+
"""Obtain end-of-day data for a specific stock ticker by attaching /eod to your URL."""
|
|
65
|
+
return TickerEODResponse.model_validate(
|
|
66
|
+
self.http_client.get(f"/v2/tickers/{self.symbol}/eod", params=params)
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
def latest(
|
|
70
|
+
self,
|
|
71
|
+
**params: Unpack[TickerEODLatestRequest],
|
|
72
|
+
) -> EODBar:
|
|
73
|
+
"""Obtain eod data for the latest date by specifying stock ticker by attaching /eod/latest to your URL."""
|
|
74
|
+
return EODBar.model_validate(
|
|
75
|
+
self.http_client.get(f"/v2/tickers/{self.symbol}/eod/latest", params=params)
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
def for_a_date(
|
|
79
|
+
self,
|
|
80
|
+
date: str,
|
|
81
|
+
**params: Unpack[TickerEODRequest],
|
|
82
|
+
) -> EODBar:
|
|
83
|
+
"""Specify a date in YYYY-MM-DD format. You can also specify an exact time in ISO-8601 date format. For example, 2020-05-21T00:00:00+0000. Example, /eod/2020-01-01."""
|
|
84
|
+
return EODBar.model_validate(
|
|
85
|
+
self.http_client.get(f"/v2/tickers/{self.symbol}/eod/{date}", params=params)
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
class TickerSplits:
|
|
90
|
+
def __init__(self, http_client: HTTPClient, symbol: str):
|
|
91
|
+
self.http_client = http_client
|
|
92
|
+
self.symbol = symbol
|
|
93
|
+
|
|
94
|
+
def list(
|
|
95
|
+
self,
|
|
96
|
+
**params: Unpack[TickerSplitsRequest],
|
|
97
|
+
) -> TickerSplitsResponse:
|
|
98
|
+
"""Obtain ticker splits factor for a specific stock ticker by attaching /splits to your URL."""
|
|
99
|
+
return TickerSplitsResponse.model_validate(
|
|
100
|
+
self.http_client.get(f"/v2/tickers/{self.symbol}/splits", params=params)
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
class TickerIntraday:
|
|
105
|
+
def __init__(self, http_client: HTTPClient, symbol: str):
|
|
106
|
+
self.http_client = http_client
|
|
107
|
+
self.symbol = symbol
|
|
108
|
+
|
|
109
|
+
def list(
|
|
110
|
+
self,
|
|
111
|
+
**params: Unpack[TickerIntradayRequest],
|
|
112
|
+
) -> TickerIntradayResponse:
|
|
113
|
+
"""Obtain intraday data for a specific stock ticker by attaching /intraday to your URL."""
|
|
114
|
+
return TickerIntradayResponse.model_validate(
|
|
115
|
+
self.http_client.get(f"/v2/tickers/{self.symbol}/intraday", params=params)
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
def latest(
|
|
119
|
+
self,
|
|
120
|
+
**params: Unpack[TickerIntradayRequest],
|
|
121
|
+
) -> IntradayBar:
|
|
122
|
+
"""Obtain intraday data for the latest date by specifying stock ticker by attaching /intraday/latest to your URL."""
|
|
123
|
+
return IntradayBar.model_validate(
|
|
124
|
+
self.http_client.get(f"/v2/tickers/{self.symbol}/intraday/latest", params=params)
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
def for_a_date(
|
|
128
|
+
self,
|
|
129
|
+
date: str,
|
|
130
|
+
**params: Unpack[TickerIntradayRequest],
|
|
131
|
+
) -> IntradayResponse:
|
|
132
|
+
"""Specify a date in YYYY-MM-DD format or ISO-8601 date format."""
|
|
133
|
+
return IntradayResponse.model_validate(
|
|
134
|
+
self.http_client.get(f"/v2/tickers/{self.symbol}/intraday/{date}", params=params)
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
class TickerDividends:
|
|
139
|
+
def __init__(self, http_client: HTTPClient, symbol: str):
|
|
140
|
+
self.http_client = http_client
|
|
141
|
+
self.symbol = symbol
|
|
142
|
+
|
|
143
|
+
def list(
|
|
144
|
+
self,
|
|
145
|
+
**params: Unpack[TickerDividendsRequest],
|
|
146
|
+
) -> TickerDividendsResponse:
|
|
147
|
+
"""Obtain dividends for a specific stock ticker."""
|
|
148
|
+
return TickerDividendsResponse.model_validate(
|
|
149
|
+
self.http_client.get(f"/v2/tickers/{self.symbol}/dividends", params=params)
|
|
150
|
+
)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .tickerslist import TickersList
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from marketstack.client.http import HTTPClient
|
|
2
|
+
from typing import Unpack
|
|
3
|
+
from marketstack.models.ticker_info import TickersListResponse, TickersListRequest
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class TickersList:
|
|
7
|
+
def __init__(self, http_client: HTTPClient):
|
|
8
|
+
self.http_client = http_client
|
|
9
|
+
|
|
10
|
+
def list(self, **params: Unpack[TickersListRequest]) -> TickersListResponse:
|
|
11
|
+
"""List tickers."""
|
|
12
|
+
return TickersListResponse.model_validate(self.http_client.get("/v2/tickerslist", params=params))
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .timezones import Timezones
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from marketstack.client.http import HTTPClient
|
|
2
|
+
from typing import Unpack
|
|
3
|
+
from marketstack.models.timezone import TimezonesResponse, TimezonesRequest
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Timezones:
|
|
7
|
+
def __init__(self, http_client: HTTPClient):
|
|
8
|
+
self.http_client = http_client
|
|
9
|
+
|
|
10
|
+
def list(self, **params: Unpack[TimezonesRequest]) -> TimezonesResponse:
|
|
11
|
+
"""List supported timezones."""
|
|
12
|
+
return TimezonesResponse.model_validate(self.http_client.get("/v2/timezones", params=params))
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: marketstack-python-client
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: A Python client for the Marketstack API.
|
|
5
|
+
Requires-Python: >=3.10
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Requires-Dist: httpx>=0.28.1
|
|
9
|
+
Requires-Dist: pydantic>=2.13.4
|
|
10
|
+
Dynamic: license-file
|
|
11
|
+
|
|
12
|
+
# Marketstack Python Client
|
|
13
|
+
|
|
14
|
+
A modern, fully-typed Python client for the [Marketstack API (v2)](https://marketstack.com/). Built on top of `httpx` and `pydantic`, this client offers high performance, strict type validation, and an elegant fluent API interface.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Features
|
|
19
|
+
|
|
20
|
+
- **Modern Python Support:** Optimized for Python `>= 3.10`.
|
|
21
|
+
- **Fully Typed Requests & Responses:** Leverages Pydantic v2 and PEP 692 `Unpack` for complete autocomplete, editor hints, and runtime validation.
|
|
22
|
+
- **Fluent & Hierarchical API:** Easily access nested endpoints (e.g., `client.tickers("AAPL").eod.list()`).
|
|
23
|
+
- **Comprehensive Coverage:** Supports 25+ namespaces covering end-of-day (EOD) data, intraday, tickers, stock exchanges, stock splits, dividends, ETFs, indices, currencies, bonds, commodities, company fundamentals, and more.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Installation
|
|
28
|
+
|
|
29
|
+
Install the package via `pip`:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
pip install marketstack-python-client
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Or using `uv`:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
uv add marketstack-python-client
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Quick Start
|
|
44
|
+
|
|
45
|
+
To use the client, you will need a Marketstack API key. Get one by registering at [marketstack.com](https://marketstack.com/).
|
|
46
|
+
|
|
47
|
+
```python
|
|
48
|
+
import os
|
|
49
|
+
from marketstack import Marketstack
|
|
50
|
+
|
|
51
|
+
# Initialize the client with your access key
|
|
52
|
+
client = Marketstack(api_key=os.environ["MARKETSTACK_API_KEY"])
|
|
53
|
+
|
|
54
|
+
# 1. Fetch generic End-of-Day (EOD) stock data
|
|
55
|
+
eod_data = client.eod.list(symbols="AAPL,MSFT")
|
|
56
|
+
for bar in eod_data.data:
|
|
57
|
+
print(f"{bar.symbol} closed at {bar.close} on {bar.date}")
|
|
58
|
+
|
|
59
|
+
# 2. Access Ticker-specific data using the fluent API
|
|
60
|
+
aapl_ticker = client.tickers("AAPL").get()
|
|
61
|
+
print(f"Name: {aapl_ticker.name}, Stock Exchange: {aapl_ticker.stock_exchange.name}")
|
|
62
|
+
|
|
63
|
+
# Fetch EOD prices specifically for AAPL
|
|
64
|
+
aapl_eod = client.tickers("AAPL").eod.list(limit=10)
|
|
65
|
+
for bar in aapl_eod.data:
|
|
66
|
+
print(f"AAPL Close: {bar.close}")
|
|
67
|
+
|
|
68
|
+
# 3. Access Stock Exchange specific tickers and EOD data
|
|
69
|
+
nasdaq_eod = client.exchanges("XNAS").eod.list(symbols="AAPL", limit=5)
|
|
70
|
+
print(f"Fetched {len(nasdaq_eod.data)} records from NASDAQ")
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Client Namespaces & API Coverage
|
|
76
|
+
|
|
77
|
+
The `Marketstack` client provides dedicated namespaces mapping to the various endpoints of the Marketstack API.
|
|
78
|
+
|
|
79
|
+
### 1. Tickers (Fluent API)
|
|
80
|
+
Interact with a specific ticker symbol.
|
|
81
|
+
```python
|
|
82
|
+
ticker = client.tickers("AAPL")
|
|
83
|
+
|
|
84
|
+
ticker.get() # Basic ticker information
|
|
85
|
+
ticker.eod.list() # End-of-Day historical data
|
|
86
|
+
ticker.eod.latest() # Latest End-of-Day bar
|
|
87
|
+
ticker.eod.for_a_date("2023-10-27") # End-of-Day bar for a specific date
|
|
88
|
+
ticker.intraday.list() # Intraday / Real-time data
|
|
89
|
+
ticker.intraday.latest() # Latest intraday data
|
|
90
|
+
ticker.intraday.for_a_date("2023-10-27")
|
|
91
|
+
ticker.splits.list() # Split history
|
|
92
|
+
ticker.dividends.list() # Dividend history
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### 2. Stock Exchanges (Fluent API)
|
|
96
|
+
Interact with stock exchanges.
|
|
97
|
+
```python
|
|
98
|
+
exchange = client.exchanges("XNAS")
|
|
99
|
+
|
|
100
|
+
exchange.get() # Basic exchange info
|
|
101
|
+
exchange.tickers.list() # All tickers listed on this exchange
|
|
102
|
+
exchange.eod.list(symbols="AAPL") # EOD data for a ticker on this exchange
|
|
103
|
+
exchange.intraday.list(symbols="AAPL") # Intraday data for a ticker on this exchange
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### 3. End-of-Day (EOD) & Intraday Market Data
|
|
107
|
+
Retrieve general EOD and Intraday datasets.
|
|
108
|
+
```python
|
|
109
|
+
# General EOD endpoints
|
|
110
|
+
client.eod.list(symbols="AAPL", date_from="2023-01-01")
|
|
111
|
+
client.eod.latest(symbols="AAPL")
|
|
112
|
+
client.eod.for_a_date(date="2023-10-27", symbols="AAPL")
|
|
113
|
+
|
|
114
|
+
# General Intraday endpoints
|
|
115
|
+
client.intraday.list(symbols="AAPL")
|
|
116
|
+
client.intraday.latest(symbols="AAPL")
|
|
117
|
+
client.intraday.for_a_date(date="2023-10-27", symbols="AAPL")
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### 4. Other Specialized Namespaces
|
|
121
|
+
The client supports many other endpoints depending on your Marketstack subscription tier:
|
|
122
|
+
|
|
123
|
+
- **Dividends & Splits:**
|
|
124
|
+
- `client.dividends.list(symbols="AAPL")`
|
|
125
|
+
- `client.splits.list(symbols="AAPL")`
|
|
126
|
+
- **Currencies & Timezones:**
|
|
127
|
+
- `client.currencies.list()`
|
|
128
|
+
- `client.timezones.list()`
|
|
129
|
+
- **Bonds & Index Info:**
|
|
130
|
+
- `client.bondlist.list(country="US")`
|
|
131
|
+
- `client.bond.get(country="US")`
|
|
132
|
+
- `client.indexlist.list()`
|
|
133
|
+
- `client.indexinfo.get(index="SPX")`
|
|
134
|
+
- **ETFs:**
|
|
135
|
+
- `client.etflist.list(ticker="SPY")`
|
|
136
|
+
- `client.etfholdings.get(ticker="PRSVX")`
|
|
137
|
+
- **Company Fundamentals (Requires Enterprise/Tier Plan):**
|
|
138
|
+
- `client.company_facts.get(cik_code="0000320193")`
|
|
139
|
+
- `client.companyname.get(cik_code="0000320193")`
|
|
140
|
+
- `client.companyratings.get(ticker="AAPL")`
|
|
141
|
+
- `client.concept.get_accounts_payable(cik_code="0000320193")`
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## Development
|
|
146
|
+
|
|
147
|
+
We use `uv` for dependency management and workspace workflows.
|
|
148
|
+
|
|
149
|
+
### Prerequisites
|
|
150
|
+
|
|
151
|
+
- Python 3.10 or higher
|
|
152
|
+
- `uv` package manager
|
|
153
|
+
|
|
154
|
+
### Setup
|
|
155
|
+
|
|
156
|
+
Clone the repository and install the dependencies:
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
uv sync
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Running Tests
|
|
163
|
+
|
|
164
|
+
This project uses `pytest` for unit and integration testing.
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
# Run all unit tests
|
|
168
|
+
uv run pytest -v
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
To run the integration tests against the live Marketstack API, make sure to set the `MARKETSTACK_API_KEY` environment variable in your `.env` or current session. Note that some tests require higher-tier plans and are marked to be skipped if your API key lacks access.
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
export MARKETSTACK_API_KEY="your_api_key_here"
|
|
175
|
+
uv run pytest tests/test_integration.py
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## License
|
|
181
|
+
|
|
182
|
+
This project is licensed under the MIT License. See individual files or package settings for more details.
|