das-cli 1.2.22__tar.gz → 1.2.26__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.2.22/das_cli.egg-info → das_cli-1.2.26}/PKG-INFO +85 -1
  2. {das_cli-1.2.22 → das_cli-1.2.26}/README.md +84 -0
  3. {das_cli-1.2.22 → das_cli-1.2.26}/das/managers/entries_manager.py +72 -29
  4. {das_cli-1.2.22 → das_cli-1.2.26/das_cli.egg-info}/PKG-INFO +85 -1
  5. {das_cli-1.2.22 → das_cli-1.2.26}/pyproject.toml +1 -1
  6. {das_cli-1.2.22 → das_cli-1.2.26}/LICENSE +0 -0
  7. {das_cli-1.2.22 → das_cli-1.2.26}/MANIFEST.in +0 -0
  8. {das_cli-1.2.22 → das_cli-1.2.26}/das/__init__.py +0 -0
  9. {das_cli-1.2.22 → das_cli-1.2.26}/das/ai/plugins/dasai.py +0 -0
  10. {das_cli-1.2.22 → das_cli-1.2.26}/das/ai/plugins/entries/entries_plugin.py +0 -0
  11. {das_cli-1.2.22 → das_cli-1.2.26}/das/app.py +0 -0
  12. {das_cli-1.2.22 → das_cli-1.2.26}/das/authentication/auth.py +0 -0
  13. {das_cli-1.2.22 → das_cli-1.2.26}/das/authentication/secure_input.py +0 -0
  14. {das_cli-1.2.22 → das_cli-1.2.26}/das/cli.py +0 -0
  15. {das_cli-1.2.22 → das_cli-1.2.26}/das/common/api.py +0 -0
  16. {das_cli-1.2.22 → das_cli-1.2.26}/das/common/config.py +0 -0
  17. {das_cli-1.2.22 → das_cli-1.2.26}/das/common/entry_fields_constants.py +0 -0
  18. {das_cli-1.2.22 → das_cli-1.2.26}/das/common/enums.py +0 -0
  19. {das_cli-1.2.22 → das_cli-1.2.26}/das/common/file_utils.py +0 -0
  20. {das_cli-1.2.22 → das_cli-1.2.26}/das/managers/__init__.py +0 -0
  21. {das_cli-1.2.22 → das_cli-1.2.26}/das/managers/digital_objects_manager.py +0 -0
  22. {das_cli-1.2.22 → das_cli-1.2.26}/das/managers/download_manager.py +0 -0
  23. {das_cli-1.2.22 → das_cli-1.2.26}/das/managers/search_manager.py +0 -0
  24. {das_cli-1.2.22 → das_cli-1.2.26}/das/services/attributes.py +0 -0
  25. {das_cli-1.2.22 → das_cli-1.2.26}/das/services/cache.py +0 -0
  26. {das_cli-1.2.22 → das_cli-1.2.26}/das/services/digital_objects.py +0 -0
  27. {das_cli-1.2.22 → das_cli-1.2.26}/das/services/downloads.py +0 -0
  28. {das_cli-1.2.22 → das_cli-1.2.26}/das/services/entries.py +0 -0
  29. {das_cli-1.2.22 → das_cli-1.2.26}/das/services/entry_fields.py +0 -0
  30. {das_cli-1.2.22 → das_cli-1.2.26}/das/services/hangfire.py +0 -0
  31. {das_cli-1.2.22 → das_cli-1.2.26}/das/services/search.py +0 -0
  32. {das_cli-1.2.22 → das_cli-1.2.26}/das/services/users.py +0 -0
  33. {das_cli-1.2.22 → das_cli-1.2.26}/das_cli.egg-info/SOURCES.txt +0 -0
  34. {das_cli-1.2.22 → das_cli-1.2.26}/das_cli.egg-info/dependency_links.txt +0 -0
  35. {das_cli-1.2.22 → das_cli-1.2.26}/das_cli.egg-info/entry_points.txt +0 -0
  36. {das_cli-1.2.22 → das_cli-1.2.26}/das_cli.egg-info/requires.txt +0 -0
  37. {das_cli-1.2.22 → das_cli-1.2.26}/das_cli.egg-info/top_level.txt +0 -0
  38. {das_cli-1.2.22 → das_cli-1.2.26}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: das-cli
3
- Version: 1.2.22
3
+ Version: 1.2.26
4
4
  Summary: DAS api client.
5
5
  Author: Royal Netherlands Institute for Sea Research
6
6
  License-Expression: MIT
@@ -74,6 +74,14 @@ cd das-cli
74
74
  pip install -e .
75
75
  ```
76
76
 
77
+ ### Upgrade
78
+
79
+ To upgrade to the latest version of das-cli:
80
+
81
+ ```bash
82
+ pip install --upgrade das-cli
83
+ ```
84
+
77
85
  ## CLI Usage
78
86
 
79
87
  The package installs a `das` executable for interacting with the DAS API.
@@ -261,6 +269,41 @@ das ai logout [--force]
261
269
 
262
270
  The DAS CLI provides three layers of interaction: CLI commands, Manager layer, and Service layer. Below are examples for each command showing usage at all three layers.
263
271
 
272
+ ### Login
273
+
274
+ Before using the Python API (e.g. `EntryManager`, `SearchManager`, `DownloadManager`), you must authenticate. The managers read the API URL and token from the stored configuration.
275
+
276
+ **Option 1 – Login via CLI first (recommended):**
277
+
278
+ ```bash
279
+ das login --api-url https://your-das-instance/api --username your_username --password your_password
280
+ # Or omit --username/--password to be prompted securely
281
+ ```
282
+
283
+ Then in Python:
284
+
285
+ ```python
286
+ from das.managers.entries_manager import EntryManager
287
+
288
+ entry_manager = EntryManager()
289
+ entry = entry_manager.get(code="7b.b.4c")
290
+ ```
291
+
292
+ **Option 2 – Login programmatically with `Das`:**
293
+
294
+ ```python
295
+ from das.app import Das
296
+ from das.managers.entries_manager import EntryManager
297
+
298
+ # Authenticate and store credentials
299
+ client = Das("https://your-das-instance/api")
300
+ client.authenticate("your_username", "your_password")
301
+
302
+ # Now EntryManager (and other managers) can use the stored config
303
+ entry_manager = EntryManager()
304
+ entry = entry_manager.get(code="7b.b.4c")
305
+ ```
306
+
264
307
  ### Entries
265
308
 
266
309
  #### Get Entry
@@ -960,6 +1003,47 @@ das config ssl-verify false
960
1003
  das config ssl-status
961
1004
  ```
962
1005
 
1006
+ ### Environment variables
1007
+
1008
+ You can use a `.env` file in the project root (or current directory) for local configuration. Copy `.env.example` to `.env` and fill in the values:
1009
+
1010
+ ```bash
1011
+ cp .env.example .env
1012
+ ```
1013
+
1014
+ Example `.env` (based on `.env.example`):
1015
+
1016
+ ```env
1017
+ # DAS API credentials (used by tests and scripts; CLI uses `das login` for interactive use)
1018
+ USER_NAME=
1019
+ USER_PASSWORD=
1020
+
1021
+ # DAS API base URL (e.g. https://api.das-dev.nioz.nl or https://localhost:44301)
1022
+ API_URL=
1023
+
1024
+ # PyPI/Twine credentials for publishing packages (deploy.ps1, etc.)
1025
+ TWINE_USERNAME=__token__
1026
+ TWINE_PASSWORD=
1027
+
1028
+ # Enable or disable SSL certificate verification (True/False). Overrides config when set.
1029
+ VERIFY_SSL=
1030
+
1031
+ # OpenAI model ID for the AI feature (e.g. gpt-4, gpt-4o-mini). Used by `das ai enable`.
1032
+ OPEN_AI_MODEL_ID=
1033
+ ```
1034
+
1035
+ | Variable | Description |
1036
+ |----------|-------------|
1037
+ | `USER_NAME` | DAS username. Used by tests and scripts for authentication. The CLI typically uses `das login` instead. |
1038
+ | `USER_PASSWORD` | DAS password. Used by tests and scripts. Never commit this to version control. |
1039
+ | `API_URL` | DAS API base URL (e.g. `https://api.das-dev.nioz.nl` or `https://localhost:44301`). Used by tests, scripts, and when no URL is stored via `das login`. |
1040
+ | `TWINE_USERNAME` | PyPI/Twine username. Use `__token__` when publishing with an API token. |
1041
+ | `TWINE_PASSWORD` | PyPI/Twine password or API token. Used by `deploy.ps1` when publishing packages. |
1042
+ | `VERIFY_SSL` | Set to `True` or `False` to control SSL certificate verification. Overrides the value from `das config ssl-verify` when set. |
1043
+ | `OPEN_AI_MODEL_ID` | OpenAI model ID (e.g. `gpt-4`, `gpt-4o-mini`). Used by the AI feature (`das ai enable`). |
1044
+
1045
+ **Note:** The `.env` file is gitignored. Do not commit credentials.
1046
+
963
1047
  ## Downloads
964
1048
 
965
1049
  ```bash
@@ -51,6 +51,14 @@ cd das-cli
51
51
  pip install -e .
52
52
  ```
53
53
 
54
+ ### Upgrade
55
+
56
+ To upgrade to the latest version of das-cli:
57
+
58
+ ```bash
59
+ pip install --upgrade das-cli
60
+ ```
61
+
54
62
  ## CLI Usage
55
63
 
56
64
  The package installs a `das` executable for interacting with the DAS API.
@@ -238,6 +246,41 @@ das ai logout [--force]
238
246
 
239
247
  The DAS CLI provides three layers of interaction: CLI commands, Manager layer, and Service layer. Below are examples for each command showing usage at all three layers.
240
248
 
249
+ ### Login
250
+
251
+ Before using the Python API (e.g. `EntryManager`, `SearchManager`, `DownloadManager`), you must authenticate. The managers read the API URL and token from the stored configuration.
252
+
253
+ **Option 1 – Login via CLI first (recommended):**
254
+
255
+ ```bash
256
+ das login --api-url https://your-das-instance/api --username your_username --password your_password
257
+ # Or omit --username/--password to be prompted securely
258
+ ```
259
+
260
+ Then in Python:
261
+
262
+ ```python
263
+ from das.managers.entries_manager import EntryManager
264
+
265
+ entry_manager = EntryManager()
266
+ entry = entry_manager.get(code="7b.b.4c")
267
+ ```
268
+
269
+ **Option 2 – Login programmatically with `Das`:**
270
+
271
+ ```python
272
+ from das.app import Das
273
+ from das.managers.entries_manager import EntryManager
274
+
275
+ # Authenticate and store credentials
276
+ client = Das("https://your-das-instance/api")
277
+ client.authenticate("your_username", "your_password")
278
+
279
+ # Now EntryManager (and other managers) can use the stored config
280
+ entry_manager = EntryManager()
281
+ entry = entry_manager.get(code="7b.b.4c")
282
+ ```
283
+
241
284
  ### Entries
242
285
 
243
286
  #### Get Entry
@@ -937,6 +980,47 @@ das config ssl-verify false
937
980
  das config ssl-status
938
981
  ```
939
982
 
983
+ ### Environment variables
984
+
985
+ You can use a `.env` file in the project root (or current directory) for local configuration. Copy `.env.example` to `.env` and fill in the values:
986
+
987
+ ```bash
988
+ cp .env.example .env
989
+ ```
990
+
991
+ Example `.env` (based on `.env.example`):
992
+
993
+ ```env
994
+ # DAS API credentials (used by tests and scripts; CLI uses `das login` for interactive use)
995
+ USER_NAME=
996
+ USER_PASSWORD=
997
+
998
+ # DAS API base URL (e.g. https://api.das-dev.nioz.nl or https://localhost:44301)
999
+ API_URL=
1000
+
1001
+ # PyPI/Twine credentials for publishing packages (deploy.ps1, etc.)
1002
+ TWINE_USERNAME=__token__
1003
+ TWINE_PASSWORD=
1004
+
1005
+ # Enable or disable SSL certificate verification (True/False). Overrides config when set.
1006
+ VERIFY_SSL=
1007
+
1008
+ # OpenAI model ID for the AI feature (e.g. gpt-4, gpt-4o-mini). Used by `das ai enable`.
1009
+ OPEN_AI_MODEL_ID=
1010
+ ```
1011
+
1012
+ | Variable | Description |
1013
+ |----------|-------------|
1014
+ | `USER_NAME` | DAS username. Used by tests and scripts for authentication. The CLI typically uses `das login` instead. |
1015
+ | `USER_PASSWORD` | DAS password. Used by tests and scripts. Never commit this to version control. |
1016
+ | `API_URL` | DAS API base URL (e.g. `https://api.das-dev.nioz.nl` or `https://localhost:44301`). Used by tests, scripts, and when no URL is stored via `das login`. |
1017
+ | `TWINE_USERNAME` | PyPI/Twine username. Use `__token__` when publishing with an API token. |
1018
+ | `TWINE_PASSWORD` | PyPI/Twine password or API token. Used by `deploy.ps1` when publishing packages. |
1019
+ | `VERIFY_SSL` | Set to `True` or `False` to control SSL certificate verification. Overrides the value from `das config ssl-verify` when set. |
1020
+ | `OPEN_AI_MODEL_ID` | OpenAI model ID (e.g. `gpt-4`, `gpt-4o-mini`). Used by the AI feature (`das ai enable`). |
1021
+
1022
+ **Note:** The `.env` file is gitignored. Do not commit credentials.
1023
+
940
1024
  ## Downloads
941
1025
 
942
1026
  ```bash
@@ -350,59 +350,102 @@ class EntryManager:
350
350
  else:
351
351
  return source
352
352
 
353
- def __get_select_combobox_field_value(self, field, source: str) -> str:
353
+ def __get_select_combobox_field_value(self, field, source: str | list | dict) -> str | list | dict:
354
354
  """Helper method to get select combobox field value."""
355
355
 
356
356
  if not source:
357
357
  return None
358
358
 
359
+ # if is a dict return source as is
360
+ if isinstance(source, dict):
361
+ return source
362
+ elif isinstance(source, list):
363
+ return source
364
+
359
365
  attribute_id = -1
360
366
 
367
+ # convert all keys to lowercase
368
+ field = {str(k).lower(): v for k, v in field.items()}
369
+
361
370
  if field.get('column').isdigit():
362
371
  attribute_id = int(field.get('column'))
363
372
  elif field.get('column')[0].isalpha() and field.get('column')[1:].isdigit():
364
373
  attribute_id = int(field.get('column')[1:])
365
374
 
366
- if attribute_id == -1:
367
- # then we need to check if the field has the property customdata
368
- if not field.get('customdata', None) is None:
369
- try:
370
- customdata = json.loads(field.get('customdata'))
371
- if (customdata is not None and isinstance(customdata, dict) and "datasource" in customdata):
372
- datasource = customdata.get("datasource")
373
- if (datasource is not None and isinstance(datasource, dict) and "attributeid" in datasource):
375
+ customdata = None
376
+ is_multiselect = False
377
+
378
+ if not field.get('customdata', None) is None and field.get('customdata') != "":
379
+ try:
380
+ customdata_string = field.get('customdata').lower()
381
+ customdata = json.loads(customdata_string)
382
+ if (customdata is not None and isinstance(customdata, dict) and "datasource" in customdata):
383
+ datasource = customdata.get("datasource")
384
+ if datasource is not None and isinstance(datasource, dict):
385
+ if "attributeid" in datasource:
374
386
  attribute_id = datasource.get("attributeid")
375
- except json.JSONDecodeError:
376
- raise ValueError(f"Invalid customdata JSON: {field.get('customdata')}")
387
+ if "ismultiselect" in datasource:
388
+ is_multiselect = datasource.get("ismultiselect")
389
+ except json.JSONDecodeError:
390
+ raise ValueError(f"Invalid customdata JSON: {field.get('customdata')}")
391
+
392
+ expected_max_result_count = 1
393
+ if is_multiselect:
394
+ expected_max_result_count = len(source.split(','))
377
395
 
378
396
  search_params = {
379
397
  "attributeId": attribute_id,
380
- "queryString": f"displayname({source}) or code({source});",
381
- "maxResultCount": 1,
398
+ "queryString": self.__get_query_string(source, is_multiselect),
399
+ "maxResultCount": expected_max_result_count,
382
400
  "skipCount": 0
383
401
  }
384
-
385
- # checks if source is GUID, if so, than we search by id
386
- if self.is_guid(source):
387
- search_params['queryString'] = f"id({source});"
388
402
 
389
403
  search_response = self.search_service.search_entries(**search_params)
390
404
 
391
405
  if search_response.get('totalCount', 0) == 0:
392
406
  raise ValueError(f"No results found for {field.get('displayName')}: {source}. Attribute ID: {attribute_id}")
393
-
407
+ result_list = []
394
408
  if search_response and 'items' in search_response and len(search_response['items']) > 0:
395
- result = {}
396
- result['id'] = search_response['items'][0].get('entry', {}).get('id')
397
- result['name'] = search_response['items'][0].get('entry', {}).get('displayname')
398
- result['code'] = search_response['items'][0].get('entry', {}).get('code')
399
- result['alias'] = search_response['items'][0].get('entry', {}).get('alias', None)
400
- result['attributeid'] = attribute_id
401
- # Filter out None values from the result dictionary
402
- result = {k: v for k, v in result.items() if v is not None}
403
- return json.dumps([result])
404
- else:
405
- return source
409
+ for item in search_response['items']:
410
+ result = {}
411
+ result['id'] = item.get('entry', {}).get('id')
412
+ result['name'] = item.get('entry', {}).get('displayname')
413
+ result['code'] = item.get('entry', {}).get('code')
414
+ result['alias'] = item.get('entry', {}).get('alias', None)
415
+ result['attributeid'] = attribute_id
416
+ result = {k: v for k, v in result.items() if v is not None}
417
+ result_list.append(result)
418
+ return json.dumps(result_list)
419
+ else:
420
+ return source
421
+
422
+ def __get_query_string(self, source: str, is_multiselect: bool) -> str:
423
+
424
+ if not source:
425
+ return None
426
+
427
+ if not is_multiselect:
428
+ if self.is_guid(source):
429
+ return f"id({source});"
430
+ else:
431
+ return f"displayname({source}) or code({source});"
432
+ else:
433
+ values = source.split(',')
434
+ query_strings = []
435
+ for value in values:
436
+ if self.is_guid(value):
437
+ query_string = f"id({value}) "
438
+ else:
439
+ query_string = f"displayname({value}) or code({value}) "
440
+ query_strings.append(query_string)
441
+ return f"{' or '.join(query_strings)}"
442
+
443
+
444
+
445
+
446
+
447
+
448
+
406
449
 
407
450
  def is_guid(self, source: str) -> bool:
408
451
  """Helper method to check if a string is a GUID."""
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: das-cli
3
- Version: 1.2.22
3
+ Version: 1.2.26
4
4
  Summary: DAS api client.
5
5
  Author: Royal Netherlands Institute for Sea Research
6
6
  License-Expression: MIT
@@ -74,6 +74,14 @@ cd das-cli
74
74
  pip install -e .
75
75
  ```
76
76
 
77
+ ### Upgrade
78
+
79
+ To upgrade to the latest version of das-cli:
80
+
81
+ ```bash
82
+ pip install --upgrade das-cli
83
+ ```
84
+
77
85
  ## CLI Usage
78
86
 
79
87
  The package installs a `das` executable for interacting with the DAS API.
@@ -261,6 +269,41 @@ das ai logout [--force]
261
269
 
262
270
  The DAS CLI provides three layers of interaction: CLI commands, Manager layer, and Service layer. Below are examples for each command showing usage at all three layers.
263
271
 
272
+ ### Login
273
+
274
+ Before using the Python API (e.g. `EntryManager`, `SearchManager`, `DownloadManager`), you must authenticate. The managers read the API URL and token from the stored configuration.
275
+
276
+ **Option 1 – Login via CLI first (recommended):**
277
+
278
+ ```bash
279
+ das login --api-url https://your-das-instance/api --username your_username --password your_password
280
+ # Or omit --username/--password to be prompted securely
281
+ ```
282
+
283
+ Then in Python:
284
+
285
+ ```python
286
+ from das.managers.entries_manager import EntryManager
287
+
288
+ entry_manager = EntryManager()
289
+ entry = entry_manager.get(code="7b.b.4c")
290
+ ```
291
+
292
+ **Option 2 – Login programmatically with `Das`:**
293
+
294
+ ```python
295
+ from das.app import Das
296
+ from das.managers.entries_manager import EntryManager
297
+
298
+ # Authenticate and store credentials
299
+ client = Das("https://your-das-instance/api")
300
+ client.authenticate("your_username", "your_password")
301
+
302
+ # Now EntryManager (and other managers) can use the stored config
303
+ entry_manager = EntryManager()
304
+ entry = entry_manager.get(code="7b.b.4c")
305
+ ```
306
+
264
307
  ### Entries
265
308
 
266
309
  #### Get Entry
@@ -960,6 +1003,47 @@ das config ssl-verify false
960
1003
  das config ssl-status
961
1004
  ```
962
1005
 
1006
+ ### Environment variables
1007
+
1008
+ You can use a `.env` file in the project root (or current directory) for local configuration. Copy `.env.example` to `.env` and fill in the values:
1009
+
1010
+ ```bash
1011
+ cp .env.example .env
1012
+ ```
1013
+
1014
+ Example `.env` (based on `.env.example`):
1015
+
1016
+ ```env
1017
+ # DAS API credentials (used by tests and scripts; CLI uses `das login` for interactive use)
1018
+ USER_NAME=
1019
+ USER_PASSWORD=
1020
+
1021
+ # DAS API base URL (e.g. https://api.das-dev.nioz.nl or https://localhost:44301)
1022
+ API_URL=
1023
+
1024
+ # PyPI/Twine credentials for publishing packages (deploy.ps1, etc.)
1025
+ TWINE_USERNAME=__token__
1026
+ TWINE_PASSWORD=
1027
+
1028
+ # Enable or disable SSL certificate verification (True/False). Overrides config when set.
1029
+ VERIFY_SSL=
1030
+
1031
+ # OpenAI model ID for the AI feature (e.g. gpt-4, gpt-4o-mini). Used by `das ai enable`.
1032
+ OPEN_AI_MODEL_ID=
1033
+ ```
1034
+
1035
+ | Variable | Description |
1036
+ |----------|-------------|
1037
+ | `USER_NAME` | DAS username. Used by tests and scripts for authentication. The CLI typically uses `das login` instead. |
1038
+ | `USER_PASSWORD` | DAS password. Used by tests and scripts. Never commit this to version control. |
1039
+ | `API_URL` | DAS API base URL (e.g. `https://api.das-dev.nioz.nl` or `https://localhost:44301`). Used by tests, scripts, and when no URL is stored via `das login`. |
1040
+ | `TWINE_USERNAME` | PyPI/Twine username. Use `__token__` when publishing with an API token. |
1041
+ | `TWINE_PASSWORD` | PyPI/Twine password or API token. Used by `deploy.ps1` when publishing packages. |
1042
+ | `VERIFY_SSL` | Set to `True` or `False` to control SSL certificate verification. Overrides the value from `das config ssl-verify` when set. |
1043
+ | `OPEN_AI_MODEL_ID` | OpenAI model ID (e.g. `gpt-4`, `gpt-4o-mini`). Used by the AI feature (`das ai enable`). |
1044
+
1045
+ **Note:** The `.env` file is gitignored. Do not commit credentials.
1046
+
963
1047
  ## Downloads
964
1048
 
965
1049
  ```bash
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "das-cli"
7
- version = "1.2.22"
7
+ version = "1.2.26"
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
File without changes