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.
Files changed (81) hide show
  1. marketstack/__init__.py +1 -0
  2. marketstack/client/__init__.py +0 -0
  3. marketstack/client/http.py +36 -0
  4. marketstack/client/marketstack.py +148 -0
  5. marketstack/models/__init__.py +0 -0
  6. marketstack/models/bond.py +47 -0
  7. marketstack/models/cik_code.py +26 -0
  8. marketstack/models/commodity.py +83 -0
  9. marketstack/models/company.py +278 -0
  10. marketstack/models/concept.py +65 -0
  11. marketstack/models/currency.py +23 -0
  12. marketstack/models/dividend.py +27 -0
  13. marketstack/models/eod.py +48 -0
  14. marketstack/models/etf.py +129 -0
  15. marketstack/models/exchange.py +117 -0
  16. marketstack/models/index.py +47 -0
  17. marketstack/models/intraday.py +43 -0
  18. marketstack/models/pagination.py +42 -0
  19. marketstack/models/split.py +24 -0
  20. marketstack/models/stockprice.py +31 -0
  21. marketstack/models/ticker.py +159 -0
  22. marketstack/models/ticker_info.py +197 -0
  23. marketstack/models/timezone.py +21 -0
  24. marketstack/namespaces/__init__.py +0 -0
  25. marketstack/namespaces/bond/__init__.py +1 -0
  26. marketstack/namespaces/bond/bond.py +12 -0
  27. marketstack/namespaces/bondlist/__init__.py +1 -0
  28. marketstack/namespaces/bondlist/bondlist.py +12 -0
  29. marketstack/namespaces/cikcode/__init__.py +1 -0
  30. marketstack/namespaces/cikcode/cikcode.py +12 -0
  31. marketstack/namespaces/commodities/__init__.py +1 -0
  32. marketstack/namespaces/commodities/commodities.py +12 -0
  33. marketstack/namespaces/commoditieshistory/__init__.py +1 -0
  34. marketstack/namespaces/commoditieshistory/commoditieshistory.py +12 -0
  35. marketstack/namespaces/company_facts/__init__.py +1 -0
  36. marketstack/namespaces/company_facts/company_facts.py +12 -0
  37. marketstack/namespaces/companyname/__init__.py +1 -0
  38. marketstack/namespaces/companyname/companyname.py +12 -0
  39. marketstack/namespaces/companyratings/__init__.py +1 -0
  40. marketstack/namespaces/companyratings/companyratings.py +12 -0
  41. marketstack/namespaces/concept/__init__.py +1 -0
  42. marketstack/namespaces/concept/concept.py +12 -0
  43. marketstack/namespaces/currencies/__init__.py +1 -0
  44. marketstack/namespaces/currencies/currencies.py +12 -0
  45. marketstack/namespaces/dividends/__init__.py +1 -0
  46. marketstack/namespaces/dividends/dividends.py +12 -0
  47. marketstack/namespaces/eod/__init__.py +1 -0
  48. marketstack/namespaces/eod/eod.py +20 -0
  49. marketstack/namespaces/etfholdings/__init__.py +1 -0
  50. marketstack/namespaces/etfholdings/etfholdings.py +12 -0
  51. marketstack/namespaces/etflist/__init__.py +1 -0
  52. marketstack/namespaces/etflist/etflist.py +12 -0
  53. marketstack/namespaces/exchanges/__init__.py +1 -0
  54. marketstack/namespaces/exchanges/exchanges.py +109 -0
  55. marketstack/namespaces/frames/__init__.py +1 -0
  56. marketstack/namespaces/frames/frames.py +12 -0
  57. marketstack/namespaces/indexinfo/__init__.py +1 -0
  58. marketstack/namespaces/indexinfo/indexinfo.py +12 -0
  59. marketstack/namespaces/indexlist/__init__.py +1 -0
  60. marketstack/namespaces/indexlist/indexlist.py +12 -0
  61. marketstack/namespaces/intraday/__init__.py +1 -0
  62. marketstack/namespaces/intraday/intraday.py +20 -0
  63. marketstack/namespaces/splits/__init__.py +1 -0
  64. marketstack/namespaces/splits/splits.py +12 -0
  65. marketstack/namespaces/stockprice/__init__.py +1 -0
  66. marketstack/namespaces/stockprice/stockprice.py +12 -0
  67. marketstack/namespaces/submissions/__init__.py +1 -0
  68. marketstack/namespaces/submissions/submissions.py +12 -0
  69. marketstack/namespaces/tickerinfo/__init__.py +1 -0
  70. marketstack/namespaces/tickerinfo/tickerinfo.py +12 -0
  71. marketstack/namespaces/tickers/__init__.py +1 -0
  72. marketstack/namespaces/tickers/tickers.py +150 -0
  73. marketstack/namespaces/tickerslist/__init__.py +1 -0
  74. marketstack/namespaces/tickerslist/tickerslist.py +12 -0
  75. marketstack/namespaces/timezones/__init__.py +1 -0
  76. marketstack/namespaces/timezones/timezones.py +12 -0
  77. marketstack_python_client-1.0.0.dist-info/METADATA +182 -0
  78. marketstack_python_client-1.0.0.dist-info/RECORD +81 -0
  79. marketstack_python_client-1.0.0.dist-info/WHEEL +5 -0
  80. marketstack_python_client-1.0.0.dist-info/licenses/LICENSE +21 -0
  81. 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.