dunkapi 0.1.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.
@@ -0,0 +1,6 @@
1
+ __pycache__/
2
+ *.egg-info/
3
+ .pytest_cache/
4
+ .venv/
5
+ dist/
6
+ build/
dunkapi-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 DunkAPI
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.
dunkapi-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,204 @@
1
+ Metadata-Version: 2.5
2
+ Name: dunkapi
3
+ Version: 0.1.0
4
+ Summary: Python client for the DunkAPI NBA data API. No dependencies.
5
+ Project-URL: Homepage, https://dunkapi.com
6
+ Project-URL: Documentation, https://dunkapi.com/docs
7
+ Project-URL: Repository, https://github.com/noahowsh/puckapi
8
+ Project-URL: Sign up, https://dunkapi.com/signup
9
+ Author-email: DunkAPI <support@dunkapi.com>
10
+ License-Expression: MIT
11
+ License-File: LICENSE
12
+ Keywords: api-client,betting,dunkapi,nba,odds,player-props,sports-data
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
23
+ Classifier: Typing :: Typed
24
+ Requires-Python: >=3.9
25
+ Provides-Extra: pandas
26
+ Requires-Dist: pandas>=1.5; extra == 'pandas'
27
+ Provides-Extra: test
28
+ Requires-Dist: pytest>=7; extra == 'test'
29
+ Description-Content-Type: text/markdown
30
+
31
+ # DunkAPI for Python
32
+
33
+ Python client for the [DunkAPI](https://dunkapi.com) NBA data API. It has no required dependencies (standard library only) and works on Python 3.9 and newer. Pandas is optional.
34
+
35
+ ## Install
36
+
37
+ ```bash
38
+ pip install dunkapi
39
+ pip install "dunkapi[pandas]" # only if you want DataFrames
40
+ ```
41
+
42
+ ## Set your key
43
+
44
+ Get a free key at https://dunkapi.com/signup. Free accounts get 500 credits a month.
45
+
46
+ ```bash
47
+ export DUNKAPI_API_KEY=your_key_here
48
+ ```
49
+
50
+ ```python
51
+ from dunkapi import Client
52
+
53
+ client = Client() # reads DUNKAPI_API_KEY
54
+ client = Client(api_key="your_key") # or pass it in
55
+ ```
56
+
57
+ ## Examples
58
+
59
+ ### 1. Player props for one game
60
+
61
+ `get_player_props` returns every player's line for one market, by sportsbook.
62
+
63
+ ```python
64
+ from dunkapi import Client, to_dataframe
65
+
66
+ client = Client()
67
+
68
+ props = client.get_player_props(
69
+ game_id="401810726",
70
+ market="player_points",
71
+ bookmaker="draftkings",
72
+ )
73
+ df = to_dataframe(props, key="props")
74
+ print(df[["player_name", "line", "over_odds", "under_odds"]].head(10))
75
+ ```
76
+
77
+ ### 2. One player's prop history
78
+
79
+ `get_prop_history` shows how a player's line for a market moved across games. Search for the player id first.
80
+
81
+ ```python
82
+ from dunkapi import Client, to_dataframe
83
+
84
+ client = Client()
85
+
86
+ jokic = client.search_players("Jokic", limit=1)["players"][0]
87
+ history = client.get_prop_history(
88
+ jokic["player_id"],
89
+ "player_points",
90
+ from_date="2026-03-01",
91
+ to_date="2026-03-08",
92
+ bookmaker="draftkings",
93
+ limit=10,
94
+ )
95
+ print(to_dataframe(history).head())
96
+ ```
97
+
98
+ ### 3. Games on a date, and scoring leaders
99
+
100
+ `list_games` needs a filter such as `date`, `season` or `team`.
101
+
102
+ ```python
103
+ from dunkapi import Client
104
+
105
+ client = Client()
106
+
107
+ games = client.list_games(date="2026-03-15", limit=3)["games"]
108
+ for g in games:
109
+ print(g["away"]["abbrev"], g["away"]["score"], "at", g["home"]["abbrev"], g["home"]["score"])
110
+
111
+ leaders = client.get_leaders("pts", limit=5)
112
+ for row in leaders["leaders"]:
113
+ print(row["name"], row["team"], row["value"])
114
+ ```
115
+
116
+ ## Credits
117
+
118
+ Every method returns the `data` object from the response. After each call, `client.last_credits_used` and `client.last_credits_remaining` hold the counters from the `X-Credits-Used` and `X-Credits-Remaining` headers. Methods that take `estimate_only=True` return the price of a call without running or charging it.
119
+
120
+ ## Pandas
121
+
122
+ ```python
123
+ from dunkapi import to_dataframe
124
+
125
+ df = to_dataframe(data) # finds the main list in the response
126
+ df = to_dataframe(data, key="rows") # or name the list yourself
127
+ ```
128
+
129
+ Nested fields become dotted columns. Install pandas separately or with `pip install "dunkapi[pandas]"`.
130
+
131
+ ## Errors
132
+
133
+ Every error is an `APIError` subclass, with the server's message and the HTTP status.
134
+
135
+ | Exception | Status | Meaning |
136
+ | --- | --- | --- |
137
+ | `AuthError` | 401 | Missing, invalid or revoked key |
138
+ | `InsufficientCreditsError` | 402 | Not enough credits for the call |
139
+ | `NotFoundError` | 404 | The id or name does not exist |
140
+ | `RateLimitError` | 429 | Too many requests; has `.retry_after` when the server sends it |
141
+ | `APIError` | 400, 5xx | Bad arguments or a server problem |
142
+ | `APIConnectionError` | none | No response (network or timeout) |
143
+
144
+ ```python
145
+ from dunkapi import Client, APIError, InsufficientCreditsError, RateLimitError
146
+
147
+ client = Client()
148
+ try:
149
+ data = client.list_teams()
150
+ except InsufficientCreditsError:
151
+ print("Out of credits, top up at https://dunkapi.com")
152
+ except RateLimitError as exc:
153
+ print("Slow down, retry after", exc.retry_after)
154
+ except APIError as exc:
155
+ print(exc.status_code, exc.message)
156
+ ```
157
+
158
+ The client retries 429 and 5xx responses and connection failures up to 3 times with backoff, and honors `Retry-After`. Set `Client(max_retries=0)` to turn that off.
159
+
160
+ If you see `CERTIFICATE_VERIFY_FAILED` on a python.org install for macOS, run the "Install Certificates.command" script that came with Python, or `pip install certifi` (the client uses it when present).
161
+
162
+ ## Options
163
+
164
+ ```python
165
+ Client(
166
+ api_key=None, # defaults to $DUNKAPI_API_KEY
167
+ base_url="https://mcp.dunkapi.com", # point at another host
168
+ timeout=60.0, # seconds per request
169
+ max_retries=3,
170
+ )
171
+ ```
172
+
173
+ `client.call("tool_name", {"arg": "value"})` calls any tool by name, which helps when the API adds a tool before this package does.
174
+
175
+ ## Tools
176
+
177
+ Method names match the API tool names. Arguments are keyword arguments; required ones can also be passed positionally. Each method's docstring lists its arguments (`help(client.list_teams)`).
178
+
179
+ | Method | Credits | What it does |
180
+ | --- | --- | --- |
181
+ | `list_teams` | 1 | List teams |
182
+ | `list_games` | 2 | List games |
183
+ | `get_schedule` | 2 | Schedule |
184
+ | `get_game` | 5 | Game |
185
+ | `get_standings` | 2 | Standings |
186
+ | `get_injuries` | 2 | Injuries |
187
+ | `search_players` | 1 | Search players |
188
+ | `get_player` | 5 | Player |
189
+ | `get_player_games` | 5 | Player games |
190
+ | `get_leaders` | 5 | Leaders |
191
+ | `get_team_stats` | 5 | Team stats |
192
+ | `get_plays` | 10 | Plays |
193
+ | `get_shot_chart` | 10 | Shot chart |
194
+ | `get_odds` | 5 | Odds |
195
+ | `get_line_movement` | 10 | Line movement |
196
+ | `get_ratings` | 2 | Ratings |
197
+ | `get_player_props` | 10 | Player props |
198
+ | `get_prop_history` | 10 | Prop history |
199
+
200
+ Full API reference: https://dunkapi.com/docs
201
+
202
+ ## License
203
+
204
+ MIT
@@ -0,0 +1,174 @@
1
+ # DunkAPI for Python
2
+
3
+ Python client for the [DunkAPI](https://dunkapi.com) NBA data API. It has no required dependencies (standard library only) and works on Python 3.9 and newer. Pandas is optional.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ pip install dunkapi
9
+ pip install "dunkapi[pandas]" # only if you want DataFrames
10
+ ```
11
+
12
+ ## Set your key
13
+
14
+ Get a free key at https://dunkapi.com/signup. Free accounts get 500 credits a month.
15
+
16
+ ```bash
17
+ export DUNKAPI_API_KEY=your_key_here
18
+ ```
19
+
20
+ ```python
21
+ from dunkapi import Client
22
+
23
+ client = Client() # reads DUNKAPI_API_KEY
24
+ client = Client(api_key="your_key") # or pass it in
25
+ ```
26
+
27
+ ## Examples
28
+
29
+ ### 1. Player props for one game
30
+
31
+ `get_player_props` returns every player's line for one market, by sportsbook.
32
+
33
+ ```python
34
+ from dunkapi import Client, to_dataframe
35
+
36
+ client = Client()
37
+
38
+ props = client.get_player_props(
39
+ game_id="401810726",
40
+ market="player_points",
41
+ bookmaker="draftkings",
42
+ )
43
+ df = to_dataframe(props, key="props")
44
+ print(df[["player_name", "line", "over_odds", "under_odds"]].head(10))
45
+ ```
46
+
47
+ ### 2. One player's prop history
48
+
49
+ `get_prop_history` shows how a player's line for a market moved across games. Search for the player id first.
50
+
51
+ ```python
52
+ from dunkapi import Client, to_dataframe
53
+
54
+ client = Client()
55
+
56
+ jokic = client.search_players("Jokic", limit=1)["players"][0]
57
+ history = client.get_prop_history(
58
+ jokic["player_id"],
59
+ "player_points",
60
+ from_date="2026-03-01",
61
+ to_date="2026-03-08",
62
+ bookmaker="draftkings",
63
+ limit=10,
64
+ )
65
+ print(to_dataframe(history).head())
66
+ ```
67
+
68
+ ### 3. Games on a date, and scoring leaders
69
+
70
+ `list_games` needs a filter such as `date`, `season` or `team`.
71
+
72
+ ```python
73
+ from dunkapi import Client
74
+
75
+ client = Client()
76
+
77
+ games = client.list_games(date="2026-03-15", limit=3)["games"]
78
+ for g in games:
79
+ print(g["away"]["abbrev"], g["away"]["score"], "at", g["home"]["abbrev"], g["home"]["score"])
80
+
81
+ leaders = client.get_leaders("pts", limit=5)
82
+ for row in leaders["leaders"]:
83
+ print(row["name"], row["team"], row["value"])
84
+ ```
85
+
86
+ ## Credits
87
+
88
+ Every method returns the `data` object from the response. After each call, `client.last_credits_used` and `client.last_credits_remaining` hold the counters from the `X-Credits-Used` and `X-Credits-Remaining` headers. Methods that take `estimate_only=True` return the price of a call without running or charging it.
89
+
90
+ ## Pandas
91
+
92
+ ```python
93
+ from dunkapi import to_dataframe
94
+
95
+ df = to_dataframe(data) # finds the main list in the response
96
+ df = to_dataframe(data, key="rows") # or name the list yourself
97
+ ```
98
+
99
+ Nested fields become dotted columns. Install pandas separately or with `pip install "dunkapi[pandas]"`.
100
+
101
+ ## Errors
102
+
103
+ Every error is an `APIError` subclass, with the server's message and the HTTP status.
104
+
105
+ | Exception | Status | Meaning |
106
+ | --- | --- | --- |
107
+ | `AuthError` | 401 | Missing, invalid or revoked key |
108
+ | `InsufficientCreditsError` | 402 | Not enough credits for the call |
109
+ | `NotFoundError` | 404 | The id or name does not exist |
110
+ | `RateLimitError` | 429 | Too many requests; has `.retry_after` when the server sends it |
111
+ | `APIError` | 400, 5xx | Bad arguments or a server problem |
112
+ | `APIConnectionError` | none | No response (network or timeout) |
113
+
114
+ ```python
115
+ from dunkapi import Client, APIError, InsufficientCreditsError, RateLimitError
116
+
117
+ client = Client()
118
+ try:
119
+ data = client.list_teams()
120
+ except InsufficientCreditsError:
121
+ print("Out of credits, top up at https://dunkapi.com")
122
+ except RateLimitError as exc:
123
+ print("Slow down, retry after", exc.retry_after)
124
+ except APIError as exc:
125
+ print(exc.status_code, exc.message)
126
+ ```
127
+
128
+ The client retries 429 and 5xx responses and connection failures up to 3 times with backoff, and honors `Retry-After`. Set `Client(max_retries=0)` to turn that off.
129
+
130
+ If you see `CERTIFICATE_VERIFY_FAILED` on a python.org install for macOS, run the "Install Certificates.command" script that came with Python, or `pip install certifi` (the client uses it when present).
131
+
132
+ ## Options
133
+
134
+ ```python
135
+ Client(
136
+ api_key=None, # defaults to $DUNKAPI_API_KEY
137
+ base_url="https://mcp.dunkapi.com", # point at another host
138
+ timeout=60.0, # seconds per request
139
+ max_retries=3,
140
+ )
141
+ ```
142
+
143
+ `client.call("tool_name", {"arg": "value"})` calls any tool by name, which helps when the API adds a tool before this package does.
144
+
145
+ ## Tools
146
+
147
+ Method names match the API tool names. Arguments are keyword arguments; required ones can also be passed positionally. Each method's docstring lists its arguments (`help(client.list_teams)`).
148
+
149
+ | Method | Credits | What it does |
150
+ | --- | --- | --- |
151
+ | `list_teams` | 1 | List teams |
152
+ | `list_games` | 2 | List games |
153
+ | `get_schedule` | 2 | Schedule |
154
+ | `get_game` | 5 | Game |
155
+ | `get_standings` | 2 | Standings |
156
+ | `get_injuries` | 2 | Injuries |
157
+ | `search_players` | 1 | Search players |
158
+ | `get_player` | 5 | Player |
159
+ | `get_player_games` | 5 | Player games |
160
+ | `get_leaders` | 5 | Leaders |
161
+ | `get_team_stats` | 5 | Team stats |
162
+ | `get_plays` | 10 | Plays |
163
+ | `get_shot_chart` | 10 | Shot chart |
164
+ | `get_odds` | 5 | Odds |
165
+ | `get_line_movement` | 10 | Line movement |
166
+ | `get_ratings` | 2 | Ratings |
167
+ | `get_player_props` | 10 | Player props |
168
+ | `get_prop_history` | 10 | Prop history |
169
+
170
+ Full API reference: https://dunkapi.com/docs
171
+
172
+ ## License
173
+
174
+ MIT
@@ -0,0 +1,50 @@
1
+ [build-system]
2
+ requires = ["hatchling>=1.27"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "dunkapi"
7
+ dynamic = ["version"]
8
+ description = "Python client for the DunkAPI NBA data API. No dependencies."
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+ license = "MIT"
12
+ license-files = ["LICENSE"]
13
+ authors = [{ name = "DunkAPI", email = "support@dunkapi.com" }]
14
+ keywords = ["nba", "sports-data", "api-client", "betting", "player-props", "odds", "dunkapi"]
15
+ classifiers = [
16
+ "Development Status :: 4 - Beta",
17
+ "Intended Audience :: Developers",
18
+ "Operating System :: OS Independent",
19
+ "Programming Language :: Python :: 3",
20
+ "Programming Language :: Python :: 3.9",
21
+ "Programming Language :: Python :: 3.10",
22
+ "Programming Language :: Python :: 3.11",
23
+ "Programming Language :: Python :: 3.12",
24
+ "Programming Language :: Python :: 3.13",
25
+ "Topic :: Software Development :: Libraries :: Python Modules",
26
+ "Typing :: Typed",
27
+ ]
28
+ dependencies = []
29
+
30
+ [project.optional-dependencies]
31
+ pandas = ["pandas>=1.5"]
32
+ test = ["pytest>=7"]
33
+
34
+ [project.urls]
35
+ Homepage = "https://dunkapi.com"
36
+ Documentation = "https://dunkapi.com/docs"
37
+ Repository = "https://github.com/noahowsh/puckapi"
38
+ "Sign up" = "https://dunkapi.com/signup"
39
+
40
+ [tool.hatch.version]
41
+ path = "src/dunkapi/_version.py"
42
+
43
+ [tool.hatch.build.targets.wheel]
44
+ packages = ["src/dunkapi"]
45
+
46
+ [tool.hatch.build.targets.sdist]
47
+ include = ["src", "tests", "README.md", "LICENSE", "pyproject.toml"]
48
+
49
+ [tool.pytest.ini_options]
50
+ testpaths = ["tests"]
@@ -0,0 +1,25 @@
1
+ """DunkAPI: Python client for the DunkAPI NBA data API."""
2
+ from ._core import (
3
+ APIConnectionError,
4
+ APIError,
5
+ AuthError,
6
+ InsufficientCreditsError,
7
+ NotFoundError,
8
+ RateLimitError,
9
+ to_dataframe,
10
+ )
11
+ from ._version import __version__
12
+ from .client import TOOLS, Client
13
+
14
+ __all__ = [
15
+ "APIConnectionError",
16
+ "APIError",
17
+ "AuthError",
18
+ "Client",
19
+ "InsufficientCreditsError",
20
+ "NotFoundError",
21
+ "RateLimitError",
22
+ "TOOLS",
23
+ "__version__",
24
+ "to_dataframe",
25
+ ]