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,551 @@
1
+ Metadata-Version: 2.4
2
+ Name: dataspace-sdk
3
+ Version: 0.4.2
4
+ Summary: Python SDK for DataSpace API
5
+ Home-page: https://github.com/CivicDataLab/DataExchange
6
+ Author: CivicDataLab
7
+ Author-email: CivicDataLab <tech@civicdatalab.in>
8
+ License: AGPL-3.0
9
+ Project-URL: Homepage, https://github.com/CivicDataLab/DataExchange
10
+ Project-URL: Documentation, https://github.com/CivicDataLab/DataExchange/blob/main/docs/sdk/README.md
11
+ Project-URL: Repository, https://github.com/CivicDataLab/DataExchange
12
+ Project-URL: Bug Tracker, https://github.com/CivicDataLab/DataExchange/issues
13
+ Keywords: dataspace,api,sdk,datasets,aimodels,usecases
14
+ Classifier: Development Status :: 3 - Alpha
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: License :: OSI Approved :: GNU Affero General Public License v3
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.8
19
+ Classifier: Programming Language :: Python :: 3.9
20
+ Classifier: Programming Language :: Python :: 3.10
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Requires-Python: >=3.8
24
+ Description-Content-Type: text/markdown
25
+ Requires-Dist: requests>=2.28.0
26
+ Provides-Extra: dev
27
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
28
+ Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
29
+ Requires-Dist: black>=23.0.0; extra == "dev"
30
+ Requires-Dist: flake8>=6.0.0; extra == "dev"
31
+ Requires-Dist: mypy>=1.0.0; extra == "dev"
32
+ Requires-Dist: types-requests>=2.28.0; extra == "dev"
33
+ Dynamic: author
34
+ Dynamic: home-page
35
+ Dynamic: requires-python
36
+
37
+ # DataSpace Python SDK
38
+
39
+ A Python SDK for programmatic access to DataSpace resources including Datasets, AI Models, and Use Cases.
40
+
41
+ ## Installation
42
+
43
+ ### From PyPI (once published)
44
+
45
+ ```bash
46
+ pip install dataspace-sdk
47
+ ```
48
+
49
+ ### From Source
50
+
51
+ ```bash
52
+ git clone https://github.com/CivicDataLab/DataExchange.git
53
+ cd DataExchange/DataExBackend
54
+ pip install -e .
55
+ ```
56
+
57
+ ### For Development
58
+
59
+ ```bash
60
+ pip install -e ".[dev]"
61
+ ```
62
+
63
+ ## Quick Start
64
+
65
+ ```python
66
+ from dataspace_sdk import DataSpaceClient
67
+
68
+ # Initialize the client with Keycloak configuration
69
+ client = DataSpaceClient(
70
+ base_url="https://dev.api.civicdataspace.in",
71
+ keycloak_url="https://opub-kc.civicdatalab.in",
72
+ keycloak_realm="DataSpace",
73
+ keycloak_client_id="dataspace",
74
+ keycloak_client_secret="your_client_secret"
75
+ )
76
+
77
+ # Login with username and password
78
+ user_info = client.login(
79
+ username="your_email@example.com",
80
+ password="your_password"
81
+ )
82
+ print(f"Logged in as: {user_info['user']['username']}")
83
+
84
+ # Search for datasets
85
+ datasets = client.datasets.search(
86
+ query="health data",
87
+ tags=["public-health"],
88
+ page=1,
89
+ page_size=10
90
+ )
91
+
92
+ # Get a specific dataset
93
+ dataset = client.datasets.get_by_id("dataset-uuid")
94
+ print(f"Dataset: {dataset['title']}")
95
+
96
+ # Get organization's resources
97
+ if user_info['user']['organizations']:
98
+ org_id = user_info['user']['organizations'][0]['id']
99
+ org_datasets = client.datasets.get_organization_datasets(org_id)
100
+ ```
101
+
102
+ ## Features
103
+
104
+ - **Authentication**: Multiple authentication methods (username/password, Keycloak token, service account)
105
+ - **Automatic Token Management**: Automatic token refresh and re-login
106
+ - **Datasets**: Search, retrieve, and list datasets with filtering and pagination
107
+ - **AI Models**: Search, retrieve, call, and list AI models with filtering
108
+ - **Use Cases**: Search, retrieve, and list use cases with filtering
109
+ - **Organization Resources**: Get resources specific to your organizations
110
+ - **GraphQL & REST**: Supports both GraphQL and REST API endpoints
111
+ - **Error Handling**: Comprehensive exception handling with detailed error messages
112
+
113
+ ## Authentication
114
+
115
+ The SDK supports three authentication methods:
116
+
117
+ ### 1. Username and Password (Recommended for Users)
118
+
119
+ ```python
120
+ from dataspace_sdk import DataSpaceClient
121
+
122
+ client = DataSpaceClient(
123
+ base_url="https://dev.api.civicdataspace.in",
124
+ keycloak_url="https://opub-kc.civicdatalab.in",
125
+ keycloak_realm="DataSpace",
126
+ keycloak_client_id="dataspace",
127
+ keycloak_client_secret="your_client_secret"
128
+ )
129
+
130
+ # Login with username and password
131
+ user_info = client.login(
132
+ username="your_email@example.com",
133
+ password="your_password"
134
+ )
135
+
136
+ # Access user information
137
+ print(user_info['user']['username'])
138
+ print(user_info['user']['organizations'])
139
+ ```
140
+
141
+ ### 2. Keycloak Token (For Token Pass-through)
142
+
143
+ ```python
144
+ # Login with an existing Keycloak token
145
+ response = client.login_with_token(keycloak_token="your_keycloak_token")
146
+ ```
147
+
148
+ ### 3. Service Account (For Backend Services)
149
+
150
+ ```python
151
+ # Login as a service account using client credentials
152
+ service_info = client.login_as_service_account()
153
+ ```
154
+
155
+ For detailed authentication documentation, see [AUTHENTICATION_COMPLETE.md](./AUTHENTICATION_COMPLETE.md)
156
+
157
+ ### Token Refresh
158
+
159
+ ```python
160
+ # Refresh access token when it expires
161
+ new_token = client.refresh_token()
162
+ ```
163
+
164
+ ### Check Authentication Status
165
+
166
+ ```python
167
+ if client.is_authenticated():
168
+ print("Authenticated!")
169
+ print(f"User: {client.user['username']}")
170
+ ```
171
+
172
+ ## Working with Datasets
173
+
174
+ ### Search Datasets
175
+
176
+ ```python
177
+ # Basic search
178
+ results = client.datasets.search(query="education")
179
+
180
+ # Advanced search with filters
181
+ results = client.datasets.search(
182
+ query="health",
183
+ tags=["public-health", "covid-19"],
184
+ sectors=["Health"],
185
+ geographies=["India", "Karnataka"],
186
+ status="PUBLISHED",
187
+ access_type="OPEN",
188
+ sort="recent",
189
+ page=1,
190
+ page_size=20
191
+ )
192
+
193
+ # Access results
194
+ print(f"Total results: {results['total']}")
195
+ for dataset in results['results']:
196
+ print(f"- {dataset['title']}")
197
+ ```
198
+
199
+ ### Get Dataset by ID
200
+
201
+ ```python
202
+ # Get detailed dataset information
203
+ dataset = client.datasets.get_by_id("550e8400-e29b-41d4-a716-446655440000")
204
+
205
+ print(f"Title: {dataset['title']}")
206
+ print(f"Description: {dataset['description']}")
207
+ print(f"Organization: {dataset['organization']['name']}")
208
+ print(f"Resources: {len(dataset['resources'])}")
209
+ ```
210
+
211
+ ### List All Datasets
212
+
213
+ ```python
214
+ # List with pagination
215
+ datasets = client.datasets.list_all(
216
+ status="PUBLISHED",
217
+ limit=50,
218
+ offset=0
219
+ )
220
+
221
+ for dataset in datasets:
222
+ print(f"- {dataset['title']}")
223
+ ```
224
+
225
+ ### Get Trending Datasets
226
+
227
+ ```python
228
+ trending = client.datasets.get_trending(limit=10)
229
+ for dataset in trending['results']:
230
+ print(f"- {dataset['title']} (views: {dataset['view_count']})")
231
+ ```
232
+
233
+ ### Get Organization Datasets
234
+
235
+ ```python
236
+ # Get datasets for your organization
237
+ org_id = client.user['organizations'][0]['id']
238
+ org_datasets = client.datasets.get_organization_datasets(
239
+ organization_id=org_id,
240
+ limit=20,
241
+ offset=0
242
+ )
243
+ ```
244
+
245
+ ## Working with AI Models
246
+
247
+ ### Search AI Models
248
+
249
+ ```python
250
+ # Basic search
251
+ results = client.aimodels.search(query="language model")
252
+
253
+ # Advanced search
254
+ results = client.aimodels.search(
255
+ query="llm",
256
+ tags=["nlp", "text-generation"],
257
+ model_type="LLM",
258
+ provider="OPENAI",
259
+ status="ACTIVE",
260
+ sort="recent",
261
+ page=1,
262
+ page_size=10
263
+ )
264
+ ```
265
+
266
+ ### Get AI Model by ID
267
+
268
+ ```python
269
+ # Using REST endpoint
270
+ model = client.aimodels.get_by_id("model-uuid")
271
+
272
+ # Using GraphQL (more detailed)
273
+ model = client.aimodels.get_by_id_graphql("model-uuid")
274
+
275
+ print(f"Model: {model['displayName']}")
276
+ print(f"Type: {model['modelType']}")
277
+ print(f"Provider: {model['provider']}")
278
+ print(f"Endpoints: {len(model['endpoints'])}")
279
+ ```
280
+
281
+ ### Call an AI Model
282
+
283
+ ```python
284
+ # Call an AI model with input text
285
+ result = client.aimodels.call_model(
286
+ model_id="model-uuid",
287
+ input_text="What is the capital of France?",
288
+ parameters={
289
+ "temperature": 0.7,
290
+ "max_tokens": 100
291
+ }
292
+ )
293
+
294
+ if result['success']:
295
+ print(f"Output: {result['output']}")
296
+ print(f"Latency: {result['latency_ms']}ms")
297
+ print(f"Provider: {result['provider']}")
298
+ else:
299
+ print(f"Error: {result['error']}")
300
+
301
+ # For long-running operations, use async call
302
+ task = client.aimodels.call_model_async(
303
+ model_id="model-uuid",
304
+ input_text="Generate a long document...",
305
+ parameters={"max_tokens": 2000}
306
+ )
307
+ print(f"Task ID: {task['task_id']}")
308
+ print(f"Status: {task['status']}")
309
+ ```
310
+
311
+ ### List All AI Models
312
+
313
+ ```python
314
+ models = client.aimodels.list_all(
315
+ status="ACTIVE",
316
+ model_type="LLM",
317
+ limit=20,
318
+ offset=0
319
+ )
320
+ ```
321
+
322
+ ### Get Organization AI Models
323
+
324
+ ```python
325
+ org_id = client.user['organizations'][0]['id']
326
+ org_models = client.aimodels.get_organization_models(
327
+ organization_id=org_id,
328
+ limit=20,
329
+ offset=0
330
+ )
331
+ ```
332
+
333
+ ## Working with Use Cases
334
+
335
+ ### Search Use Cases
336
+
337
+ ```python
338
+ # Basic search
339
+ results = client.usecases.search(query="health monitoring")
340
+
341
+ # Advanced search
342
+ results = client.usecases.search(
343
+ query="covid",
344
+ tags=["health", "monitoring"],
345
+ sectors=["Health"],
346
+ status="PUBLISHED",
347
+ running_status="COMPLETED",
348
+ sort="completed_on",
349
+ page=1,
350
+ page_size=10
351
+ )
352
+ ```
353
+
354
+ ### Get Use Case by ID
355
+
356
+ ```python
357
+ # Get use case by ID
358
+ usecase = client.usecases.get_by_id(123)
359
+
360
+ print(f"Title: {usecase['title']}")
361
+ print(f"Summary: {usecase['summary']}")
362
+ print(f"Status: {usecase['runningStatus']}")
363
+ print(f"Datasets used: {len(usecase['datasets'])}")
364
+ print(f"Organizations: {len(usecase['organizations'])}")
365
+ ```
366
+
367
+ ### List All Use Cases
368
+
369
+ ```python
370
+ usecases = client.usecases.list_all(
371
+ status="PUBLISHED",
372
+ running_status="COMPLETED",
373
+ limit=20,
374
+ offset=0
375
+ )
376
+ ```
377
+
378
+ ### Get Organization Use Cases
379
+
380
+ ```python
381
+ org_id = client.user['organizations'][0]['id']
382
+ org_usecases = client.usecases.get_organization_usecases(
383
+ organization_id=org_id,
384
+ limit=20,
385
+ offset=0
386
+ )
387
+ ```
388
+
389
+ ## Error Handling
390
+
391
+ ```python
392
+ from dataspace_sdk import (
393
+ DataSpaceAPIError,
394
+ DataSpaceAuthError,
395
+ DataSpaceNotFoundError,
396
+ DataSpaceValidationError,
397
+ )
398
+
399
+ try:
400
+ dataset = client.datasets.get_by_id("invalid-uuid")
401
+ except DataSpaceNotFoundError as e:
402
+ print(f"Dataset not found: {e.message}")
403
+ except DataSpaceAuthError as e:
404
+ print(f"Authentication error: {e.message}")
405
+ # Try to refresh token
406
+ client.refresh_token()
407
+ except DataSpaceValidationError as e:
408
+ print(f"Validation error: {e.message}")
409
+ print(f"Details: {e.response}")
410
+ except DataSpaceAPIError as e:
411
+ print(f"API error: {e.message}")
412
+ print(f"Status code: {e.status_code}")
413
+ ```
414
+
415
+ ## Advanced Usage
416
+
417
+ ### Pagination
418
+
419
+ ```python
420
+ # Manual pagination
421
+ page = 1
422
+ page_size = 20
423
+ all_datasets = []
424
+
425
+ while True:
426
+ results = client.datasets.search(
427
+ query="health",
428
+ page=page,
429
+ page_size=page_size
430
+ )
431
+
432
+ all_datasets.extend(results['results'])
433
+
434
+ if len(results['results']) < page_size:
435
+ break
436
+
437
+ page += 1
438
+
439
+ print(f"Total datasets fetched: {len(all_datasets)}")
440
+ ```
441
+
442
+ ### Working with Multiple Organizations
443
+
444
+ ```python
445
+ # Get user's organizations
446
+ user_info = client.get_user_info()
447
+
448
+ for org in user_info['organizations']:
449
+ print(f"\nOrganization: {org['name']} (Role: {org['role']})")
450
+
451
+ # Get resources for each organization
452
+ datasets = client.datasets.get_organization_datasets(org['id'])
453
+ models = client.aimodels.get_organization_models(org['id'])
454
+ usecases = client.usecases.get_organization_usecases(org['id'])
455
+
456
+ print(f" Datasets: {len(datasets)}")
457
+ print(f" AI Models: {len(models)}")
458
+ print(f" Use Cases: {len(usecases)}")
459
+ ```
460
+
461
+ ### Combining Search Results
462
+
463
+ ```python
464
+ # Search across all resource types
465
+ query = "health"
466
+
467
+ datasets = client.datasets.search(query=query, page_size=5)
468
+ models = client.aimodels.search(query=query, page_size=5)
469
+ usecases = client.usecases.search(query=query, page_size=5)
470
+
471
+ print(f"Found {datasets['total']} datasets")
472
+ print(f"Found {models['total']} AI models")
473
+ print(f"Found {usecases['total']} use cases")
474
+ ```
475
+
476
+ ## API Reference
477
+
478
+ ### DataSpaceClient
479
+
480
+ Main client for interacting with DataSpace API.
481
+
482
+ **Methods:**
483
+
484
+ - `login(username: str, password: str) -> dict`: Login with username and password
485
+ - `login_with_token(keycloak_token: str) -> dict`: Login with Keycloak token
486
+ - `login_as_service_account() -> dict`: Login as service account (client credentials)
487
+ - `refresh_token() -> str`: Refresh access token
488
+ - `get_user_info() -> dict`: Get current user information
489
+ - `is_authenticated() -> bool`: Check authentication status
490
+
491
+ **Properties:**
492
+
493
+ - `datasets`: DatasetClient instance
494
+ - `aimodels`: AIModelClient instance
495
+ - `usecases`: UseCaseClient instance
496
+ - `user`: Current user information
497
+ - `access_token`: Current access token
498
+
499
+ ### DatasetClient
500
+
501
+ Client for dataset operations.
502
+
503
+ **Methods:**
504
+
505
+ - `search(...)`: Search datasets with filters
506
+ - `get_by_id(dataset_id: str)`: Get dataset by UUID (GraphQL)
507
+ - `list_all(...)`: List all datasets with pagination
508
+ - `get_trending(limit: int)`: Get trending datasets
509
+ - `get_organization_datasets(organization_id: str, ...)`: Get organization's datasets
510
+ - `get_resources(dataset_id: str)`: Get dataset resources
511
+ - `list_by_organization(organization_id: str, ...)`: List datasets by organization
512
+
513
+ ### AIModelClient
514
+
515
+ Client for AI model operations.
516
+
517
+ **Methods:**
518
+
519
+ - `search(...)`: Search AI models with filters
520
+ - `get_by_id(model_id: str)`: Get AI model by UUID (REST)
521
+ - `get_by_id_graphql(model_id: str)`: Get AI model by UUID (GraphQL)
522
+ - `call_model(model_id: str, input_text: str, parameters: dict)`: Call an AI model
523
+ - `call_model_async(model_id: str, input_text: str, parameters: dict)`: Call an AI model asynchronously
524
+ - `list_all(...)`: List all AI models with pagination
525
+ - `get_organization_models(organization_id: str, ...)`: Get organization's AI models
526
+ - `create(data: dict)`: Create a new AI model
527
+ - `update(model_id: str, data: dict)`: Update an AI model
528
+ - `delete_model(model_id: str)`: Delete an AI model
529
+
530
+ ### UseCaseClient
531
+
532
+ Client for use case operations.
533
+
534
+ **Methods:**
535
+
536
+ - `search(...)`: Search use cases with filters
537
+ - `get_by_id(usecase_id: int)`: Get use case by ID (GraphQL)
538
+ - `list_all(...)`: List all use cases with pagination
539
+ - `get_organization_usecases(organization_id: str, ...)`: Get organization's use cases
540
+
541
+ ## Contributing
542
+
543
+ Contributions are welcome! Please feel free to submit a Pull Request.
544
+
545
+ ## License
546
+
547
+ AGPL-3.0 License
548
+
549
+ ## Support
550
+
551
+ For issues and questions, please open an issue on [GitHub](https://github.com/CivicDataLab/DataExchange/issues).
@@ -0,0 +1,15 @@
1
+ dataspace_sdk/__init__.py,sha256=5PPYEbMxDxzgzmsMgKhFwJM7-EA8KlY0TiKwxTDfqeg,472
2
+ dataspace_sdk/__version__.py,sha256=zQeRu19tySFHvGYzcXDbgLlJej9N5Hl9TnvbcVBqo7w,68
3
+ dataspace_sdk/auth.py,sha256=_Vo_oNCylzgac_YuKxeV6OapgWrSnVkBgSaA057zXbU,16814
4
+ dataspace_sdk/base.py,sha256=YlUG3HwdvWzfIeQ7EfKSvHI909GoK_H88Gpg3xWCYoM,5424
5
+ dataspace_sdk/client.py,sha256=pe-hpRbFv1pyi_9GCehD4QJenTk03bN8C-QnjHlrXxs,6838
6
+ dataspace_sdk/exceptions.py,sha256=HRai-3cthqJKGnjKsZgEqzLSW_l--YSKzNZ_fhC1CyY,806
7
+ dataspace_sdk/resources/__init__.py,sha256=jrsHn2_e5ARBGFasefkJ2_vbYRskDHu-dbUMkb2IkX8,356
8
+ dataspace_sdk/resources/aimodels.py,sha256=OnzzA8KOzXVbk4UwUj7fEZdf4Wl8mrUo9KeKsL4TKh8,33029
9
+ dataspace_sdk/resources/datasets.py,sha256=BZiA0C1P3-SuBibEaCyLPekxIksab0owH6QcXZEI_mE,6491
10
+ dataspace_sdk/resources/sectors.py,sha256=6V3Q3Uiv6ZLxt0PFqzl9KjAb1JoWXpQ122tzQAwdV-A,3706
11
+ dataspace_sdk/resources/usecases.py,sha256=GuKpUpX2ieQb09tTfzQy52tPS0KaGk5p4JGbFF4zsas,7031
12
+ dataspace_sdk-0.4.2.dist-info/METADATA,sha256=1QZRpP3HNKZsepTJg2zPoia7hgHj0Q8uY8YVhXz_7Ts,14016
13
+ dataspace_sdk-0.4.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
14
+ dataspace_sdk-0.4.2.dist-info/top_level.txt,sha256=xtmbzqBecwKo420WOtSKjiNYe74TPVVhVuRDHDzMrXI,14
15
+ dataspace_sdk-0.4.2.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.9.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1 @@
1
+ dataspace_sdk