Skip to content

Commit 9901fca

Browse files
DhanashreePetareDhanashreePetareInteger-Ctrl
authored
# PR: Release databusclient 0.15 to PyPI (Issue #35) (#41)
* Restrict Vault token exchange to specific hosts; improve auth errors; add tests (fixes #19) * Restrict Vault token exchange to specific hosts; improve auth errors; add tests and docs note (fixes #19) * Release 0.15: bump version, add changelog, docstrings(issue #35) * Prepare PyPI release 0.15 with build artifacts and publishing guide (Issue #35) * Convert all docstrings to Google-style format --------- Co-authored-by: DhanashreePetare <[email protected]> Co-authored-by: Fabian Hofer <[email protected]>
1 parent b2c3f1c commit 9901fca

File tree

12 files changed

+423
-168
lines changed

12 files changed

+423
-168
lines changed

CHANGELOG.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented in this file.
4+
5+
## [0.15] - 2025-12-31
6+
7+
### Added
8+
- Vault authentication improvements with host-restricted token exchange
9+
- Comprehensive tests for Vault authentication behavior
10+
- Enhanced docstrings across all modules for better documentation coverage
11+
- Support for download redirect handling
12+
13+
### Fixed
14+
- Vault token exchange now restricted to known hosts for improved security
15+
- Clearer authentication error messages
16+
- README instructions now consistent with PyPI release
17+
18+
### Changed
19+
- Updated CLI usage documentation to reflect current command structure
20+
- Improved error handling in download operations
21+
22+
### Notes
23+
- Version 0.15 skips 0.13 and 0.14 as requested in issue #35
24+
- This release updates the PyPI package to align with current repository features

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@ Before using the client, install it via pip:
4141
python3 -m pip install databusclient
4242
```
4343

44+
Note: the PyPI release was updated and this repository prepares version `0.15`. If you previously installed `databusclient` via `pip` and observe different CLI behavior, upgrade to the latest release:
45+
46+
```bash
47+
python3 -m pip install --upgrade databusclient==0.15
48+
```
49+
4450
You can then use the client in the command line:
4551

4652
```bash

RELEASE_NOTES.md

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# Release Notes for databusclient 0.15
2+
3+
## Overview
4+
This release addresses issue #35 by providing a new PyPI package (version 0.15) to ensure `pip install databusclient` provides the latest CLI features and bug fixes.
5+
6+
## Version
7+
**0.15** (skipping 0.13 and 0.14 as requested)
8+
9+
## What's New
10+
11+
### Features & Improvements
12+
- **Vault Authentication Enhancement**: Host-restricted token exchange for improved security
13+
- **Better Error Messages**: Clearer authentication error messages for easier debugging
14+
- **Download Redirect Handling**: Improved handling of redirects during file downloads
15+
- **Comprehensive Documentation**: Enhanced docstrings across all modules
16+
17+
### Bug Fixes
18+
- Fixed Vault token exchange to only work with known hosts
19+
- Improved error handling in download operations
20+
- Aligned README with current CLI behavior
21+
22+
### Testing
23+
- Added comprehensive tests for Vault authentication
24+
- Improved test coverage overall
25+
26+
## Installation
27+
28+
After this release is published to PyPI, users can install or upgrade with:
29+
30+
```bash
31+
pip install databusclient==0.15
32+
# or to upgrade
33+
pip install --upgrade databusclient
34+
```
35+
36+
## Build Artifacts
37+
38+
The following distribution files have been created and validated:
39+
- `databusclient-0.15-py3-none-any.whl` (wheel format)
40+
- `databusclient-0.15.tar.gz` (source distribution)
41+
42+
Both files have passed `twine check` validation.
43+
44+
## Publishing Instructions
45+
46+
### Prerequisites
47+
1. PyPI account with maintainer access to the `databusclient` package
48+
2. PyPI API token configured
49+
50+
### Steps to Publish
51+
52+
1. **Verify the build artifacts** (already done):
53+
```bash
54+
poetry build
55+
twine check dist/*
56+
```
57+
58+
2. **Upload to TestPyPI** (recommended first):
59+
```bash
60+
twine upload --repository testpypi dist/*
61+
```
62+
Then test installation:
63+
```bash
64+
pip install --index-url https://test.pypi.org/simple/ databusclient==0.15
65+
```
66+
67+
3. **Upload to PyPI**:
68+
```bash
69+
twine upload dist/*
70+
```
71+
72+
4. **Create a Git tag**:
73+
```bash
74+
git tag -a v0.15 -m "Release version 0.15"
75+
git push origin v0.15
76+
```
77+
78+
5. **Create a GitHub Release**:
79+
- Go to GitHub repository → Releases → Draft a new release
80+
- Choose tag `v0.15`
81+
- Release title: `databusclient 0.15`
82+
- Copy content from CHANGELOG.md
83+
- Attach the dist files as release assets
84+
85+
## Verification
86+
87+
After publishing, verify the release:
88+
```bash
89+
pip install --upgrade databusclient==0.15
90+
databusclient --version
91+
databusclient --help
92+
```
93+
94+
## Notes
95+
- This release resolves issue #35
96+
- The PyPI package will now be consistent with the repository's CLI documentation
97+
- Version numbers 0.13 and 0.14 were intentionally skipped as requested

databusclient/__init__.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,22 @@
1+
"""Top-level package for the databus Python client.
2+
3+
This module exposes a small set of convenience functions and the CLI
4+
entrypoint so the package can be used as a library or via
5+
``python -m databusclient``.
6+
"""
7+
18
from databusclient import cli
29
from databusclient.api.deploy import create_dataset, create_distribution, deploy
310

11+
__version__ = "0.15"
412
__all__ = ["create_dataset", "deploy", "create_distribution"]
513

614

715
def run():
16+
"""Start the Click CLI application.
17+
18+
This function is used by the ``__main__`` module and the package
19+
entrypoint to invoke the command line interface.
20+
"""
21+
822
cli.app()

databusclient/__main__.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
"""Module used for ``python -m databusclient`` execution.
2+
3+
Runs the package's CLI application.
4+
"""
5+
16
from databusclient import cli
27

3-
cli.app()
8+
9+
def main():
10+
"""Invoke the CLI application.
11+
12+
Kept as a named function for easier testing and clarity.
13+
"""
14+
15+
cli.app()
16+
17+
18+
if __name__ == "__main__":
19+
main()

databusclient/api/delete.py

Lines changed: 68 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
"""Helpers for deleting Databus resources via the Databus HTTP API.
2+
3+
This module provides utilities to delete groups, artifacts and versions on a
4+
Databus instance using authenticated HTTP requests. The class `DeleteQueue`
5+
also allows batching of deletions.
6+
"""
7+
18
import json
29
from typing import List
310

@@ -16,23 +23,43 @@ class DeleteQueue:
1623
"""
1724

1825
def __init__(self, databus_key: str):
26+
"""Create a DeleteQueue bound to a given Databus API key.
27+
28+
Args:
29+
databus_key: API key used to authenticate deletion requests.
30+
"""
1931
self.databus_key = databus_key
2032
self.queue: set[str] = set()
2133

2234
def add_uri(self, databusURI: str):
35+
"""Add a single Databus URI to the deletion queue.
36+
37+
The URI will be deleted when `execute()` is called.
38+
"""
2339
self.queue.add(databusURI)
2440

2541
def add_uris(self, databusURIs: List[str]):
42+
"""Add multiple Databus URIs to the deletion queue.
43+
44+
Args:
45+
databusURIs: Iterable of full Databus URIs.
46+
"""
2647
for uri in databusURIs:
2748
self.queue.add(uri)
2849

2950
def is_empty(self) -> bool:
51+
"""Return True if the queue is empty."""
3052
return len(self.queue) == 0
3153

3254
def is_not_empty(self) -> bool:
55+
"""Return True if the queue contains any URIs."""
3356
return len(self.queue) > 0
3457

3558
def execute(self):
59+
"""Execute all queued deletions.
60+
61+
Each queued URI will be deleted using `_delete_resource`.
62+
"""
3663
_delete_list(
3764
list(self.queue),
3865
self.databus_key,
@@ -41,16 +68,15 @@ def execute(self):
4168

4269

4370
def _confirm_delete(databusURI: str) -> str:
44-
"""
45-
Confirm deletion of a Databus resource with the user.
71+
"""Confirm deletion of a Databus resource with the user.
4672
47-
Parameters:
48-
- databusURI: The full databus URI of the resource to delete
73+
Args:
74+
databusURI: The full databus URI of the resource to delete.
4975
5076
Returns:
51-
- "confirm" if the user confirms deletion
52-
- "skip" if the user chooses to skip deletion
53-
- "cancel" if the user chooses to cancel the entire deletion process
77+
"confirm" if the user confirms deletion.
78+
"skip" if the user chooses to skip deletion.
79+
"cancel" if the user chooses to cancel the entire deletion process.
5480
"""
5581
print(f"Are you sure you want to delete: {databusURI}?")
5682
print(
@@ -81,18 +107,17 @@ def _delete_resource(
81107
force: bool = False,
82108
queue: DeleteQueue = None,
83109
):
84-
"""
85-
Delete a single Databus resource (version, artifact, group).
110+
"""Delete a single Databus resource (version, artifact, group).
86111
87112
Equivalent to:
88113
curl -X DELETE "<databusURI>" -H "accept: */*" -H "X-API-KEY: <key>"
89114
90-
Parameters:
91-
- databusURI: The full databus URI of the resource to delete
92-
- databus_key: Databus API key to authenticate the deletion request
93-
- dry_run: If True, do not perform the deletion but only print what would be deleted
94-
- force: If True, skip confirmation prompt and proceed with deletion
95-
- queue: If queue is provided, add the URI to the queue instead of deleting immediately
115+
Args:
116+
databusURI: The full databus URI of the resource to delete.
117+
databus_key: Databus API key to authenticate the deletion request.
118+
dry_run: If True, do not perform the deletion but only print what would be deleted.
119+
force: If True, skip confirmation prompt and proceed with deletion.
120+
queue: If queue is provided, add the URI to the queue instead of deleting immediately.
96121
"""
97122

98123
# Confirm the deletion request, skip the request or cancel deletion process
@@ -134,15 +159,14 @@ def _delete_list(
134159
force: bool = False,
135160
queue: DeleteQueue = None,
136161
):
137-
"""
138-
Delete a list of Databus resources.
139-
140-
Parameters:
141-
- databusURIs: List of full databus URIs of the resources to delete
142-
- databus_key: Databus API key to authenticate the deletion requests
143-
- dry_run: If True, do not perform the deletion but only print what would be deleted
144-
- force: If True, skip confirmation prompt and proceed with deletion
145-
- queue: If queue is provided, add the URIs to the queue instead of deleting immediately
162+
"""Delete a list of Databus resources.
163+
164+
Args:
165+
databusURIs: List of full databus URIs of the resources to delete.
166+
databus_key: Databus API key to authenticate the deletion requests.
167+
dry_run: If True, do not perform the deletion but only print what would be deleted.
168+
force: If True, skip confirmation prompt and proceed with deletion.
169+
queue: If queue is provided, add the URIs to the queue instead of deleting immediately.
146170
"""
147171
for databusURI in databusURIs:
148172
_delete_resource(
@@ -157,18 +181,17 @@ def _delete_artifact(
157181
force: bool = False,
158182
queue: DeleteQueue = None,
159183
):
160-
"""
161-
Delete an artifact and all its versions.
184+
"""Delete an artifact and all its versions.
162185
163186
This function first retrieves all versions of the artifact and then deletes them one by one.
164187
Finally, it deletes the artifact itself.
165188
166-
Parameters:
167-
- databusURI: The full databus URI of the artifact to delete
168-
- databus_key: Databus API key to authenticate the deletion requests
169-
- dry_run: If True, do not perform the deletion but only print what would be deleted
170-
- force: If True, skip confirmation prompt and proceed with deletion
171-
- queue: If queue is provided, add the URI to the queue instead of deleting immediately
189+
Args:
190+
databusURI: The full databus URI of the artifact to delete.
191+
databus_key: Databus API key to authenticate the deletion requests.
192+
dry_run: If True, do not perform the deletion but only print what would be deleted.
193+
force: If True, skip confirmation prompt and proceed with deletion.
194+
queue: If queue is provided, add the URI to the queue instead of deleting immediately.
172195
"""
173196
artifact_body = fetch_databus_jsonld(databusURI, databus_key)
174197

@@ -204,18 +227,17 @@ def _delete_group(
204227
force: bool = False,
205228
queue: DeleteQueue = None,
206229
):
207-
"""
208-
Delete a group and all its artifacts and versions.
230+
"""Delete a group and all its artifacts and versions.
209231
210232
This function first retrieves all artifacts of the group, then deletes each artifact (which in turn deletes its versions).
211233
Finally, it deletes the group itself.
212234
213-
Parameters:
214-
- databusURI: The full databus URI of the group to delete
215-
- databus_key: Databus API key to authenticate the deletion requests
216-
- dry_run: If True, do not perform the deletion but only print what would be deleted
217-
- force: If True, skip confirmation prompt and proceed with deletion
218-
- queue: If queue is provided, add the URI to the queue instead of deleting immediately
235+
Args:
236+
databusURI: The full databus URI of the group to delete.
237+
databus_key: Databus API key to authenticate the deletion requests.
238+
dry_run: If True, do not perform the deletion but only print what would be deleted.
239+
force: If True, skip confirmation prompt and proceed with deletion.
240+
queue: If queue is provided, add the URI to the queue instead of deleting immediately.
219241
"""
220242
group_body = fetch_databus_jsonld(databusURI, databus_key)
221243

@@ -242,17 +264,16 @@ def _delete_group(
242264

243265

244266
def delete(databusURIs: List[str], databus_key: str, dry_run: bool, force: bool):
245-
"""
246-
Delete a dataset from the databus.
267+
"""Delete a dataset from the databus.
247268
248269
Delete a group, artifact, or version identified by the given databus URI.
249270
Will recursively delete all data associated with the dataset.
250271
251-
Parameters:
252-
- databusURIs: List of full databus URIs of the resources to delete
253-
- databus_key: Databus API key to authenticate the deletion requests
254-
- dry_run: If True, will only print what would be deleted without performing actual deletions
255-
- force: If True, skip confirmation prompt and proceed with deletion
272+
Args:
273+
databusURIs: List of full databus URIs of the resources to delete.
274+
databus_key: Databus API key to authenticate the deletion requests.
275+
dry_run: If True, will only print what would be deleted without performing actual deletions.
276+
force: If True, skip confirmation prompt and proceed with deletion.
256277
"""
257278

258279
queue = DeleteQueue(databus_key)

0 commit comments

Comments
 (0)