dataspace-sdk 0.4.2__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.
@@ -0,0 +1,206 @@
1
+ """Main DataSpace SDK client."""
2
+
3
+ from typing import Optional
4
+
5
+ from dataspace_sdk.auth import AuthClient
6
+ from dataspace_sdk.resources.aimodels import AIModelClient
7
+ from dataspace_sdk.resources.datasets import DatasetClient
8
+ from dataspace_sdk.resources.sectors import SectorClient
9
+ from dataspace_sdk.resources.usecases import UseCaseClient
10
+
11
+
12
+ class DataSpaceClient:
13
+ """
14
+ Main client for interacting with DataSpace API.
15
+
16
+ Example:
17
+ >>> from dataspace_sdk import DataSpaceClient
18
+ >>>
19
+ >>> # Initialize client
20
+ >>> client = DataSpaceClient(base_url="https://api.dataspace.example.com")
21
+ >>>
22
+ >>> # Login with Keycloak token
23
+ >>> client.login(keycloak_token="your_keycloak_token")
24
+ >>>
25
+ >>> # Search for datasets
26
+ >>> datasets = client.datasets.search(query="health", tags=["public-health"])
27
+ >>>
28
+ >>> # Get a specific dataset
29
+ >>> dataset = client.datasets.get_by_id("dataset-uuid")
30
+ >>>
31
+ >>> # Get organization's resources
32
+ >>> org_datasets = client.datasets.get_organization_datasets("org-uuid")
33
+ >>> org_models = client.aimodels.get_organization_models("org-uuid")
34
+ >>> org_usecases = client.usecases.get_organization_usecases("org-uuid")
35
+ """
36
+
37
+ def __init__(
38
+ self,
39
+ base_url: str,
40
+ keycloak_url: Optional[str] = None,
41
+ keycloak_realm: Optional[str] = None,
42
+ keycloak_client_id: Optional[str] = None,
43
+ keycloak_client_secret: Optional[str] = None,
44
+ ):
45
+ """
46
+ Initialize the DataSpace client.
47
+
48
+ Args:
49
+ base_url: Base URL of the DataSpace API (e.g., "https://api.dataspace.example.com")
50
+ keycloak_url: Keycloak server URL (e.g., "https://opub-kc.civicdatalab.in")
51
+ keycloak_realm: Keycloak realm name (e.g., "DataSpace")
52
+ keycloak_client_id: Keycloak client ID (e.g., "dataspace")
53
+ keycloak_client_secret: Optional client secret for confidential clients
54
+ """
55
+ self.base_url = base_url.rstrip("/")
56
+ self._auth = AuthClient(
57
+ self.base_url,
58
+ keycloak_url=keycloak_url,
59
+ keycloak_realm=keycloak_realm,
60
+ keycloak_client_id=keycloak_client_id,
61
+ keycloak_client_secret=keycloak_client_secret,
62
+ )
63
+
64
+ # Initialize resource clients
65
+ self.datasets = DatasetClient(self.base_url, self._auth)
66
+ self.aimodels = AIModelClient(self.base_url, self._auth)
67
+ self.usecases = UseCaseClient(self.base_url, self._auth)
68
+ self.sectors = SectorClient(self.base_url, self._auth)
69
+
70
+ def login(self, username: str, password: str) -> dict:
71
+ """
72
+ Login using username and password.
73
+
74
+ Args:
75
+ username: User's username or email
76
+ password: User's password
77
+
78
+ Returns:
79
+ Dictionary containing user info and tokens
80
+
81
+ Raises:
82
+ DataSpaceAuthError: If authentication fails
83
+
84
+ Example:
85
+ >>> client = DataSpaceClient(
86
+ ... base_url="https://api.dataspace.example.com",
87
+ ... keycloak_url="https://opub-kc.civicdatalab.in",
88
+ ... keycloak_realm="DataSpace",
89
+ ... keycloak_client_id="dataspace"
90
+ ... )
91
+ >>> user_info = client.login(username="user@example.com", password="secret")
92
+ >>> print(user_info["user"]["username"])
93
+ """
94
+ return self._auth.login(username, password)
95
+
96
+ def login_as_service_account(self) -> dict:
97
+ """
98
+ Login using client credentials (service account).
99
+
100
+ This method authenticates the client itself using client_id and client_secret.
101
+ The Keycloak client must have "Service Accounts Enabled" turned ON.
102
+
103
+ This is the recommended approach for backend services and automated tasks.
104
+
105
+ Returns:
106
+ Dictionary containing user info and tokens
107
+
108
+ Raises:
109
+ DataSpaceAuthError: If authentication fails
110
+
111
+ Example:
112
+ >>> client = DataSpaceClient(
113
+ ... base_url="https://api.dataspace.example.com",
114
+ ... keycloak_url="https://opub-kc.civicdatalab.in",
115
+ ... keycloak_realm="DataSpace",
116
+ ... keycloak_client_id="dataspace",
117
+ ... keycloak_client_secret="your-secret"
118
+ ... )
119
+ >>> info = client.login_as_service_account()
120
+ >>> print("Authenticated as service account")
121
+ """
122
+ return self._auth.login_as_service_account()
123
+
124
+ def login_with_token(self, keycloak_token: str) -> dict:
125
+ """
126
+ Login using a pre-obtained Keycloak token.
127
+
128
+ Args:
129
+ keycloak_token: Valid Keycloak access token
130
+
131
+ Returns:
132
+ Dictionary containing user info and tokens
133
+
134
+ Raises:
135
+ DataSpaceAuthError: If authentication fails
136
+
137
+ Example:
138
+ >>> client = DataSpaceClient(base_url="https://api.dataspace.example.com")
139
+ >>> user_info = client.login_with_token(keycloak_token="your_token")
140
+ >>> print(user_info["user"]["username"])
141
+ """
142
+ return self._auth._login_with_keycloak_token(keycloak_token)
143
+
144
+ def refresh_token(self) -> str:
145
+ """
146
+ Refresh the access token using the refresh token.
147
+
148
+ Returns:
149
+ New access token
150
+
151
+ Raises:
152
+ DataSpaceAuthError: If token refresh fails
153
+
154
+ Example:
155
+ >>> client.refresh_token()
156
+ """
157
+ return self._auth.refresh_access_token()
158
+
159
+ def get_user_info(self) -> dict:
160
+ """
161
+ Get current user information.
162
+
163
+ Returns:
164
+ Dictionary containing user information including organizations
165
+
166
+ Raises:
167
+ DataSpaceAuthError: If not authenticated or request fails
168
+
169
+ Example:
170
+ >>> user_info = client.get_user_info()
171
+ >>> print(user_info["organizations"])
172
+ """
173
+ return self._auth.get_user_info()
174
+
175
+ def is_authenticated(self) -> bool:
176
+ """
177
+ Check if the client is authenticated.
178
+
179
+ Returns:
180
+ True if authenticated, False otherwise
181
+
182
+ Example:
183
+ >>> if client.is_authenticated():
184
+ ... datasets = client.datasets.search()
185
+ """
186
+ return self._auth.is_authenticated()
187
+
188
+ @property
189
+ def user(self) -> Optional[dict]:
190
+ """
191
+ Get cached user information.
192
+
193
+ Returns:
194
+ User information dictionary or None if not authenticated
195
+ """
196
+ return self._auth.user_info
197
+
198
+ @property
199
+ def access_token(self) -> Optional[str]:
200
+ """
201
+ Get the current access token.
202
+
203
+ Returns:
204
+ Access token string or None if not authenticated
205
+ """
206
+ return self._auth.access_token
@@ -0,0 +1,36 @@
1
+ """Custom exceptions for DataSpace SDK."""
2
+
3
+ from typing import Any, Optional
4
+
5
+
6
+ class DataSpaceAPIError(Exception):
7
+ """Base exception for DataSpace API errors."""
8
+
9
+ def __init__(
10
+ self,
11
+ message: str,
12
+ status_code: Optional[int] = None,
13
+ response: Optional[dict[str, Any]] = None,
14
+ ):
15
+ self.message = message
16
+ self.status_code = status_code
17
+ self.response = response
18
+ super().__init__(self.message)
19
+
20
+
21
+ class DataSpaceAuthError(DataSpaceAPIError):
22
+ """Exception raised for authentication errors."""
23
+
24
+ pass
25
+
26
+
27
+ class DataSpaceNotFoundError(DataSpaceAPIError):
28
+ """Exception raised when a resource is not found."""
29
+
30
+ pass
31
+
32
+
33
+ class DataSpaceValidationError(DataSpaceAPIError):
34
+ """Exception raised for validation errors."""
35
+
36
+ pass
@@ -0,0 +1,8 @@
1
+ """Resource clients for DataSpace SDK."""
2
+
3
+ from dataspace_sdk.resources.aimodels import AIModelClient
4
+ from dataspace_sdk.resources.datasets import DatasetClient
5
+ from dataspace_sdk.resources.sectors import SectorClient
6
+ from dataspace_sdk.resources.usecases import UseCaseClient
7
+
8
+ __all__ = ["DatasetClient", "AIModelClient", "UseCaseClient", "SectorClient"]