das-cli 1.0.12__tar.gz → 1.0.15__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 (38) hide show
  1. {das_cli-1.0.12/das_cli.egg-info → das_cli-1.0.15}/PKG-INFO +31 -1
  2. {das_cli-1.0.12 → das_cli-1.0.15}/README.md +30 -0
  3. {das_cli-1.0.12 → das_cli-1.0.15}/das/cli.py +41 -0
  4. das_cli-1.0.15/das/managers/digital_objects_manager.py +46 -0
  5. das_cli-1.0.15/das/services/digital_objects.py +44 -0
  6. {das_cli-1.0.12 → das_cli-1.0.15/das_cli.egg-info}/PKG-INFO +31 -1
  7. {das_cli-1.0.12 → das_cli-1.0.15}/das_cli.egg-info/SOURCES.txt +2 -0
  8. {das_cli-1.0.12 → das_cli-1.0.15}/pyproject.toml +1 -1
  9. {das_cli-1.0.12 → das_cli-1.0.15}/LICENSE +0 -0
  10. {das_cli-1.0.12 → das_cli-1.0.15}/MANIFEST.in +0 -0
  11. {das_cli-1.0.12 → das_cli-1.0.15}/das/__init__.py +0 -0
  12. {das_cli-1.0.12 → das_cli-1.0.15}/das/ai/plugins/dasai.py +0 -0
  13. {das_cli-1.0.12 → das_cli-1.0.15}/das/ai/plugins/entries/entries_plugin.py +0 -0
  14. {das_cli-1.0.12 → das_cli-1.0.15}/das/app.py +0 -0
  15. {das_cli-1.0.12 → das_cli-1.0.15}/das/authentication/auth.py +0 -0
  16. {das_cli-1.0.12 → das_cli-1.0.15}/das/authentication/secure_input.py +0 -0
  17. {das_cli-1.0.12 → das_cli-1.0.15}/das/common/api.py +0 -0
  18. {das_cli-1.0.12 → das_cli-1.0.15}/das/common/config.py +0 -0
  19. {das_cli-1.0.12 → das_cli-1.0.15}/das/common/entry_fields_constants.py +0 -0
  20. {das_cli-1.0.12 → das_cli-1.0.15}/das/common/enums.py +0 -0
  21. {das_cli-1.0.12 → das_cli-1.0.15}/das/common/file_utils.py +0 -0
  22. {das_cli-1.0.12 → das_cli-1.0.15}/das/managers/__init__.py +0 -0
  23. {das_cli-1.0.12 → das_cli-1.0.15}/das/managers/download_manager.py +0 -0
  24. {das_cli-1.0.12 → das_cli-1.0.15}/das/managers/entries_manager.py +0 -0
  25. {das_cli-1.0.12 → das_cli-1.0.15}/das/managers/search_manager.py +0 -0
  26. {das_cli-1.0.12 → das_cli-1.0.15}/das/services/attributes.py +0 -0
  27. {das_cli-1.0.12 → das_cli-1.0.15}/das/services/cache.py +0 -0
  28. {das_cli-1.0.12 → das_cli-1.0.15}/das/services/downloads.py +0 -0
  29. {das_cli-1.0.12 → das_cli-1.0.15}/das/services/entries.py +0 -0
  30. {das_cli-1.0.12 → das_cli-1.0.15}/das/services/entry_fields.py +0 -0
  31. {das_cli-1.0.12 → das_cli-1.0.15}/das/services/hangfire.py +0 -0
  32. {das_cli-1.0.12 → das_cli-1.0.15}/das/services/search.py +0 -0
  33. {das_cli-1.0.12 → das_cli-1.0.15}/das/services/users.py +0 -0
  34. {das_cli-1.0.12 → das_cli-1.0.15}/das_cli.egg-info/dependency_links.txt +0 -0
  35. {das_cli-1.0.12 → das_cli-1.0.15}/das_cli.egg-info/entry_points.txt +0 -0
  36. {das_cli-1.0.12 → das_cli-1.0.15}/das_cli.egg-info/requires.txt +0 -0
  37. {das_cli-1.0.12 → das_cli-1.0.15}/das_cli.egg-info/top_level.txt +0 -0
  38. {das_cli-1.0.12 → das_cli-1.0.15}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: das-cli
3
- Version: 1.0.12
3
+ Version: 1.0.15
4
4
  Summary: DAS api client.
5
5
  Author: Royal Netherlands Institute for Sea Research
6
6
  License-Expression: MIT
@@ -166,6 +166,23 @@ das entry update --attribute <AttributeName> [--code CODE] <file_path>
166
166
  # das entry update --attribute core --data [{ 'Code': 'ENT001' }, { 'Code': 'ENT002' }]
167
167
  ```
168
168
 
169
+ #### Link or unlink digital objects
170
+
171
+ ```bash
172
+ # Link digital objects by their codes to an entry
173
+ das entry link-digital-objects --entry-code ENT001 -d DO001 -d DO002
174
+
175
+ # Unlink digital objects from an entry
176
+ das entry link-digital-objects --entry-code ENT001 -d DO003 --unlink
177
+ ```
178
+
179
+ #### Change ownership
180
+
181
+ ```bash
182
+ # Transfer ownership of one or more entries to a user
183
+ das entry chown --user alice --code ENT001 --code ENT002
184
+ ```
185
+
169
186
  ### Hangfire
170
187
 
171
188
  ```bash
@@ -216,6 +233,19 @@ das config ssl-status
216
233
  das config reset --force
217
234
  ```
218
235
 
236
+ ### AI
237
+
238
+ ```bash
239
+ # Start interactive DAS AI session (prompts for OpenAI API key if needed)
240
+ das ai enable
241
+
242
+ # Clear saved OpenAI key and auth token
243
+ das ai clear [--force]
244
+
245
+ # Alias for `das ai clear`
246
+ das ai logout [--force]
247
+ ```
248
+
219
249
  ## Python API
220
250
 
221
251
  ### Basic Usage
@@ -143,6 +143,23 @@ das entry update --attribute <AttributeName> [--code CODE] <file_path>
143
143
  # das entry update --attribute core --data [{ 'Code': 'ENT001' }, { 'Code': 'ENT002' }]
144
144
  ```
145
145
 
146
+ #### Link or unlink digital objects
147
+
148
+ ```bash
149
+ # Link digital objects by their codes to an entry
150
+ das entry link-digital-objects --entry-code ENT001 -d DO001 -d DO002
151
+
152
+ # Unlink digital objects from an entry
153
+ das entry link-digital-objects --entry-code ENT001 -d DO003 --unlink
154
+ ```
155
+
156
+ #### Change ownership
157
+
158
+ ```bash
159
+ # Transfer ownership of one or more entries to a user
160
+ das entry chown --user alice --code ENT001 --code ENT002
161
+ ```
162
+
146
163
  ### Hangfire
147
164
 
148
165
  ```bash
@@ -193,6 +210,19 @@ das config ssl-status
193
210
  das config reset --force
194
211
  ```
195
212
 
213
+ ### AI
214
+
215
+ ```bash
216
+ # Start interactive DAS AI session (prompts for OpenAI API key if needed)
217
+ das ai enable
218
+
219
+ # Clear saved OpenAI key and auth token
220
+ das ai clear [--force]
221
+
222
+ # Alias for `das ai clear`
223
+ das ai logout [--force]
224
+ ```
225
+
196
226
  ## Python API
197
227
 
198
228
  ### Basic Usage
@@ -14,6 +14,7 @@ from das.app import Das
14
14
  from das.managers.download_manager import DownloadManager
15
15
  from das.managers.entries_manager import EntryManager
16
16
  from das.managers.search_manager import SearchManager
17
+ from das.managers.digital_objects_manager import DigitalObjectsManager
17
18
  from das.common.file_utils import load_file_based_on_extension, parse_data_string
18
19
  from das.ai.plugins.dasai import DasAI
19
20
 
@@ -51,6 +52,7 @@ class DasCLI:
51
52
  self.entry_manager = None
52
53
  self.search_manager = None
53
54
  self.download_manager = None
55
+ self.digital_objects_manager = None
54
56
  self.das_ai = None
55
57
 
56
58
  def get_client(self):
@@ -65,6 +67,7 @@ class DasCLI:
65
67
  self.entry_manager = EntryManager()
66
68
  self.search_manager = SearchManager()
67
69
  self.download_manager = DownloadManager()
70
+ self.digital_objects_manager = DigitalObjectsManager()
68
71
  # Set SSL verification based on saved config
69
72
  if not self.client:
70
73
  self.client = Das(self.api_url)
@@ -409,6 +412,44 @@ def delete_entry(das_ctx, code):
409
412
  except Exception as e:
410
413
  click.secho(f"Error: {e}", fg="red")
411
414
 
415
+ @entry.command("link-digital-objects")
416
+ @click.option('--entry-code', required=True, help='Entry code to link/unlink digital objects to')
417
+ @click.option('--digital-object-code', '-d', multiple=True, required=True, help='Digital object code. Use multiple times for multiple objects.')
418
+ @click.option('--unlink', is_flag=True, help='Unlink specified digital objects from the entry instead of linking')
419
+ @pass_das_context
420
+ def link_digital_objects(das_ctx, entry_code, digital_object_code, unlink):
421
+ """Link or unlink existing digital objects to an entry by their codes.
422
+
423
+ Examples:
424
+
425
+ \b
426
+ # Link two digital objects to an entry
427
+ das entry link-digital-objects --entry-code ENT001 -d DO001 -d DO002
428
+
429
+ \b
430
+ # Unlink a digital object from an entry
431
+ das entry link-digital-objects --entry-code ENT001 -d DO003 --unlink
432
+ """
433
+ try:
434
+ das_ctx.get_client()
435
+ codes = list(digital_object_code)
436
+ if not codes:
437
+ raise click.UsageError("Please provide at least one --digital-object-code")
438
+
439
+ success = das_ctx.digital_objects_manager.link_existing_digital_objects(
440
+ entry_code=entry_code,
441
+ digital_object_code_list=codes,
442
+ is_unlink=unlink,
443
+ )
444
+
445
+ if success:
446
+ action = "unlinked" if unlink else "linked"
447
+ click.secho(f"✓ Successfully {action} {len(codes)} digital object(s) for entry '{entry_code}'", fg="green")
448
+ else:
449
+ click.secho("Operation did not report success.", fg="yellow")
450
+ except Exception as e:
451
+ click.secho(f"Error: {e}", fg="red")
452
+
412
453
  @entry.command("create")
413
454
  @click.option('--attribute', required=True, help='Attribute name')
414
455
  @click.argument('file_path', required=False)
@@ -0,0 +1,46 @@
1
+ from das.common.config import load_api_url
2
+ from das.services.entries import EntriesService
3
+ from das.services.digital_objects import DigitalObjectsService
4
+
5
+
6
+ class DigitalObjectsManager:
7
+ def __init__(self):
8
+ base_url = load_api_url()
9
+ if base_url is None or base_url == "":
10
+ raise ValueError(f"Base URL is required - {self.__class__.__name__}")
11
+
12
+ self.digital_objects_service = DigitalObjectsService(base_url)
13
+ self.entry_service = EntriesService(base_url)
14
+
15
+ def link_existing_digital_objects(
16
+ self, entry_code: str, digital_object_code_list: list[str], is_unlink: bool = False
17
+ ) -> bool:
18
+ """Attach or detach (unlink) digital objects to an entry using codes."""
19
+ entry_response = self.entry_service.get_entry(entry_code)
20
+
21
+ if entry_response is None:
22
+ raise ValueError(f"Entry with code '{entry_code}' not found")
23
+
24
+ entry_payload = entry_response.get("entry")
25
+ if entry_payload is None:
26
+ raise ValueError(f"Entry with code '{entry_code}' not found")
27
+
28
+ digital_object_id_list: list[str] = []
29
+
30
+ for code in digital_object_code_list:
31
+ do_response = self.entry_service.get_entry(code)
32
+ do_entry = do_response.get("entry") if do_response else None
33
+ if do_entry is None:
34
+ raise ValueError(f"Digital object with code '{code}' not found")
35
+ digital_object_id_list.append(do_entry.get("id"))
36
+
37
+ result = self.digital_objects_service.link_existing_digital_objects(
38
+ attribute_id=entry_response.get("attributeId"),
39
+ entry_id=entry_payload.get("id"),
40
+ digital_object_id_list=digital_object_id_list,
41
+ is_unlink=is_unlink,
42
+ )
43
+
44
+ return result
45
+
46
+
@@ -0,0 +1,44 @@
1
+ from das.common.api import post_data
2
+ from das.common.config import load_token
3
+
4
+
5
+ class DigitalObjectsService:
6
+ def __init__(self, base_url):
7
+ self.base_url = f"{base_url}/api/services/app/DigitalObject"
8
+
9
+ def link_existing_digital_objects(self, attribute_id: int, entry_id: str, digital_object_id_list: list[str], is_unlink: bool = False):
10
+ """Link existing digital objects to an entry."""
11
+ token = load_token()
12
+
13
+ if token is None or token == "":
14
+ raise ValueError("Authorization token is required")
15
+
16
+ headers = {
17
+ "Authorization": f"Bearer {token}",
18
+ "Content-Type": "application/json",
19
+ }
20
+
21
+ payload = {
22
+ "attributeId": attribute_id,
23
+ "attributeValueId": entry_id,
24
+ "digitalObjects": [],
25
+ }
26
+
27
+ for digital_object_id in digital_object_id_list:
28
+ payload["digitalObjects"].append(
29
+ {
30
+ "attributeId": attribute_id,
31
+ "attributeValueId": entry_id,
32
+ "digitalObjectId": digital_object_id,
33
+ "isDeleted": is_unlink,
34
+ }
35
+ )
36
+
37
+ response = post_data(
38
+ f"{self.base_url}/LinkExistingDigitalObject", data=payload, headers=headers
39
+ )
40
+
41
+ return response.get("success")
42
+
43
+
44
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: das-cli
3
- Version: 1.0.12
3
+ Version: 1.0.15
4
4
  Summary: DAS api client.
5
5
  Author: Royal Netherlands Institute for Sea Research
6
6
  License-Expression: MIT
@@ -166,6 +166,23 @@ das entry update --attribute <AttributeName> [--code CODE] <file_path>
166
166
  # das entry update --attribute core --data [{ 'Code': 'ENT001' }, { 'Code': 'ENT002' }]
167
167
  ```
168
168
 
169
+ #### Link or unlink digital objects
170
+
171
+ ```bash
172
+ # Link digital objects by their codes to an entry
173
+ das entry link-digital-objects --entry-code ENT001 -d DO001 -d DO002
174
+
175
+ # Unlink digital objects from an entry
176
+ das entry link-digital-objects --entry-code ENT001 -d DO003 --unlink
177
+ ```
178
+
179
+ #### Change ownership
180
+
181
+ ```bash
182
+ # Transfer ownership of one or more entries to a user
183
+ das entry chown --user alice --code ENT001 --code ENT002
184
+ ```
185
+
169
186
  ### Hangfire
170
187
 
171
188
  ```bash
@@ -216,6 +233,19 @@ das config ssl-status
216
233
  das config reset --force
217
234
  ```
218
235
 
236
+ ### AI
237
+
238
+ ```bash
239
+ # Start interactive DAS AI session (prompts for OpenAI API key if needed)
240
+ das ai enable
241
+
242
+ # Clear saved OpenAI key and auth token
243
+ das ai clear [--force]
244
+
245
+ # Alias for `das ai clear`
246
+ das ai logout [--force]
247
+ ```
248
+
219
249
  ## Python API
220
250
 
221
251
  ### Basic Usage
@@ -16,11 +16,13 @@ das/common/entry_fields_constants.py
16
16
  das/common/enums.py
17
17
  das/common/file_utils.py
18
18
  das/managers/__init__.py
19
+ das/managers/digital_objects_manager.py
19
20
  das/managers/download_manager.py
20
21
  das/managers/entries_manager.py
21
22
  das/managers/search_manager.py
22
23
  das/services/attributes.py
23
24
  das/services/cache.py
25
+ das/services/digital_objects.py
24
26
  das/services/downloads.py
25
27
  das/services/entries.py
26
28
  das/services/entry_fields.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "das-cli"
7
- version = "1.0.12"
7
+ version = "1.0.15"
8
8
  authors = [
9
9
  { name="Royal Netherlands Institute for Sea Research" },
10
10
  ]
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes