SpectrumX SDK Changelog
0.2.1 - 2026-07-09
-
Fixes:
- Fixed file descriptor leak:
replaced
multiprocessing.RLockwiththreading.RLockin file models and gateway client to prevent OS-level file descriptor leakage in long-running sessions. - Connection pooling in gateway
client:
the gateway now uses
requests.Sessionwith a configured retry strategy instead of opening a new connection on every API call, reducing TCP connection churn and associated FD leakage. - Network errors now raise
NetworkError: connection failures in the gateway are now wrapped in the SDK'sNetworkErrorexception instead of barerequestsexceptions, making them catchable by existing error-handling patterns in user code.
- Fixed file descriptor leak:
replaced
-
Housekeeping:
- Expanded test coverage:
added new test modules (
test_base.py,test_datasets.py,test_enums.py,test_files.py,test_permission.py,test_user.py,test_config.py,test_errors.py,test_gateway.py) with comprehensive model, config, error, and gateway tests — 4,272 lines of additional test coverage. log_cli=trueremoved from pytest config: disabled noisy CLI log capture in pytest defaults to reduce test output noise.- Version bump to
0.2.1.
- Expanded test coverage:
added new test modules (
0.2.0 - 2026-07-06
-
Features:
- Byte-level progress bars for file
downloads: file downloads now
show a byte-level progress bar with throttled
tqdmcallbacks (~100 KB refresh rate), providing smooth visual feedback during multi-file downloads — matching the upload progress bar experience introduced in v0.1.15. When total bytes are unknown (e.g. paginated results), a file-level fallback progress bar is used instead. - Configurable periodic progress
logging: new
progress_log_period_secsconfig option (default: 30 seconds) controls how often structured progress log entries are emitted during long-running uploads and downloads. Set via environment variable or.envfile. - Custom structured log path:
new
log_fileconfig option allows setting a custom path for the structured JSONL log file via environment variable,.envfile, orClient(log_file=...)parameter.
- Byte-level progress bars for file
downloads: file downloads now
show a byte-level progress bar with throttled
-
Observability:
- Structured JSONL logging
system: new
enable_structured_logging()function configures the SDK to write machine-parseable JSON lines to~/.local/state/spectrumx/logs/YYYY-MM-DD.jsonl. Each log line includes timestamp, process ID, severity, category, and message. Usejqto filter and analyze:
# Show only download operations jq 'select(.cat == "download")' ~/.local/state/spectrumx/logs/*.jsonl # Show warnings and errors jq 'select(.lvl == "WARNING" or .lvl == "ERROR")' ~/.local/state/spectrumx/logs/*.jsonl+ Boot message with SDK version, OS platform, and Python version on every session. + Log categories: `config`, `auth`, `network`, `filesystem`, `download`, `upload`, `log`. + Scoped context via `LogContext` context manager for per-operation fields (e.g. upload ID, directory). + Persistent context via `set_persistent_log_context()` for cross-operation fields (e.g. API key prefix). + Error entries include exception type and message in `exc_info` field. + Re-configurable at runtime — calling `enable_structured_logging()` with a new path switches to the new file and emits a fresh boot message.- Upload workflow now emits structured log entries:
- Periodic progress every
progress_log_period_secswith completed/total files, bytes uploaded/total, failures, in-progress, and skipped counts. - Completion summary with elapsed time, average speed, and status (clean/interrupted).
- Per-file operation log context via
log_context(upload_id=..., upload_dir=...).
- Periodic progress every
- Download workflow now emits structured log entries:
- Per-file completion with file name and size.
- Periodic progress every
progress_log_period_secswith completed/total files, bytes downloaded/total, and failure count. - Completion summary with elapsed time, average speed, and status (clean/interrupted).
- Configuration events tagged with
LogCategory.CONFIG— config loading, env file discovery, and attribute setting now emit structured log entries for easier debugging.
- Structured JSONL logging
system: new
-
Housekeeping:
- Developer demo script: added
scripts/demo_progress_bars.pythat simulates upload/download transfers at configurable rates to let developers preview progress bar visuals without a live gateway. - Improved test coverage:
- New
test_structured_logging.pymodule (9 tests): JSONL file paths, boot message emission, core fields on every log line, contextual field binding, category filtering, scoped context lifecycle, persistent context, path re-configuration, and state reset. - New download byte progress tests in
test_client.pycovering skipped content credit and partial stream accounting. - New upload progress tests in
test_uploads_workflow.pycovering unstreamed byte credit, metadata-only uploads, and concurrent progress bar byte counting. - New
credit_unstreamed_file_bytestests intest_utils.py.
- New
- Version bump to
0.2.0.
- Developer demo script: added
0.1.20 - 2026-06-02
- Fixes:
- Fixed crash when
ownerand related fields are missing from API responses: theCapture.ownerfield (andUser.name/User.emailfor cascading partial data) are now optional withNonedefaults. Previously, the SDK would raise a PydanticValidationErrorwhen the server omitted these fields from capture payloads during file and capture listing, causing the entire operation to fail.
- Fixed crash when
0.1.19 - 2026-05-15
-
Features:
- Added
start_timeandend_timeparameters tolist_filesanddownload: this gives users the ability to filter file directory downloads associated with DigitalRF captures based on a time span within the capture bounds (similar to time filtering in the web UI on SDS) - Added
capture_uuids,top_level_dirs, andartifacts_onlyparameters todownload_dataset: this allows users to input specific capture UUIDs or file directories associated with the dataset to download.artifacts_onlyallows user to filter for directly connected files on a dataset specifically. In this case,capture_uuidsentry is ignored, but users may definetop_level_dirfile directories to filter artifacts for download on a large dataset. Users may runlist_dataset_capturesto see the UUID andtop_level_dirof the captures on the dataset they wish to download. - Added
list_dataset_capturesmethod: this allows users to list all captures associated with a dataset. - Added
list_dataset_artifact_filesmethod: this allows users to list all artifact files associated with a dataset.
- Added
-
Observability:
- Added
capturesandfilesattributes toDatasetmodel: This allows visibility from the dataset side into attached captures and files. - Added
capture_start_iso_utc,capture_end_iso_utc,capture_start_display, andcapture_end_displayfields to theCapturemodel: Users can now inspect the indexed capture time bounds from OpenSearch on capture metadata, both in UTC and in a display-formatted time zone. - Added
gatewayproperty toClient: Advanced users and test code can now access the underlyingGatewayClientdirectly viasds.gateway.
- Added
-
Housekeeping:
- Paginator now surfaces API warnings: When the server returns warning messages in paginated responses, they are now logged automatically via the SDK's logger.
0.1.18 - 2026-04-30
-
Features:
- Added
deleteandrevoke_share_permissionsmethods for datasets: this allows users to (soft) delete datasets in the SDS through the SDK and revoke ALL share permissions from datasets if needed before deletion or in general. - Added
revoke_share_permissionsanddetach_from_datasetsmethods to captures: this gives users the ability to revoke share permissions or detach captures from connected datasets when they need to delete a capture. - Added
detach_from_datasetsmethods to files: this gives users the ability to detach files from connected datasets when they need to delete them. Note: Files CANNOT be detached from captures. Delete a the parent capture FIRST to delete the file.
- Added
-
Observability:
- Added fields displaying ownership, share permission, and asset
connection information to SDK
models: this allows users to
see more relevant information when retrieving or listing assets like whether they
are shared, who they are shared with, who owns them, and what other assets the
target is attached to (like files to captures and datasets).
- New file attributes:
owner,captures,datasets - New capture attributes:
owner,is_shared,is_shared_with_me,share_permissions - New dataset attributes:
owner,is_shared,share_permissions,datasets
- New file attributes:
- Added new models for User and UserSharePermission: This allows for visibility into the users and share permissions connected to assets.
- Added fields displaying ownership, share permission, and asset
connection information to SDK
models: this allows users to
see more relevant information when retrieving or listing assets like whether they
are shared, who they are shared with, who owns them, and what other assets the
target is attached to (like files to captures and datasets).
-
Fixes:
- Fixed upload failure when using relative local
paths: the file discovery step
in uploads broke when a relative path was given as
local_path(e.g.sds.upload(local_path="my_dir", ...)). The root cause was passing the resolved (absolute) root path but feeding candidates from an unresolved (relative)rglobiterator, causingPath.relative_to()to fail with aValueError. This was a regression introduced in v0.1.15 when switching toanyio.Pathfor async path operations.
- Fixed upload failure when using relative local
paths: the file discovery step
in uploads broke when a relative path was given as
0.1.17 - 2025-12-20
- Fixes:
- Improved file downloads:
more reliability for file downloads when they need to be resumed.
- File downloads now use a temporary file during download to avoid partial files being left behind if the download is interrupted.
- When overwrite is
Falseand a local file would be overwritten, we skip re-downloading it. - When overwrite is
Trueand the checksums don't match with server, we re-download and replace the local file to match the server's. - If local file is identical to server's, we now skip the download entirely,
even when overwrite is
True.
- Improved file downloads:
more reliability for file downloads when they need to be resumed.
0.1.16 - 2025-12-16
- Fixes:
- Added
persist_statetoupload_multichannel_drf_capture: users can now control whether to persist the upload state of files during multi-channel DRF captures.
- Added
- Reliability:
- Relaxed validation in capture
listing: capture listing is now
more tolerant of cases where a given capture fails validation, now listing the
ones that can be loaded correctly instead of failing the whole operations.
Container fields like
filesnow also default to empty ones if missing, instead of failing validation.
- Relaxed validation in capture
listing: capture listing is now
more tolerant of cases where a given capture fails validation, now listing the
ones that can be loaded correctly instead of failing the whole operations.
Container fields like
0.1.15 - 2025-12-02
- Features:
- Added support for Python 3.14: the SDK is now compatible with Python 3.14. We're thus dropping support for version 3.10 in this and future releases.
- Improved UX for file
uploads: the new file upload
process:
- Backwards compatible with previous method.
- Discovery step lists all files before starting upload.
- Concurrent uploads with asyncio: up to 5 streams by default.
- Progress tracking the number of files and bytes, in human-friendly units.
- Tracking completed :white_check_mark:, failed :x: , in progress :hourglass_flowing_sand:️ and skipped:rabbit2: files. On Windows, we use ASCII characters for better compatibility.
- New file upload persistence:
we now keep a local copy of the upload state of files.
- This makes resuming interrupted uploads faster. The persistence mode can be
bypassed with
persist_state=Falsein upload methods in case users want to force the file checks (previous behavior).
- This makes resuming interrupted uploads faster. The persistence mode can be
bypassed with
- Reliability:
- Increased the battery of tests for file uploads and progress tracking.
- Several new tests covering features of upload state persistence.
0.1.14 - 2025-10-07
- Documentation:
- Added and SDK walkthrough notebook to the users' guide: SpectrumX SDK walkthrough.
- Fixes:
- Reviewed logic to ignore
files: now files like
.DS_Store,*.tmp, and other patterns in .sds-ignore are correctly skipped for uploads.
- Reviewed logic to ignore
files: now files like
0.1.13 - 2025-08-26
- Features:
- Added
download_datasetmethod to client: Users can now download datasets through the SDK by passing in a dataset UUID e.g.sds_client.download_dataset(uuid=<dataset_uuid>, to_local_path=...). - Added a
files_to_downloadargument to thedownload()method: Can now supply a pre-filtered list of files to download rather than downloading all files in a path.
- Added
0.1.12 - 2025-08-12
- Features:
- Added
nameparameter toupload_capturemethod:upload_capture()now accepts an optionalnameparameter to set custom capture names.
- Added
0.1.11 - 2025-07-03
- Features:
- Added
upload_multichannel_drf_captureSDK method toClient: Multi-channel captures can now be uploaded to the SDS.
- Added
0.1.10 - 2025-06-05
- Features:
- Added
created_atto captures:: captures now feature acreated_atdatetime attribute when this information is available. - Allowing upload of sigmf-data files: removed restriction of octet-stream files in uploads.
- Added
0.1.9 - 2025-05-08
- Features:
- Capture deletions: captures
may now be deleted using the SDK with
sds_client.captures.delete(). - Advanced searches:
introducing preliminary support for advanced capture searches using OpenSearch
queries. See the OpenSearch Query
Tips
for details about the syntax. The SDK endpoint is
sds_client.captures.advanced_search(): the method's docstring has information on arguments and links to documentation.
- Capture deletions: captures
may now be deleted using the SDK with
- Usage improvements:
- Allowing positional args: SDK
methods that receive a single UUID as an argument now allow it to be passed as a
positional argument e.g.
sds_client.get_file(<uuid>)is equivalent tosds_client.get_file(uuid=<uuid>). - Capture uploads: new
high-level method that combines the upload of a directory of files with a capture
creation:
sds_client.upload_capture(). - Usage guide updates: the SDK usage guide now includes information on how to check the results returned by a directory upload.
- Logging control:: client's verbose flag propagates to submodules and sub-APIs.
- Allowing positional args: SDK
methods that receive a single UUID as an argument now allow it to be passed as a
positional argument e.g.
- Bugfixes and reliability improvements:
- Bugfix:
File.local_pathattribute of some downloaded files was not correctly set. - Path usage tests:: new tests to cover regressions of different ways to use paths from SDK methods.
- Capture read test: tests for
client.capture.read()now check the number of files associated to the capture is correct.
- Bugfix:
0.1.8 - 2025-03-24
- Features and improvements:
- #72 Added Windows compatibility.
- #79 SDS files may now be deleted using the SDK.
- #78 The
capture_typeargument ofsds_client.captures.listing()is now optional. - #78 The method
sds_client.captures.read()is now available for reading a single capture, complementing the existingsds_client.captures.listing()method. - #78 When retrieving a single
capture with
capture = read(<uuid>), the list of files associated to it is available incapture.files.- Note these are
CaptureFileinstances, which hold a subset of the information in an SDS'Fileinstance. To get all metadata on a file, usesds_client.get_file(<uuid>).
- Note these are
- Fixes:
- Housekeeping:
- #76 Fixed documentation typos; Updated and expanded note on concurrent access in the usage guide.
0.1.7 - 2025-03-07
- Features:
spectrumx.api.captures.create()now accepts ascan_groupfor RadioHound captures.index_namefromspectrumx.api.captures.create()is dropped: the index is automatically chosen from the capture type.
0.1.6 - 2025-02-24
- New features:
- Support for Python 3.10 and 3.11.
0.1.5 - 2025-02-10
- Breaking changes:
spectrumx.models.Filemoved tospectrumx.models.files.File.
- New features:
- SDS Capture creation and listing.
- Housekeeping:
- Refactored client by branching its method implementations and client configuration to separate modules.
0.1.4 - 2025-01-17
- New features:
- File listing with lazy-loaded paginated results.
- Introduced new file upload modes to avoid re-uploading files already in SDS.
- Housekeeping:
- Usage documentation updated.
- See
tests/e2e_examples/check_build_acceptance.pyfor more SDK usage examples. - Refactoring of internal modules.
- Improved test coverage.