marketstack-python-client 1.0.0__tar.gz

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 (89) hide show
  1. marketstack_python_client-1.0.0/LICENSE +21 -0
  2. marketstack_python_client-1.0.0/MANIFEST.in +4 -0
  3. marketstack_python_client-1.0.0/PKG-INFO +182 -0
  4. marketstack_python_client-1.0.0/README.md +171 -0
  5. marketstack_python_client-1.0.0/marketstack/__init__.py +1 -0
  6. marketstack_python_client-1.0.0/marketstack/client/__init__.py +0 -0
  7. marketstack_python_client-1.0.0/marketstack/client/http.py +36 -0
  8. marketstack_python_client-1.0.0/marketstack/client/marketstack.py +148 -0
  9. marketstack_python_client-1.0.0/marketstack/models/__init__.py +0 -0
  10. marketstack_python_client-1.0.0/marketstack/models/bond.py +47 -0
  11. marketstack_python_client-1.0.0/marketstack/models/cik_code.py +26 -0
  12. marketstack_python_client-1.0.0/marketstack/models/commodity.py +83 -0
  13. marketstack_python_client-1.0.0/marketstack/models/company.py +278 -0
  14. marketstack_python_client-1.0.0/marketstack/models/concept.py +65 -0
  15. marketstack_python_client-1.0.0/marketstack/models/currency.py +23 -0
  16. marketstack_python_client-1.0.0/marketstack/models/dividend.py +27 -0
  17. marketstack_python_client-1.0.0/marketstack/models/eod.py +48 -0
  18. marketstack_python_client-1.0.0/marketstack/models/etf.py +129 -0
  19. marketstack_python_client-1.0.0/marketstack/models/exchange.py +117 -0
  20. marketstack_python_client-1.0.0/marketstack/models/index.py +47 -0
  21. marketstack_python_client-1.0.0/marketstack/models/intraday.py +43 -0
  22. marketstack_python_client-1.0.0/marketstack/models/pagination.py +42 -0
  23. marketstack_python_client-1.0.0/marketstack/models/split.py +24 -0
  24. marketstack_python_client-1.0.0/marketstack/models/stockprice.py +31 -0
  25. marketstack_python_client-1.0.0/marketstack/models/ticker.py +159 -0
  26. marketstack_python_client-1.0.0/marketstack/models/ticker_info.py +197 -0
  27. marketstack_python_client-1.0.0/marketstack/models/timezone.py +21 -0
  28. marketstack_python_client-1.0.0/marketstack/namespaces/__init__.py +0 -0
  29. marketstack_python_client-1.0.0/marketstack/namespaces/bond/__init__.py +1 -0
  30. marketstack_python_client-1.0.0/marketstack/namespaces/bond/bond.py +12 -0
  31. marketstack_python_client-1.0.0/marketstack/namespaces/bondlist/__init__.py +1 -0
  32. marketstack_python_client-1.0.0/marketstack/namespaces/bondlist/bondlist.py +12 -0
  33. marketstack_python_client-1.0.0/marketstack/namespaces/cikcode/__init__.py +1 -0
  34. marketstack_python_client-1.0.0/marketstack/namespaces/cikcode/cikcode.py +12 -0
  35. marketstack_python_client-1.0.0/marketstack/namespaces/commodities/__init__.py +1 -0
  36. marketstack_python_client-1.0.0/marketstack/namespaces/commodities/commodities.py +12 -0
  37. marketstack_python_client-1.0.0/marketstack/namespaces/commoditieshistory/__init__.py +1 -0
  38. marketstack_python_client-1.0.0/marketstack/namespaces/commoditieshistory/commoditieshistory.py +12 -0
  39. marketstack_python_client-1.0.0/marketstack/namespaces/company_facts/__init__.py +1 -0
  40. marketstack_python_client-1.0.0/marketstack/namespaces/company_facts/company_facts.py +12 -0
  41. marketstack_python_client-1.0.0/marketstack/namespaces/companyname/__init__.py +1 -0
  42. marketstack_python_client-1.0.0/marketstack/namespaces/companyname/companyname.py +12 -0
  43. marketstack_python_client-1.0.0/marketstack/namespaces/companyratings/__init__.py +1 -0
  44. marketstack_python_client-1.0.0/marketstack/namespaces/companyratings/companyratings.py +12 -0
  45. marketstack_python_client-1.0.0/marketstack/namespaces/concept/__init__.py +1 -0
  46. marketstack_python_client-1.0.0/marketstack/namespaces/concept/concept.py +12 -0
  47. marketstack_python_client-1.0.0/marketstack/namespaces/currencies/__init__.py +1 -0
  48. marketstack_python_client-1.0.0/marketstack/namespaces/currencies/currencies.py +12 -0
  49. marketstack_python_client-1.0.0/marketstack/namespaces/dividends/__init__.py +1 -0
  50. marketstack_python_client-1.0.0/marketstack/namespaces/dividends/dividends.py +12 -0
  51. marketstack_python_client-1.0.0/marketstack/namespaces/eod/__init__.py +1 -0
  52. marketstack_python_client-1.0.0/marketstack/namespaces/eod/eod.py +20 -0
  53. marketstack_python_client-1.0.0/marketstack/namespaces/etfholdings/__init__.py +1 -0
  54. marketstack_python_client-1.0.0/marketstack/namespaces/etfholdings/etfholdings.py +12 -0
  55. marketstack_python_client-1.0.0/marketstack/namespaces/etflist/__init__.py +1 -0
  56. marketstack_python_client-1.0.0/marketstack/namespaces/etflist/etflist.py +12 -0
  57. marketstack_python_client-1.0.0/marketstack/namespaces/exchanges/__init__.py +1 -0
  58. marketstack_python_client-1.0.0/marketstack/namespaces/exchanges/exchanges.py +109 -0
  59. marketstack_python_client-1.0.0/marketstack/namespaces/frames/__init__.py +1 -0
  60. marketstack_python_client-1.0.0/marketstack/namespaces/frames/frames.py +12 -0
  61. marketstack_python_client-1.0.0/marketstack/namespaces/indexinfo/__init__.py +1 -0
  62. marketstack_python_client-1.0.0/marketstack/namespaces/indexinfo/indexinfo.py +12 -0
  63. marketstack_python_client-1.0.0/marketstack/namespaces/indexlist/__init__.py +1 -0
  64. marketstack_python_client-1.0.0/marketstack/namespaces/indexlist/indexlist.py +12 -0
  65. marketstack_python_client-1.0.0/marketstack/namespaces/intraday/__init__.py +1 -0
  66. marketstack_python_client-1.0.0/marketstack/namespaces/intraday/intraday.py +20 -0
  67. marketstack_python_client-1.0.0/marketstack/namespaces/splits/__init__.py +1 -0
  68. marketstack_python_client-1.0.0/marketstack/namespaces/splits/splits.py +12 -0
  69. marketstack_python_client-1.0.0/marketstack/namespaces/stockprice/__init__.py +1 -0
  70. marketstack_python_client-1.0.0/marketstack/namespaces/stockprice/stockprice.py +12 -0
  71. marketstack_python_client-1.0.0/marketstack/namespaces/submissions/__init__.py +1 -0
  72. marketstack_python_client-1.0.0/marketstack/namespaces/submissions/submissions.py +12 -0
  73. marketstack_python_client-1.0.0/marketstack/namespaces/tickerinfo/__init__.py +1 -0
  74. marketstack_python_client-1.0.0/marketstack/namespaces/tickerinfo/tickerinfo.py +12 -0
  75. marketstack_python_client-1.0.0/marketstack/namespaces/tickers/__init__.py +1 -0
  76. marketstack_python_client-1.0.0/marketstack/namespaces/tickers/tickers.py +150 -0
  77. marketstack_python_client-1.0.0/marketstack/namespaces/tickerslist/__init__.py +1 -0
  78. marketstack_python_client-1.0.0/marketstack/namespaces/tickerslist/tickerslist.py +12 -0
  79. marketstack_python_client-1.0.0/marketstack/namespaces/timezones/__init__.py +1 -0
  80. marketstack_python_client-1.0.0/marketstack/namespaces/timezones/timezones.py +12 -0
  81. marketstack_python_client-1.0.0/marketstack_python_client.egg-info/PKG-INFO +182 -0
  82. marketstack_python_client-1.0.0/marketstack_python_client.egg-info/SOURCES.txt +87 -0
  83. marketstack_python_client-1.0.0/marketstack_python_client.egg-info/dependency_links.txt +1 -0
  84. marketstack_python_client-1.0.0/marketstack_python_client.egg-info/requires.txt +2 -0
  85. marketstack_python_client-1.0.0/marketstack_python_client.egg-info/top_level.txt +1 -0
  86. marketstack_python_client-1.0.0/openapi.yaml +5669 -0
  87. marketstack_python_client-1.0.0/pyproject.toml +35 -0
  88. marketstack_python_client-1.0.0/setup.cfg +4 -0
  89. marketstack_python_client-1.0.0/tests/test_integration.py +213 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 01Joseph-Hwang10
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,4 @@
1
+ include README.md
2
+ include LICENSE
3
+ include openapi.yaml
4
+ recursive-include marketstack *.py
@@ -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.
@@ -0,0 +1,171 @@
1
+ # Marketstack Python Client
2
+
3
+ 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.
4
+
5
+ ---
6
+
7
+ ## Features
8
+
9
+ - **Modern Python Support:** Optimized for Python `>= 3.10`.
10
+ - **Fully Typed Requests & Responses:** Leverages Pydantic v2 and PEP 692 `Unpack` for complete autocomplete, editor hints, and runtime validation.
11
+ - **Fluent & Hierarchical API:** Easily access nested endpoints (e.g., `client.tickers("AAPL").eod.list()`).
12
+ - **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.
13
+
14
+ ---
15
+
16
+ ## Installation
17
+
18
+ Install the package via `pip`:
19
+
20
+ ```bash
21
+ pip install marketstack-python-client
22
+ ```
23
+
24
+ Or using `uv`:
25
+
26
+ ```bash
27
+ uv add marketstack-python-client
28
+ ```
29
+
30
+ ---
31
+
32
+ ## Quick Start
33
+
34
+ To use the client, you will need a Marketstack API key. Get one by registering at [marketstack.com](https://marketstack.com/).
35
+
36
+ ```python
37
+ import os
38
+ from marketstack import Marketstack
39
+
40
+ # Initialize the client with your access key
41
+ client = Marketstack(api_key=os.environ["MARKETSTACK_API_KEY"])
42
+
43
+ # 1. Fetch generic End-of-Day (EOD) stock data
44
+ eod_data = client.eod.list(symbols="AAPL,MSFT")
45
+ for bar in eod_data.data:
46
+ print(f"{bar.symbol} closed at {bar.close} on {bar.date}")
47
+
48
+ # 2. Access Ticker-specific data using the fluent API
49
+ aapl_ticker = client.tickers("AAPL").get()
50
+ print(f"Name: {aapl_ticker.name}, Stock Exchange: {aapl_ticker.stock_exchange.name}")
51
+
52
+ # Fetch EOD prices specifically for AAPL
53
+ aapl_eod = client.tickers("AAPL").eod.list(limit=10)
54
+ for bar in aapl_eod.data:
55
+ print(f"AAPL Close: {bar.close}")
56
+
57
+ # 3. Access Stock Exchange specific tickers and EOD data
58
+ nasdaq_eod = client.exchanges("XNAS").eod.list(symbols="AAPL", limit=5)
59
+ print(f"Fetched {len(nasdaq_eod.data)} records from NASDAQ")
60
+ ```
61
+
62
+ ---
63
+
64
+ ## Client Namespaces & API Coverage
65
+
66
+ The `Marketstack` client provides dedicated namespaces mapping to the various endpoints of the Marketstack API.
67
+
68
+ ### 1. Tickers (Fluent API)
69
+ Interact with a specific ticker symbol.
70
+ ```python
71
+ ticker = client.tickers("AAPL")
72
+
73
+ ticker.get() # Basic ticker information
74
+ ticker.eod.list() # End-of-Day historical data
75
+ ticker.eod.latest() # Latest End-of-Day bar
76
+ ticker.eod.for_a_date("2023-10-27") # End-of-Day bar for a specific date
77
+ ticker.intraday.list() # Intraday / Real-time data
78
+ ticker.intraday.latest() # Latest intraday data
79
+ ticker.intraday.for_a_date("2023-10-27")
80
+ ticker.splits.list() # Split history
81
+ ticker.dividends.list() # Dividend history
82
+ ```
83
+
84
+ ### 2. Stock Exchanges (Fluent API)
85
+ Interact with stock exchanges.
86
+ ```python
87
+ exchange = client.exchanges("XNAS")
88
+
89
+ exchange.get() # Basic exchange info
90
+ exchange.tickers.list() # All tickers listed on this exchange
91
+ exchange.eod.list(symbols="AAPL") # EOD data for a ticker on this exchange
92
+ exchange.intraday.list(symbols="AAPL") # Intraday data for a ticker on this exchange
93
+ ```
94
+
95
+ ### 3. End-of-Day (EOD) & Intraday Market Data
96
+ Retrieve general EOD and Intraday datasets.
97
+ ```python
98
+ # General EOD endpoints
99
+ client.eod.list(symbols="AAPL", date_from="2023-01-01")
100
+ client.eod.latest(symbols="AAPL")
101
+ client.eod.for_a_date(date="2023-10-27", symbols="AAPL")
102
+
103
+ # General Intraday endpoints
104
+ client.intraday.list(symbols="AAPL")
105
+ client.intraday.latest(symbols="AAPL")
106
+ client.intraday.for_a_date(date="2023-10-27", symbols="AAPL")
107
+ ```
108
+
109
+ ### 4. Other Specialized Namespaces
110
+ The client supports many other endpoints depending on your Marketstack subscription tier:
111
+
112
+ - **Dividends & Splits:**
113
+ - `client.dividends.list(symbols="AAPL")`
114
+ - `client.splits.list(symbols="AAPL")`
115
+ - **Currencies & Timezones:**
116
+ - `client.currencies.list()`
117
+ - `client.timezones.list()`
118
+ - **Bonds & Index Info:**
119
+ - `client.bondlist.list(country="US")`
120
+ - `client.bond.get(country="US")`
121
+ - `client.indexlist.list()`
122
+ - `client.indexinfo.get(index="SPX")`
123
+ - **ETFs:**
124
+ - `client.etflist.list(ticker="SPY")`
125
+ - `client.etfholdings.get(ticker="PRSVX")`
126
+ - **Company Fundamentals (Requires Enterprise/Tier Plan):**
127
+ - `client.company_facts.get(cik_code="0000320193")`
128
+ - `client.companyname.get(cik_code="0000320193")`
129
+ - `client.companyratings.get(ticker="AAPL")`
130
+ - `client.concept.get_accounts_payable(cik_code="0000320193")`
131
+
132
+ ---
133
+
134
+ ## Development
135
+
136
+ We use `uv` for dependency management and workspace workflows.
137
+
138
+ ### Prerequisites
139
+
140
+ - Python 3.10 or higher
141
+ - `uv` package manager
142
+
143
+ ### Setup
144
+
145
+ Clone the repository and install the dependencies:
146
+
147
+ ```bash
148
+ uv sync
149
+ ```
150
+
151
+ ### Running Tests
152
+
153
+ This project uses `pytest` for unit and integration testing.
154
+
155
+ ```bash
156
+ # Run all unit tests
157
+ uv run pytest -v
158
+ ```
159
+
160
+ 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.
161
+
162
+ ```bash
163
+ export MARKETSTACK_API_KEY="your_api_key_here"
164
+ uv run pytest tests/test_integration.py
165
+ ```
166
+
167
+ ---
168
+
169
+ ## License
170
+
171
+ This project is licensed under the MIT License. See individual files or package settings for more details.
@@ -0,0 +1 @@
1
+ from .client.marketstack import Marketstack
@@ -0,0 +1,36 @@
1
+ import httpx
2
+
3
+
4
+ class HTTPClient:
5
+ def __init__(self, base_url: str, params: dict = None):
6
+ self.base_url = base_url
7
+ self.params = params or {}
8
+
9
+ def get(self, endpoint: str, params: dict = None):
10
+ merged_params = {**self.params}
11
+ if params:
12
+ cleaned_params = {k: v for k, v in params.items() if v is not None}
13
+ merged_params.update(cleaned_params)
14
+ with httpx.Client(base_url=self.base_url, timeout=30.0) as client:
15
+ response = client.get(endpoint, params=merged_params)
16
+ response.raise_for_status()
17
+ data = response.json()
18
+ if isinstance(data, dict):
19
+ if "error" in data:
20
+ err = data["error"]
21
+ err_msg = err.get("message", "Unknown error") if isinstance(err, dict) else str(err)
22
+ err_code = err.get("code", "unknown") if isinstance(err, dict) else "unknown"
23
+ raise httpx.HTTPStatusError(
24
+ message=f"API Error ({err_code}): {err_msg}",
25
+ request=response.request,
26
+ response=response,
27
+ )
28
+ if data.get("message") == "error":
29
+ err_msg = data.get("details", "Unknown error")
30
+ err_code = data.get("code", "unknown")
31
+ raise httpx.HTTPStatusError(
32
+ message=f"API Error ({err_code}): {err_msg}",
33
+ request=response.request,
34
+ response=response,
35
+ )
36
+ return data
@@ -0,0 +1,148 @@
1
+ from marketstack.client.http import HTTPClient
2
+ from marketstack.namespaces.bond import Bond
3
+ from marketstack.namespaces.bondlist import BondList
4
+ from marketstack.namespaces.cikcode import CIKCode
5
+ from marketstack.namespaces.commodities import Commodities
6
+ from marketstack.namespaces.commoditieshistory import CommoditiesHistory
7
+ from marketstack.namespaces.company_facts import CompanyFacts
8
+ from marketstack.namespaces.companyname import CompanyName
9
+ from marketstack.namespaces.companyratings import CompanyRatings
10
+ from marketstack.namespaces.concept import Concept
11
+ from marketstack.namespaces.currencies import Currencies
12
+ from marketstack.namespaces.dividends import Dividends
13
+ from marketstack.namespaces.eod import EOD
14
+ from marketstack.namespaces.etfholdings import ETFHoldings
15
+ from marketstack.namespaces.etflist import ETFList
16
+ from marketstack.namespaces.exchanges import Exchanges
17
+ from marketstack.namespaces.frames import Frames
18
+ from marketstack.namespaces.indexinfo import IndexInfo
19
+ from marketstack.namespaces.indexlist import IndexList
20
+ from marketstack.namespaces.intraday import Intraday
21
+ from marketstack.namespaces.splits import Splits
22
+ from marketstack.namespaces.stockprice import StockPrice
23
+ from marketstack.namespaces.submissions import Submissions
24
+ from marketstack.namespaces.tickerinfo import TickerInfo
25
+ from marketstack.namespaces.tickers import Tickers
26
+ from marketstack.namespaces.tickerslist import TickersList
27
+ from marketstack.namespaces.timezones import Timezones
28
+
29
+
30
+ class Marketstack:
31
+ """
32
+ The marketstack API was built to deliver worldwide stock market data
33
+ (real-time, intraday and historical), together with information on stock
34
+ exchanges, tickers, indices, ETFs, bonds, commodities and company
35
+ fundamentals, in a simple, lightweight JSON format. Requests to the REST API
36
+ are made using a straightforward HTTP GET URL structure. This documentation
37
+ covers the v2 API surface.
38
+ """
39
+
40
+ def __init__(self, api_key: str):
41
+ self.http_client = HTTPClient(
42
+ base_url="https://api.marketstack.com",
43
+ params={"access_key": api_key},
44
+ )
45
+
46
+ @property
47
+ def bond(self) -> Bond:
48
+ return Bond(http_client=self.http_client)
49
+
50
+ @property
51
+ def bondlist(self) -> BondList:
52
+ return BondList(http_client=self.http_client)
53
+
54
+ @property
55
+ def cikcode(self) -> CIKCode:
56
+ return CIKCode(http_client=self.http_client)
57
+
58
+ @property
59
+ def commodities(self) -> Commodities:
60
+ return Commodities(http_client=self.http_client)
61
+
62
+ @property
63
+ def commoditieshistory(self) -> CommoditiesHistory:
64
+ return CommoditiesHistory(http_client=self.http_client)
65
+
66
+ @property
67
+ def company_facts(self) -> CompanyFacts:
68
+ return CompanyFacts(http_client=self.http_client)
69
+
70
+ @property
71
+ def companyname(self) -> CompanyName:
72
+ return CompanyName(http_client=self.http_client)
73
+
74
+ @property
75
+ def companyratings(self) -> CompanyRatings:
76
+ return CompanyRatings(http_client=self.http_client)
77
+
78
+ @property
79
+ def concept(self) -> Concept:
80
+ return Concept(http_client=self.http_client)
81
+
82
+ @property
83
+ def currencies(self) -> Currencies:
84
+ return Currencies(http_client=self.http_client)
85
+
86
+ @property
87
+ def dividends(self) -> Dividends:
88
+ return Dividends(http_client=self.http_client)
89
+
90
+ @property
91
+ def eod(self) -> EOD:
92
+ return EOD(http_client=self.http_client)
93
+
94
+ @property
95
+ def etfholdings(self) -> ETFHoldings:
96
+ return ETFHoldings(http_client=self.http_client)
97
+
98
+ @property
99
+ def etflist(self) -> ETFList:
100
+ return ETFList(http_client=self.http_client)
101
+
102
+ @property
103
+ def exchanges(self) -> Exchanges:
104
+ return Exchanges(http_client=self.http_client)
105
+
106
+ @property
107
+ def frames(self) -> Frames:
108
+ return Frames(http_client=self.http_client)
109
+
110
+ @property
111
+ def indexinfo(self) -> IndexInfo:
112
+ return IndexInfo(http_client=self.http_client)
113
+
114
+ @property
115
+ def indexlist(self) -> IndexList:
116
+ return IndexList(http_client=self.http_client)
117
+
118
+ @property
119
+ def intraday(self) -> Intraday:
120
+ return Intraday(http_client=self.http_client)
121
+
122
+ @property
123
+ def splits(self) -> Splits:
124
+ return Splits(http_client=self.http_client)
125
+
126
+ @property
127
+ def stockprice(self) -> StockPrice:
128
+ return StockPrice(http_client=self.http_client)
129
+
130
+ @property
131
+ def submissions(self) -> Submissions:
132
+ return Submissions(http_client=self.http_client)
133
+
134
+ @property
135
+ def tickerinfo(self) -> TickerInfo:
136
+ return TickerInfo(http_client=self.http_client)
137
+
138
+ @property
139
+ def tickers(self) -> Tickers:
140
+ return Tickers(http_client=self.http_client)
141
+
142
+ @property
143
+ def tickerslist(self) -> TickersList:
144
+ return TickersList(http_client=self.http_client)
145
+
146
+ @property
147
+ def timezones(self) -> Timezones:
148
+ return Timezones(http_client=self.http_client)
@@ -0,0 +1,47 @@
1
+ from pydantic import BaseModel, Field
2
+ from typing import Union
3
+ from types import NoneType
4
+ from .pagination import Pagniation, PaginationRequest
5
+ from typing import TypedDict
6
+
7
+
8
+ class BondRequest(TypedDict, total=False):
9
+ country: Union[NoneType, str] = None
10
+ """Filter bonds by country."""
11
+
12
+ class BondListRequest(PaginationRequest, total=False):
13
+ country: Union[NoneType, str] = None
14
+ """Filter bond list by country."""
15
+
16
+ class BondInfoItem(BaseModel):
17
+ region: str
18
+ """Region where the bond is supported."""
19
+ country: str
20
+ """Country where the bond is supported."""
21
+ type: str
22
+ """Bond tenor/type (for example 10Y)."""
23
+ yield_: str = Field(..., alias="yield")
24
+ """Current bond yield."""
25
+ price_change_day: str
26
+ """Price change day-over-day."""
27
+ percentage_week: str
28
+ """Weekly change percentage."""
29
+ percentage_month: str
30
+ """Monthly change percentage."""
31
+ percentage_year: str
32
+ """Yearly change percentage."""
33
+ date: str
34
+ """Quote date."""
35
+ model_config = {"populate_by_name": True}
36
+
37
+ class BondInfoResponse(BaseModel):
38
+ pagination: Pagniation
39
+ data: list["BondInfoItem"]
40
+
41
+ class BondListItem(BaseModel):
42
+ country: str
43
+ """Country supported for bonds."""
44
+
45
+ class BondListResponse(BaseModel):
46
+ pagination: Pagniation
47
+ data: list["BondListItem"]
@@ -0,0 +1,26 @@
1
+ from pydantic import BaseModel
2
+ from typing import Union
3
+ from types import NoneType
4
+ from .pagination import Pagniation, PaginationRequest
5
+ from typing import TypedDict
6
+
7
+
8
+ class CIKCodeRequest(PaginationRequest, total=False):
9
+ company_name: Union[NoneType, str] = None
10
+ """Search by company name."""
11
+
12
+ class CIKItem(BaseModel):
13
+ cik_code: str
14
+ """Company CIK code."""
15
+ company_name: str
16
+ """Company name."""
17
+ ein: str
18
+ """Employer Identification Number."""
19
+ sic: str
20
+ """Standard Industrial Classification."""
21
+ sic_description: str
22
+ """SIC description."""
23
+
24
+ class CIKSearchResponse(BaseModel):
25
+ pagination: Pagniation
26
+ data: list["CIKItem"]