Skip to main content

DAS api client.

Project description

DAS Python Client

A Python library and CLI for interacting with the Data Archive System (DAS) API.

Table of Contents

  • Quickstart
  • Installation
  • CLI Usage
  • Python API
  • Configuration
  • Examples
  • Troubleshooting
  • Development
  • Contributing
  • License

Quickstart

# Install
pip install das-cli

# Login (prompts for credentials if omitted)
das login --api-url https://your-das-instance/api

# Search entries
das search entries --attribute Name --query 'name(*core*)' --format table

# Get an entry
das entry get --code 7b.b.4c

Installation

Requirements

  • Python 3.13 or higher

Install from PyPI

pip install das-cli

Install from Source

git clone https://git.nioz.nl/ict-projects/das-cli.git
cd das-cli
pip install -e .

CLI Usage

The package installs a das executable for interacting with the DAS API.

Authentication

das login --api-url https://your-das-instance/api --username your_username --password your_password
  • Omit --username/--password to be prompted securely.

Search

das search entries --attribute <AttributeName> --query '<SearchQuery>' \
  --max-results 10 --page 1 --sort-by Name --sort-order asc --format table

Options:

  • --max-results <n>: Maximum results per page (default: 10)
  • --page <num>: Page number (default: 1)
  • --sort-by <field>: Field to sort by (default: Name)
  • --sort-order <order>: asc or desc (default: asc)
  • --format <format>: table, json, or compact (default: table)
  • --raw: Print raw API response

Get a specific entry by ID:

das search entry <ID> --format table

Help for query syntax:

das search help

Example queries:

  • Name contains pattern: name(*pattern*)
  • Multiple conditions: name(*pattern*);code(*ABC*)
  • Date comparison: Created at(>2023-01-01)

Entries

# Get entry by code
das entry get --code CODE

# Get entry by ID
das entry get --id ID

# Delete an entry
das entry delete --code CODE
# Or by ID
das entry delete --id ID
# Skip confirmation prompt
das entry delete --code CODE --force

# Create entries from file or data
das entry create --attribute <AttributeName> <file_path>
# Examples:
#   JSON file (can contain a list of entries)
#   das entry create --attribute core c:\data\entries.json
#   CSV file (rows become entries)
#   das entry create --attribute core c:\data\entries.csv
#   Excel file (rows become entries)
#   das entry create --attribute core c:\data\entries.xls
#   Single entry from data string
#   das entry create --attribute core --data { 'Name': 'Entry 1', ... }
#   Multiple entries from data string
#   das entry create --attribute core --data [{ 'Name': 'Entry 1' }, { 'Name': 'Entry 2' }]

# Update entries from file or data
das entry update --attribute <AttributeName> [--code CODE] <file_path>
# Notes:
# - For bulk updates, each entry must include a Code field
# - For single updates via --data, you can pass --code or include Code in data
# Examples:
#   JSON file (each object must include Code)
#   das entry update --attribute core c:\data\entries.json
#   CSV file (must have Code column)
#   das entry update --attribute core c:\data\entries.csv
#   Excel file (must have Code column)
#   das entry update --attribute core c:\data\entries.xls
#   Single entry with explicit code
#   das entry update --attribute core --code ENT001 --data { 'Grant Public Access': Yes }
#   Single entry with Code in data
#   das entry update --attribute core --data { 'Code': 'ENT001', 'Grant Public Access': Yes }
#   Multiple entries from data string (each must include Code)
#   das entry update --attribute core --data [{ 'Code': 'ENT001' }, { 'Code': 'ENT002' }]

Upload and link a digital object

# Upload a file as a digital object and link it to an entry
das entry upload-digital-object --entry-code ENT001 --type Dataset --description "CTD raw" c:\data\ctd.zip

Link or unlink digital objects

# Link digital objects by their codes to an entry
das entry link-digital-objects --entry-code ENT001 -d DO001 -d DO002

# Unlink digital objects from an entry
das entry link-digital-objects --entry-code ENT001 -d DO003 --unlink

Change ownership

# Transfer ownership of one or more entries to a user
das entry chown --user alice --code ENT001 --code ENT002

Hangfire

das hangfire sync-doi ID

Attributes

# By ID
das attribute get --id 123

# By name
das attribute get --name "temperature"

# By alias
das attribute get --alias "temp"

# By table name
das attribute get --table-name "measurements"

# Converters
das attribute get-name 123
das attribute get-id "temperature"

Cache

das cache list
das cache clear "cache-name"
das cache clear-all

Configuration

# Enable SSL certificate verification (recommended)
das config ssl-verify true

# Disable SSL certificate verification (development/testing only)
das config ssl-verify false

# Show current SSL verification status
das config ssl-status

# Reset all configuration (clears credentials and settings)
das config reset --force

AI

# Start interactive DAS AI session (prompts for OpenAI API key if needed)
das ai enable

# Clear saved OpenAI key and auth token
das ai clear [--force]

# Alias for `das ai clear`
das ai logout [--force]

Python API

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.

Entries

Get Entry

CLI:

# Get entry by code
das entry get --code 7b.b.4c

# Get entry by ID
das entry get --id 123

Manager Layer:

from das.managers.entries_manager import EntryManager

entry_manager = EntryManager()

# Get entry by code
entry = entry_manager.get(code="7b.b.4c")

# Get entry by ID
entry = entry_manager.get(id="123")

Service Layer:

from das.services.entries import EntriesService
from das.common.config import load_api_url

base_url = load_api_url()
entry_service = EntriesService(base_url)

# Get entry by code
entry = entry_service.get(code="7b.b.4c")

# Get entry by ID
entry = entry_service.get(id="123")

Create Entry

CLI:

# Create from JSON file
das entry create --attribute core c:\data\entries.json

# Create from CSV file
das entry create --attribute core c:\data\entries.csv

# Create single entry from data string
das entry create --attribute core --data "{ 'Name': 'Entry 1', 'Description': 'Test entry' }"

# Create multiple entries from data string
das entry create --attribute core --data "[{ 'Name': 'Entry 1' }, { 'Name': 'Entry 2' }]"

Manager Layer:

from das.managers.entries_manager import EntryManager

entry_manager = EntryManager()

# Create single entry
result = entry_manager.create(
    attribute="core",
    entry={"Name": "Entry 1", "Description": "Test entry"}
)

# Create multiple entries
results = entry_manager.create(
    attribute="core",
    entries=[
        {"Name": "Entry 1", "Description": "Test entry 1"},
        {"Name": "Entry 2", "Description": "Test entry 2"}
    ]
)

Service Layer:

from das.services.entries import EntriesService
from das.services.attributes import AttributesService
from das.common.config import load_api_url

base_url = load_api_url()
entry_service = EntriesService(base_url)
attribute_service = AttributesService(base_url)

# Get attribute ID first
attribute_id = attribute_service.get_id(name="core")

# Create entry
entry_id = entry_service.create(
    attribute_id=attribute_id,
    entry={"name": "Entry 1", "description": "Test entry"}
)

Update Entry

CLI:

# Update from JSON file
das entry update --attribute core c:\data\entries.json

# Update from CSV file
das entry update --attribute core c:\data\entries.csv

# Update single entry with explicit code
das entry update --attribute core --code ENT001 --data "{ 'Grant Public Access': 'Yes' }"

# Update single entry with Code in data
das entry update --attribute core --data "{ 'Code': 'ENT001', 'Grant Public Access': 'Yes' }"

# Update multiple entries from data string
das entry update --attribute core --data "[{ 'Code': 'ENT001', 'Name': 'Updated 1' }, { 'Code': 'ENT002', 'Name': 'Updated 2' }]"

Manager Layer:

from das.managers.entries_manager import EntryManager

entry_manager = EntryManager()

# Update single entry
result = entry_manager.update(
    attribute="core",
    code="ENT001",
    entry={"Grant Public Access": "Yes"}
)

# Update multiple entries
results = entry_manager.update(
    attribute="core",
    entries=[
        {"Code": "ENT001", "Name": "Updated Entry 1"},
        {"Code": "ENT002", "Name": "Updated Entry 2"}
    ]
)

Service Layer:

from das.services.entries import EntriesService
from das.services.attributes import AttributesService
from das.common.config import load_api_url

base_url = load_api_url()
entry_service = EntriesService(base_url)
attribute_service = AttributesService(base_url)

# Get existing entry to retrieve attribute_id
existing_entry = entry_service.get(code="ENT001")
attribute_id = existing_entry.get("attributeId")

# Update entry
entry_id = entry_service.update(
    attribute_id=attribute_id,
    entry={"name": "Updated Entry 1", "grantpublicaccess": "Yes"}
)

Delete Entry

CLI:

# Delete by code (with confirmation)
das entry delete --code ENT001

# Delete by code (skip confirmation)
das entry delete --code ENT001 --force

# Delete by ID
das entry delete --id 123

Manager Layer:

from das.managers.entries_manager import EntryManager

entry_manager = EntryManager()

# Delete by code
success = entry_manager.delete(code="ENT001")

# Delete by ID
success = entry_manager.delete(id="123")

Service Layer:

from das.services.entries import EntriesService
from das.common.config import load_api_url

base_url = load_api_url()
entry_service = EntriesService(base_url)

# Delete by code
success = entry_service.delete(code="ENT001")

# Delete by ID
success = entry_service.delete_by_id(id="123")

Change Ownership

CLI:

# Transfer ownership of entries to a user
das entry chown --user alice --code ENT001 --code ENT002

Manager Layer:

from das.managers.entries_manager import EntryManager

entry_manager = EntryManager()

# Change ownership
result = entry_manager.chown(
    user_name="alice",
    entry_code_list=["ENT001", "ENT002"]
)

Service Layer:

from das.services.entries import EntriesService
from das.services.users import UsersService
from das.common.config import load_api_url

base_url = load_api_url()
entry_service = EntriesService(base_url)
user_service = UsersService(base_url)

# Get user ID
user = user_service.get_user("alice")
user_id = user.get("id")

# Get entry IDs
entry1 = entry_service.get(code="ENT001")
entry2 = entry_service.get(code="ENT002")
entry_ids = [entry1.get("entry", {}).get("id"), entry2.get("entry", {}).get("id")]

# Change ownership
result = entry_service.chown(
    new_user_id=user_id,
    entry_list_ids=entry_ids
)

Search

CLI:

# Search entries
das search entries --attribute Cores --query "name(*64*)" --max-results 10 --page 1 --sort-by Name --sort-order asc --format table

# Get detailed entry by ID
das search entry 6b0e68e6-00cd-43a7-9c51-d56c9c091123 --format json

Manager Layer:

from das.managers.search_manager import SearchManager

search_manager = SearchManager()

# Search entries
results = search_manager.search_entries(
    attribute="Cores",
    query="name(*64*)",
    max_results=10,
    page=1,
    sort_by="Name",
    sort_order="asc"
)

Service Layer:

from das.services.search import SearchService
from das.services.attributes import AttributesService
from das.common.config import load_api_url

base_url = load_api_url()
search_service = SearchService(base_url)
attribute_service = AttributesService(base_url)

# Get attribute ID
attr_response = attribute_service.get_attribute(name="Cores")
attribute_id = attr_response.get("result", {}).get("items", [])[0].get("id")

# Search entries
results = search_service.search_entries(
    attributeId=attribute_id,
    queryString="name(*64*);",
    maxResultCount=10,
    skipCount=0,
    sorting="name asc"
)

Downloads

Create Download Request

CLI:

# Create request for all files from an entry
das download request --entry ENT001 --name "My Download Request"

# Create request with specific files
das download request --entry ENT001 --file FILE001 --file FILE002

# Create request from JSON file
das download request --from-file request.json

Manager Layer:

from das.managers.download_manager import DownloadManager

download_manager = DownloadManager()

# Create download request
request_data = {
    'name': 'My Download Request',
    'ENT001': ['FILE001', 'FILE002'],  # Specific files
    'ENT002': []  # All files from this entry
}
request_id = download_manager.create_download_request(request_data)

Service Layer:

from das.services.downloads import DownloadRequestService
from das.common.config import load_api_url

base_url = load_api_url()
download_service = DownloadRequestService(base_url)

# Create download request (requires formatted request items)
request_items = {
    'items': [
        {
            'name': 'My Download Request',
            'sourceId': 'entry_id_1',
            'sourceAttributeId': 123,
            'id': 'digital_object_id_1'
        }
    ]
}
request_id = download_service.create(request_items)

List Download Requests

CLI:

# List your download requests
das download my-requests --format table

Manager Layer:

from das.managers.download_manager import DownloadManager

download_manager = DownloadManager()

# Get all download requests
my_requests = download_manager.get_my_requests()

Service Layer:

from das.services.downloads import DownloadRequestService
from das.common.config import load_api_url

base_url = load_api_url()
download_service = DownloadRequestService(base_url)

# Get all download requests
my_requests = download_service.get_my_requests()

Delete Download Request

CLI:

# Delete a download request
das download delete-request 6b0e68e6-00cd-43a7-9c51-d56c9c091123

Manager Layer:

from das.managers.download_manager import DownloadManager

download_manager = DownloadManager()

# Delete download request
result = download_manager.delete_download_request("6b0e68e6-00cd-43a7-9c51-d56c9c091123")

Service Layer:

from das.services.downloads import DownloadRequestService
from das.common.config import load_api_url

base_url = load_api_url()
download_service = DownloadRequestService(base_url)

# Delete download request
result = download_service.delete("6b0e68e6-00cd-43a7-9c51-d56c9c091123")

Download Files

CLI:

# Download files to current directory
das download files 6b0e68e6-00cd-43a7-9c51-d56c9c091123

# Download to specific folder
das download files 6b0e68e6-00cd-43a7-9c51-d56c9c091123 --out C:\Downloads

# Download with explicit filename, overwriting if exists
das download files 6b0e68e6-00cd-43a7-9c51-d56c9c091123 --out C:\Downloads\bundle.zip --force

Manager Layer:

from das.managers.download_manager import DownloadManager

download_manager = DownloadManager()

# Save download to disk
saved_path = download_manager.save_download(
    request_id="6b0e68e6-00cd-43a7-9c51-d56c9c091123",
    output_path="C:\\Downloads",
    overwrite=False
)

Service Layer:

from das.services.downloads import DownloadRequestService
from das.common.config import load_api_url

base_url = load_api_url()
download_service = DownloadRequestService(base_url)

# Get streaming response
response = download_service.download_files("6b0e68e6-00cd-43a7-9c51-d56c9c091123")

# Save to disk manually
with open("download.zip", "wb") as f:
    for chunk in response.iter_content(chunk_size=8192):
        if chunk:
            f.write(chunk)

Attributes

CLI:

# Get attribute by ID
das attribute get --id 123

# Get attribute by name
das attribute get --name "temperature"

# Get attribute name by ID
das attribute get-name 123

# Get attribute ID by name
das attribute get-id "temperature"

Manager Layer:

from das.services.attributes import AttributesService
from das.common.config import load_api_url

base_url = load_api_url()
attribute_service = AttributesService(base_url)

# Get attribute by various methods
attribute = attribute_service.get_attribute(id=123)
attribute = attribute_service.get_attribute(name="temperature")
attribute = attribute_service.get_attribute(alias="temp")
attribute = attribute_service.get_attribute(table_name="measurements")

# Get name/ID converters
name = attribute_service.get_name(123)
attr_id = attribute_service.get_id("temperature")

Service Layer:

from das.services.attributes import AttributesService
from das.common.config import load_api_url

base_url = load_api_url()
attribute_service = AttributesService(base_url)

# Get attribute
result = attribute_service.get_attribute(id=123, name="temperature", alias="temp", table_name="measurements")

# Get name/ID converters
name = attribute_service.get_name(123)
attr_id = attribute_service.get_id("temperature")

Cache

CLI:

# List all cache entries
das cache list

# Clear a specific cache
das cache clear "cache-name"

# Clear all caches
das cache clear-all

Manager Layer:

from das.app import Das

client = Das("https://your-das-instance/api")
client.authenticate("username", "password")

# List all caches
cache_entries = client.cache.get_all()

# Clear specific cache
result = client.cache.clear_cache("cache-name")

# Clear all caches
result = client.cache.clear_all()

Service Layer:

from das.services.cache import CacheService
from das.common.config import load_api_url

base_url = load_api_url()
cache_service = CacheService(base_url)

# List all caches
cache_entries = cache_service.get_all()

# Clear specific cache
result = cache_service.clear_cache("cache-name")

# Clear all caches
result = cache_service.clear_all()

Hangfire

CLI:

# Trigger DOI synchronization
das hangfire sync-doi 123

Manager Layer:

from das.app import Das

client = Das("https://your-das-instance/api")
client.authenticate("username", "password")

# Sync DOI
client.hangfire.sync_doi("123")

Service Layer:

from das.services.hangfire import HangfireService
from das.common.config import load_api_url

base_url = load_api_url()
hangfire_service = HangfireService(base_url)

# Sync DOI
result = hangfire_service.sync_doi("123")

Digital Objects

Upload Digital Object

CLI:

# Upload a file as digital object and link to entry
das entry upload-digital-object --entry-code ENT001 --type Dataset --description "CTD raw" c:\data\ctd.zip

Manager Layer:

from das.managers.digital_objects_manager import DigitalObjectsManager

digital_objects_manager = DigitalObjectsManager()

# Upload digital object
digital_object_id = digital_objects_manager.upload_digital_object(
    entry_code="ENT001",
    file_description="CTD raw",
    digital_object_type="Dataset",
    file_path="c:\\data\\ctd.zip"
)

Link/Unlink Digital Objects

CLI:

# Link digital objects to an entry
das entry link-digital-objects --entry-code ENT001 -d DO001 -d DO002

# Unlink digital objects from an entry
das entry link-digital-objects --entry-code ENT001 -d DO003 --unlink

Manager Layer:

from das.managers.digital_objects_manager import DigitalObjectsManager

digital_objects_manager = DigitalObjectsManager()

# Link digital objects
success = digital_objects_manager.link_existing_digital_objects(
    entry_code="ENT001",
    digital_object_code_list=["DO001", "DO002"],
    is_unlink=False
)

# Unlink digital objects
success = digital_objects_manager.link_existing_digital_objects(
    entry_code="ENT001",
    digital_object_code_list=["DO003"],
    is_unlink=True
)

Configuration

CLI:

# Enable SSL verification
das config ssl-verify true

# Disable SSL verification
das config ssl-verify false

# Check SSL status
das config ssl-status

# Reset all configuration
das config reset --force

Python:

from das.common.config import save_verify_ssl, load_verify_ssl, save_api_url, load_api_url

# SSL verification
save_verify_ssl(True)   # enable (recommended)
save_verify_ssl(False)  # disable (dev/testing)
current_setting = load_verify_ssl()

# API URL
save_api_url("https://your-das-instance/api")
api_url = load_api_url()

Configuration

SSL certificate verification

# Enable (default)
das config ssl-verify true

# Disable (development/testing only)
das config ssl-verify false

# Check status
das config ssl-status

Downloads

# Create a download request
das download request --entry ENT001 --name "My Download Request"

# Create a request with specific files
das download request --entry ENT001 --file FILE001 --file FILE002

# Create a request with multiple entries
das download request --entry ENT001 --entry ENT002 --name "Multiple Entries"

# Create a request from JSON file
das download request --from-file request.json

# List your download requests
das download my-requests --format table

# Delete a download request
das download delete-request 6b0e68e6-00cd-43a7-9c51-d56c9c091123

# Download files for a completed request
das download files 6b0e68e6-00cd-43a7-9c51-d56c9c091123

# Save to a specific folder
das download files 6b0e68e6-00cd-43a7-9c51-d56c9c091123 --out C:\Downloads

# Save to an explicit filename, overwriting if it exists
das download files 6b0e68e6-00cd-43a7-9c51-d56c9c091123 --out C:\Downloads\bundle.zip --force

Examples

# List cache and clear a specific cache
das cache list
das cache clear "attributes"

# Dump a single entry as JSON
das search entry 123 --format json

# Paginate through search results
das search entries --attribute Name --query 'name(*core*)' --max-results 50 --page 2

# List your download requests
das download my-requests --format table

# Reset all configuration
das config reset --force

Troubleshooting

  • Authentication failed:
    • Ensure --api-url points to the correct DAS instance base URL (often ends with /api).
    • Try re-running das login without passing password to be prompted.
  • SSL certificate errors:
    • Use das config ssl-verify false temporarily in non-production environments.
    • Consider configuring your corporate CA store instead of disabling verification.
  • Proxy/network issues:
    • Respect environment variables HTTP_PROXY, HTTPS_PROXY, and NO_PROXY if required.
  • Windows PowerShell quoting:
    • Prefer single quotes for queries, or escape * and ; as needed (e.g., \*).
  • Unexpected output formatting:
    • Switch format with --format json or --format compact.

Dependencies

Runtime and development dependencies are declared in requirements.txt and pyproject.toml. Install via pip install das-cli or pip install -e . for development.

Development

Setting Up Development Environment

# Clone the repository
git clone https://git.nioz.nl/ict-projects/das-cli.git
cd das-cli

# Create and activate a virtual environment
python -m venv venv
.\venv\Scripts\activate  # On Windows
source venv/bin/activate    # On Unix/macOS

# Install in editable mode
pip install -e .

# (Optional) Install dev/test tooling
pip install -e .[dev]

Running Tests

# Run all tests
python run_tests.py

# Run a specific test file
python -m pytest tests/specific_test_file.py

Contributing

Contributions are welcome! Please open a Pull Request.

Report bugs or request features via the DAS CLI issue tracker.

License

MIT License

Maintainers

This project is maintained by the Royal Netherlands Institute for Sea Research (NIOZ).

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

das_cli-1.2.14.tar.gz (49.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

das_cli-1.2.14-py3-none-any.whl (45.7 kB view details)

Uploaded Python 3

File details

Details for the file das_cli-1.2.14.tar.gz.

File metadata

  • Download URL: das_cli-1.2.14.tar.gz
  • Upload date:
  • Size: 49.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.2

File hashes

Hashes for das_cli-1.2.14.tar.gz
Algorithm Hash digest
SHA256 e0dbcab38ad24b7d3e8685391b16999c93be16489ccba246737e92eaa862f5f0
MD5 2cf599c546c763210f5578b014aab4b9
BLAKE2b-256 803ca31a128600d2891fed81e45be82e49ac5b353e780b22e2badf8517a928fe

See more details on using hashes here.

File details

Details for the file das_cli-1.2.14-py3-none-any.whl.

File metadata

  • Download URL: das_cli-1.2.14-py3-none-any.whl
  • Upload date:
  • Size: 45.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.2

File hashes

Hashes for das_cli-1.2.14-py3-none-any.whl
Algorithm Hash digest
SHA256 dda3d304e91f94ada0e39fe4db32341dc90e875719b950e8cf71216e65d73891
MD5 80b25d599318479a4f56e546b19279cd
BLAKE2b-256 672f5c782802a7de936000ace8d4c4c8c4ffe0794d4e54c555cdb9471a4136c7

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page