iplaygames-sdk 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.
@@ -0,0 +1,20 @@
1
+ Metadata-Version: 2.4
2
+ Name: iplaygames-sdk
3
+ Version: 1.0.0
4
+ Summary: IPlayGames SDK - High-level wrapper for casino game aggregation
5
+ Author-email: IPlayGames <support@iplaygames.ai>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/iplaygamesai/sdk-python
8
+ Project-URL: Documentation, https://docs.iplaygames.ai/sdks/python
9
+ Classifier: Development Status :: 4 - Beta
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.8
14
+ Classifier: Programming Language :: Python :: 3.9
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Requires-Python: >=3.8
19
+ Description-Content-Type: text/markdown
20
+ Requires-Dist: iplaygames-api-client>=1.0.0
@@ -0,0 +1,29 @@
1
+ """
2
+ IPlayGames SDK
3
+ High-level wrapper for casino game aggregation
4
+ """
5
+
6
+ from .client import Client
7
+ from .flows.games import GamesFlow
8
+ from .flows.sessions import SessionsFlow
9
+ from .flows.multi_session import MultiSessionFlow
10
+ from .flows.jackpot import JackpotFlow
11
+ from .flows.promotions import PromotionsFlow
12
+ from .flows.jackpot_widget import JackpotWidgetFlow
13
+ from .flows.promotion_widget import PromotionWidgetFlow
14
+ from .webhooks import WebhookHandler, WebhookPayload
15
+
16
+ __version__ = "1.0.0"
17
+
18
+ __all__ = [
19
+ "Client",
20
+ "GamesFlow",
21
+ "SessionsFlow",
22
+ "MultiSessionFlow",
23
+ "JackpotFlow",
24
+ "PromotionsFlow",
25
+ "JackpotWidgetFlow",
26
+ "PromotionWidgetFlow",
27
+ "WebhookHandler",
28
+ "WebhookPayload",
29
+ ]
@@ -0,0 +1,189 @@
1
+ """
2
+ IPlayGames SDK Client
3
+
4
+ Main entry point for the IPlayGames API SDK.
5
+ Provides high-level flows for common operations.
6
+ """
7
+
8
+ from typing import Optional
9
+ from iplaygames_api_client import Configuration, ApiClient
10
+ from iplaygames_api_client.api import (
11
+ GamesApi,
12
+ GameSessionsApi,
13
+ MultiSessionsApi,
14
+ WidgetManagementApi,
15
+ FreespinsApi,
16
+ EndpointsApi,
17
+ GameTransactionsApi,
18
+ )
19
+
20
+ from .flows.games import GamesFlow
21
+ from .flows.sessions import SessionsFlow
22
+ from .flows.multi_session import MultiSessionFlow
23
+ from .flows.jackpot import JackpotFlow
24
+ from .flows.promotions import PromotionsFlow
25
+ from .flows.jackpot_widget import JackpotWidgetFlow
26
+ from .flows.promotion_widget import PromotionWidgetFlow
27
+ from .webhooks import WebhookHandler
28
+
29
+
30
+ class Client:
31
+ """Main client for the IPlayGames SDK"""
32
+
33
+ def __init__(
34
+ self,
35
+ api_key: str,
36
+ base_url: str = "https://api.iplaygames.ai",
37
+ webhook_secret: Optional[str] = None,
38
+ timeout: Optional[int] = None,
39
+ debug: bool = False,
40
+ ):
41
+ """
42
+ Create a new IPlayGames client
43
+
44
+ Args:
45
+ api_key: Your API key
46
+ base_url: API base URL (default: https://api.iplaygames.ai)
47
+ webhook_secret: Secret for verifying webhooks
48
+ timeout: Request timeout in seconds
49
+ debug: Enable debug logging
50
+ """
51
+ if not api_key:
52
+ raise ValueError("api_key is required")
53
+
54
+ self._config = Configuration(
55
+ host=base_url,
56
+ access_token=api_key,
57
+ )
58
+ self._api_client = ApiClient(self._config)
59
+ self._webhook_secret = webhook_secret
60
+ self._base_url = base_url
61
+
62
+ # SDK API instances (lazy-loaded)
63
+ self._games_api: Optional[GamesApi] = None
64
+ self._game_sessions_api: Optional[GameSessionsApi] = None
65
+ self._multi_sessions_api: Optional[MultiSessionsApi] = None
66
+ self._widget_management_api: Optional[WidgetManagementApi] = None
67
+ self._freespins_api: Optional[FreespinsApi] = None
68
+ self._endpoints_api: Optional[EndpointsApi] = None
69
+ self._game_transactions_api: Optional[GameTransactionsApi] = None
70
+
71
+ # Flow instances (lazy-loaded)
72
+ self._games_flow: Optional[GamesFlow] = None
73
+ self._sessions_flow: Optional[SessionsFlow] = None
74
+ self._multi_session_flow: Optional[MultiSessionFlow] = None
75
+ self._jackpot_flow: Optional[JackpotFlow] = None
76
+ self._promotions_flow: Optional[PromotionsFlow] = None
77
+ self._jackpot_widget_flow: Optional[JackpotWidgetFlow] = None
78
+ self._promotion_widget_flow: Optional[PromotionWidgetFlow] = None
79
+ self._webhook_handler: Optional[WebhookHandler] = None
80
+
81
+ def get_base_url(self) -> str:
82
+ """Get the base URL"""
83
+ return self._base_url
84
+
85
+ # =========================================================================
86
+ # SDK API Accessors
87
+ # =========================================================================
88
+
89
+ @property
90
+ def games_api(self) -> GamesApi:
91
+ if self._games_api is None:
92
+ self._games_api = GamesApi(self._api_client)
93
+ return self._games_api
94
+
95
+ @property
96
+ def game_sessions_api(self) -> GameSessionsApi:
97
+ if self._game_sessions_api is None:
98
+ self._game_sessions_api = GameSessionsApi(self._api_client)
99
+ return self._game_sessions_api
100
+
101
+ @property
102
+ def multi_sessions_api(self) -> MultiSessionsApi:
103
+ if self._multi_sessions_api is None:
104
+ self._multi_sessions_api = MultiSessionsApi(self._api_client)
105
+ return self._multi_sessions_api
106
+
107
+ @property
108
+ def widget_management_api(self) -> WidgetManagementApi:
109
+ if self._widget_management_api is None:
110
+ self._widget_management_api = WidgetManagementApi(self._api_client)
111
+ return self._widget_management_api
112
+
113
+ @property
114
+ def freespins_api(self) -> FreespinsApi:
115
+ if self._freespins_api is None:
116
+ self._freespins_api = FreespinsApi(self._api_client)
117
+ return self._freespins_api
118
+
119
+ @property
120
+ def endpoints_api(self) -> EndpointsApi:
121
+ if self._endpoints_api is None:
122
+ self._endpoints_api = EndpointsApi(self._api_client)
123
+ return self._endpoints_api
124
+
125
+ @property
126
+ def game_transactions_api(self) -> GameTransactionsApi:
127
+ if self._game_transactions_api is None:
128
+ self._game_transactions_api = GameTransactionsApi(self._api_client)
129
+ return self._game_transactions_api
130
+
131
+ # =========================================================================
132
+ # High-Level Flow Accessors
133
+ # =========================================================================
134
+
135
+ def games(self) -> GamesFlow:
136
+ """Games flow - List and retrieve games"""
137
+ if self._games_flow is None:
138
+ self._games_flow = GamesFlow(self)
139
+ return self._games_flow
140
+
141
+ def sessions(self) -> SessionsFlow:
142
+ """Sessions flow - Start and manage game sessions"""
143
+ if self._sessions_flow is None:
144
+ self._sessions_flow = SessionsFlow(self)
145
+ return self._sessions_flow
146
+
147
+ def multi_session(self) -> MultiSessionFlow:
148
+ """Multi-session flow - TikTok-style game swiping"""
149
+ if self._multi_session_flow is None:
150
+ self._multi_session_flow = MultiSessionFlow(self)
151
+ return self._multi_session_flow
152
+
153
+ def jackpot(self) -> JackpotFlow:
154
+ """Jackpot flow - Configure and manage jackpot pools"""
155
+ if self._jackpot_flow is None:
156
+ self._jackpot_flow = JackpotFlow(self)
157
+ return self._jackpot_flow
158
+
159
+ def promotions(self) -> PromotionsFlow:
160
+ """Promotions flow - Create and manage promotions"""
161
+ if self._promotions_flow is None:
162
+ self._promotions_flow = PromotionsFlow(self)
163
+ return self._promotions_flow
164
+
165
+ def jackpot_widget(self) -> JackpotWidgetFlow:
166
+ """Jackpot Widget flow - Manage widget tokens for jackpot displays"""
167
+ if self._jackpot_widget_flow is None:
168
+ self._jackpot_widget_flow = JackpotWidgetFlow(self)
169
+ return self._jackpot_widget_flow
170
+
171
+ def promotion_widget(self) -> PromotionWidgetFlow:
172
+ """Promotion Widget flow - Manage widget tokens for promotion displays"""
173
+ if self._promotion_widget_flow is None:
174
+ self._promotion_widget_flow = PromotionWidgetFlow(self)
175
+ return self._promotion_widget_flow
176
+
177
+ def webhooks(self) -> WebhookHandler:
178
+ """Webhook handler - Verify and handle callbacks"""
179
+ if self._webhook_handler is None:
180
+ if not self._webhook_secret:
181
+ raise ValueError(
182
+ "Webhook secret not configured. Pass webhook_secret in client options."
183
+ )
184
+ self._webhook_handler = WebhookHandler(self._webhook_secret)
185
+ return self._webhook_handler
186
+
187
+ def create_webhook_handler(self, secret: str) -> WebhookHandler:
188
+ """Create webhook handler with a specific secret"""
189
+ return WebhookHandler(secret)
@@ -0,0 +1,23 @@
1
+ """
2
+ IPlayGames SDK Flows
3
+
4
+ High-level flows for common operations.
5
+ """
6
+
7
+ from .games import GamesFlow
8
+ from .sessions import SessionsFlow
9
+ from .multi_session import MultiSessionFlow
10
+ from .jackpot import JackpotFlow
11
+ from .promotions import PromotionsFlow
12
+ from .jackpot_widget import JackpotWidgetFlow
13
+ from .promotion_widget import PromotionWidgetFlow
14
+
15
+ __all__ = [
16
+ "GamesFlow",
17
+ "SessionsFlow",
18
+ "MultiSessionFlow",
19
+ "JackpotFlow",
20
+ "PromotionsFlow",
21
+ "JackpotWidgetFlow",
22
+ "PromotionWidgetFlow",
23
+ ]
@@ -0,0 +1,120 @@
1
+ """
2
+ Games Flow
3
+
4
+ List and retrieve available games from the aggregator.
5
+ """
6
+
7
+ from typing import TYPE_CHECKING, Any, Dict, List, Optional
8
+
9
+ if TYPE_CHECKING:
10
+ from ..client import Client
11
+
12
+
13
+ class GamesFlow:
14
+ """High-level flow for game operations"""
15
+
16
+ def __init__(self, client: "Client"):
17
+ self._client = client
18
+
19
+ def list(
20
+ self,
21
+ search: Optional[str] = None,
22
+ producer_id: Optional[int] = None,
23
+ provider: Optional[str] = None,
24
+ game_type: Optional[str] = None,
25
+ per_page: Optional[int] = None,
26
+ ) -> Dict[str, Any]:
27
+ """
28
+ List available games
29
+
30
+ Args:
31
+ search: Search by game title
32
+ producer_id: Filter by producer ID
33
+ provider: Filter by provider
34
+ game_type: Filter by game type
35
+ per_page: Number of results per page
36
+
37
+ Returns:
38
+ Dict with success, games, and meta
39
+ """
40
+ try:
41
+ response = self._client.games_api.list_games(
42
+ search=search,
43
+ producer_id=producer_id,
44
+ provider=provider,
45
+ type=game_type,
46
+ per_page=str(per_page) if per_page else None,
47
+ )
48
+
49
+ games = []
50
+ for g in response.data or []:
51
+ games.append({
52
+ "id": g.id,
53
+ "title": g.title,
54
+ "producer": g.producer,
55
+ "type": g.type,
56
+ "image_url": getattr(g, "image_url", None),
57
+ "demo_available": getattr(g, "demo_available", None),
58
+ })
59
+
60
+ meta = {}
61
+ if hasattr(response, "meta") and response.meta:
62
+ meta = {
63
+ "current_page": getattr(response.meta, "current_page", 1),
64
+ "last_page": getattr(response.meta, "last_page", 1),
65
+ "per_page": getattr(response.meta, "per_page", 100),
66
+ "total": getattr(response.meta, "total", len(games)),
67
+ }
68
+
69
+ return {
70
+ "success": True,
71
+ "games": games,
72
+ "meta": meta,
73
+ }
74
+ except Exception as e:
75
+ return {
76
+ "success": False,
77
+ "error": str(e),
78
+ "games": [],
79
+ "meta": {"current_page": 1, "last_page": 1, "per_page": 100, "total": 0},
80
+ }
81
+
82
+ def get(self, game_id: int) -> Dict[str, Any]:
83
+ """
84
+ Get a single game by ID
85
+
86
+ Args:
87
+ game_id: The game ID
88
+
89
+ Returns:
90
+ Dict with success and data
91
+ """
92
+ try:
93
+ self._client.games_api.get_api_v1_games_id(str(game_id))
94
+
95
+ return {
96
+ "success": True,
97
+ "data": {"id": game_id},
98
+ }
99
+ except Exception as e:
100
+ return {
101
+ "success": False,
102
+ "error": str(e),
103
+ }
104
+
105
+ def by_producer(self, producer_id: int, **kwargs) -> Dict[str, Any]:
106
+ """Get games by producer"""
107
+ return self.list(producer_id=producer_id, **kwargs)
108
+
109
+ def by_category(self, game_type: str, **kwargs) -> Dict[str, Any]:
110
+ """Get games by category/type"""
111
+ return self.list(game_type=game_type, **kwargs)
112
+
113
+ def search(self, query: str, **kwargs) -> Dict[str, Any]:
114
+ """Search games by title"""
115
+ return self.list(search=query, **kwargs)
116
+
117
+ def all(self, **kwargs) -> Dict[str, Any]:
118
+ """Get all games (no pagination)"""
119
+ kwargs["per_page"] = "all"
120
+ return self.list(**kwargs)
@@ -0,0 +1,239 @@
1
+ """
2
+ Jackpot Flow
3
+
4
+ Configure and manage jackpot pools for your casino.
5
+ """
6
+
7
+ from typing import TYPE_CHECKING, Any, Dict, List, Optional
8
+
9
+ if TYPE_CHECKING:
10
+ from ..client import Client
11
+
12
+
13
+ class JackpotFlow:
14
+ """High-level flow for jackpot operations"""
15
+
16
+ def __init__(self, client: "Client"):
17
+ self._client = client
18
+
19
+ def get_configuration(self) -> Dict[str, Any]:
20
+ """Get current jackpot configuration"""
21
+ try:
22
+ self._client.endpoints_api.configure_jackpot_settings_for_the_operator(None)
23
+
24
+ return {
25
+ "success": True,
26
+ "message": "Configuration retrieved",
27
+ }
28
+ except Exception as e:
29
+ return {
30
+ "success": False,
31
+ "error": str(e),
32
+ }
33
+
34
+ def configure(self, prize_tiers: Optional[List[Any]] = None) -> Dict[str, Any]:
35
+ """
36
+ Configure jackpot settings
37
+
38
+ Args:
39
+ prize_tiers: Array of prize tier configurations
40
+
41
+ Returns:
42
+ Dict with success status
43
+ """
44
+ try:
45
+ request = {}
46
+ if prize_tiers:
47
+ request["prize_tiers"] = prize_tiers
48
+
49
+ self._client.endpoints_api.configure_jackpot_settings_for_the_operator(request)
50
+
51
+ return {
52
+ "success": True,
53
+ "message": "Configuration updated",
54
+ }
55
+ except Exception as e:
56
+ return {
57
+ "success": False,
58
+ "error": str(e),
59
+ }
60
+
61
+ def get_pools(self) -> Dict[str, Any]:
62
+ """Get all active jackpot pools"""
63
+ try:
64
+ self._client.endpoints_api.list_operators_jackpot_pools(None)
65
+
66
+ return {
67
+ "success": True,
68
+ "pools": [],
69
+ }
70
+ except Exception as e:
71
+ return {
72
+ "success": False,
73
+ "error": str(e),
74
+ "pools": [],
75
+ }
76
+
77
+ def get_pool(self, pool_type: str) -> Dict[str, Any]:
78
+ """
79
+ Get a specific pool by type
80
+
81
+ Args:
82
+ pool_type: Pool type: daily, weekly, monthly, progressive
83
+
84
+ Returns:
85
+ Dict with pool details
86
+ """
87
+ try:
88
+ self._client.endpoints_api.list_operators_jackpot_pools({"pool_type": pool_type})
89
+
90
+ return {
91
+ "success": True,
92
+ "pool_type": pool_type,
93
+ }
94
+ except Exception as e:
95
+ return {
96
+ "success": False,
97
+ "error": str(e),
98
+ }
99
+
100
+ def get_winners(self, pool_id: str) -> Dict[str, Any]:
101
+ """Get winners for a pool"""
102
+ return {
103
+ "success": True,
104
+ "pool_id": pool_id,
105
+ "winners": [],
106
+ }
107
+
108
+ def get_games(self, pool_type: Optional[str] = None) -> Dict[str, Any]:
109
+ """
110
+ Get games eligible for jackpot
111
+
112
+ Args:
113
+ pool_type: Filter by pool type
114
+
115
+ Returns:
116
+ Dict with list of games
117
+ """
118
+ try:
119
+ request = {"pool_type": pool_type} if pool_type else None
120
+ self._client.endpoints_api.get_games_for_a_pool_type_or_all_pool_types(request)
121
+
122
+ return {
123
+ "success": True,
124
+ "pool_type": pool_type,
125
+ "games": [],
126
+ }
127
+ except Exception as e:
128
+ return {
129
+ "success": False,
130
+ "error": str(e),
131
+ "games": [],
132
+ }
133
+
134
+ def add_games(self, pool_type: str, game_ids: List[int]) -> Dict[str, Any]:
135
+ """
136
+ Add games to a jackpot pool
137
+
138
+ Args:
139
+ pool_type: Pool type
140
+ game_ids: Array of game IDs
141
+
142
+ Returns:
143
+ Dict with success status
144
+ """
145
+ try:
146
+ self._client.endpoints_api.add_games_to_a_jackpot_pool_type({
147
+ "pool_type": pool_type,
148
+ "game_ids": game_ids,
149
+ })
150
+
151
+ return {
152
+ "success": True,
153
+ "message": "Games added to jackpot pool",
154
+ }
155
+ except Exception as e:
156
+ return {
157
+ "success": False,
158
+ "error": str(e),
159
+ }
160
+
161
+ def remove_games(self, pool_type: str, game_ids: List[int]) -> Dict[str, Any]:
162
+ """
163
+ Remove games from a jackpot pool
164
+
165
+ Args:
166
+ pool_type: Pool type
167
+ game_ids: Array of game IDs
168
+
169
+ Returns:
170
+ Dict with success status
171
+ """
172
+ try:
173
+ self._client.endpoints_api.remove_games_from_a_jackpot_pool_type({
174
+ "pool_type": pool_type,
175
+ "game_ids": game_ids,
176
+ })
177
+
178
+ return {
179
+ "success": True,
180
+ "message": "Games removed from jackpot pool",
181
+ }
182
+ except Exception as e:
183
+ return {
184
+ "success": False,
185
+ "error": str(e),
186
+ }
187
+
188
+ def get_contributions(
189
+ self,
190
+ player_id: Optional[str] = None,
191
+ pool_type: Optional[str] = None,
192
+ ) -> Dict[str, Any]:
193
+ """
194
+ Get contribution history
195
+
196
+ Args:
197
+ player_id: Filter by player
198
+ pool_type: Filter by pool type
199
+
200
+ Returns:
201
+ Dict with list of contributions
202
+ """
203
+ try:
204
+ request = {}
205
+ if player_id:
206
+ request["player_id"] = player_id
207
+ if pool_type:
208
+ request["pool_type"] = pool_type
209
+
210
+ self._client.endpoints_api.get_player_contribution_history(request)
211
+
212
+ return {
213
+ "success": True,
214
+ "contributions": [],
215
+ }
216
+ except Exception as e:
217
+ return {
218
+ "success": False,
219
+ "error": str(e),
220
+ "contributions": [],
221
+ }
222
+
223
+ def release(self, pool_id: str, player_id: str) -> Dict[str, Any]:
224
+ """
225
+ Manually release a jackpot pool
226
+
227
+ Args:
228
+ pool_id: Pool ID
229
+ player_id: Winner's player ID
230
+
231
+ Returns:
232
+ Dict with payout details
233
+ """
234
+ return {
235
+ "success": True,
236
+ "pool_id": pool_id,
237
+ "player_id": player_id,
238
+ "message": "Jackpot release initiated",
239
+ }