Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Python-pyo3: add library interface #566

Merged
merged 40 commits into from
Nov 14, 2024
Merged
Show file tree
Hide file tree
Changes from 39 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
0964cb6
cargo update
Esgrove Nov 12, 2024
81cf61d
rename p_vault to n_vault again and move cli to cli.py
Esgrove Nov 12, 2024
610c420
expose list_all and lookup from rust library
Esgrove Nov 12, 2024
6135a41
output binary data in base64
Esgrove Nov 12, 2024
98771bb
rust fixes
Esgrove Nov 12, 2024
ed71953
add license texts
Esgrove Nov 12, 2024
a8feeee
implement store, exists, and delete
Esgrove Nov 12, 2024
52e6dcc
update pyproject information
Esgrove Nov 12, 2024
2d28968
add integration test cases for python library
Esgrove Nov 12, 2024
e21b8f0
tweak comment
Esgrove Nov 12, 2024
db45f2a
fix integration test trigger for PRs
Esgrove Nov 12, 2024
784caf3
cancel previous runs for PR wheel build
Esgrove Nov 12, 2024
5c75a50
fix store when input argument is a string
Esgrove Nov 12, 2024
2b2a55a
fix empty string for print end arg
Esgrove Nov 12, 2024
979c9aa
add extra rust cache key for release build
Esgrove Nov 12, 2024
47f28e1
convert lookup bytes output to string
Esgrove Nov 12, 2024
1b44ce5
workaround list all case since there seems to be unexpected extra keys
Esgrove Nov 12, 2024
cbb3378
remove unneeded decode from python rust lib test
Esgrove Nov 12, 2024
045fc0e
add `delete_many` to library
Esgrove Nov 12, 2024
cb1728f
fix wc -l to not count empty lines
Esgrove Nov 12, 2024
3b6b9c1
remove extra list all
Esgrove Nov 12, 2024
5714c02
add readme section for python library usage
Esgrove Nov 12, 2024
41d3a7c
support specifying vault parameters
Esgrove Nov 12, 2024
80b646a
add init and update
Esgrove Nov 13, 2024
84982e5
add stack status
Esgrove Nov 13, 2024
80698cd
return python dict
Esgrove Nov 13, 2024
892928e
update docstrings for library functions
Esgrove Nov 13, 2024
0fe5e2f
docstrings for all public library methods
Esgrove Nov 13, 2024
a92879c
match parameter names to old python library
Esgrove Nov 13, 2024
7014b9d
fix variable rename
Esgrove Nov 13, 2024
af6625d
make type hinting compatible with python 3.9
Esgrove Nov 13, 2024
8079b2b
fix help output when no arguments are given
Esgrove Nov 13, 2024
bc045d8
rename and reorder vault class parameters to match previous version
Esgrove Nov 13, 2024
a1143fc
add direct encrypt and decrypt
Esgrove Nov 13, 2024
d638dda
return bytes from direct encrypt and decrypt
Esgrove Nov 13, 2024
8dfea46
fix type hints for 3.9 :(
Esgrove Nov 13, 2024
a903504
ignore all venvs
Esgrove Nov 13, 2024
91e94ed
match parameter name for direct decrypt
Esgrove Nov 13, 2024
b287d34
cargo update
Esgrove Nov 13, 2024
5f2996a
fix typo in helper function name
Esgrove Nov 14, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 63 additions & 5 deletions .github/workflows/integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ on:
paths:
- "!**/README.md"
pull_request:
paths:
- "!**/README.md"

permissions:
id-token: write
Expand Down Expand Up @@ -37,6 +35,9 @@ jobs:

- uses: Swatinem/[email protected]
if: ${{ matrix.lang == 'rust'}}
with:
# The build script creates a `release` build so use separate cache
key: "release"

- uses: actions/setup-go@v5
if: ${{ matrix.lang == 'go'}}
Expand Down Expand Up @@ -218,9 +219,6 @@ jobs:
- name: Delete secret with Rust
run: bin/rust/vault -d "secret-${{github.sha}}.zip"

- name: Verify that key has been deleted with Rust
run: bin/rust/vault exists secret-${{github.sha}}.zip | grep -q "does not exist"

- name: Verify that keys have been deleted using Rust
run: |
bin/rust/vault exists secret-python | grep -q "key 'secret-python' does not exist"
Expand All @@ -229,6 +227,33 @@ jobs:
bin/rust/vault exists secret-rust | grep -q "key 'secret-rust' does not exist"
bin/rust/vault exists secret-nodejs | grep -q "key 'secret-nodejs' does not exist"

- name: Check Python vault package
run: python -m pip show nitor-vault

- name: Store secret using Python library
run: |
python -c "from n_vault import Vault; Vault().store('secret-python-library', 'sha-${{github.sha}}')"

- name: Verify secret using Python library
run: |
python -c "from n_vault import Vault; print('true') if Vault().exists('secret-python-library') else print('false')" | grep -q "true"

- name: Validate storing worked with Rust
run: diff <(bin/rust/vault -l secret-python-library) <(echo -n sha-${{github.sha}})

- name: Lookup with Python library
run: |
diff <(python -c "from n_vault import Vault; print(Vault().lookup('secret-python-library').decode('utf-8'), end='', flush=True)") <(echo -n sha-${{github.sha}})

- name: List with Python library
run: python -c "from n_vault import Vault; print('\n'.join(Vault().list_all()))"

- name: Delete with Python library
run: python -c "from n_vault import Vault; Vault().delete('secret-python-library')"

- name: Verify that key has been deleted with Rust
run: bin/rust/vault exists secret-python-library | grep -q "key 'secret-python-library' does not exist"

- name: Install Python PyO3 vault
run: python -m pip install --force-reinstall .
working-directory: python-pyo3
Expand Down Expand Up @@ -310,3 +335,36 @@ jobs:

- name: Verify that key has been deleted with Python-pyo3
run: vault exists secret-${{github.sha}}.zip | grep -q "does not exist"

- name: Check Python vault package
run: python -m pip show nitor-vault

- name: Delete all keys with Python library
run: python -c "from n_vault import Vault; Vault().delete_many(Vault().list_all())"

- name: List with Python library
run: python -c "from n_vault import Vault; print('\n'.join(Vault().list_all()))" | grep -ve '^\s*$' | wc -l | grep -q "0"

- name: Store secret using Python library
run: |
python -c "from n_vault import Vault; Vault().store('secret-python-library', 'sha-${{github.sha}}')"

- name: Verify secret using Python library
run: |
python -c "from n_vault import Vault; print('true') if Vault().exists('secret-python-library') else print('false')" | grep -q "true"

- name: Validate storing worked with Rust
run: diff <(bin/rust/vault -l secret-python-library) <(echo -n sha-${{github.sha}})

- name: Lookup with Python library
run: |
diff <(python -c "from n_vault import Vault; print(Vault().lookup('secret-python-library'), end='', flush=True)") <(echo -n sha-${{github.sha}})

- name: List with Python library
run: python -c "from n_vault import Vault; print('\n'.join(Vault().list_all()))" | wc -l | grep -q "1"

- name: Delete with Python library
run: python -c "from n_vault import Vault; Vault().delete('secret-python-library')"

- name: Verify that key has been deleted with Rust
run: bin/rust/vault exists secret-python-library | grep -q "key 'secret-python-library' does not exist"
5 changes: 5 additions & 0 deletions .github/workflows/python-wheel.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ on:
permissions:
contents: read

# Cancel previous runs for PRs but not pushes to main
concurrency:
group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.head_ref || github.sha }}
cancel-in-progress: true

jobs:
linux:
runs-on: ${{ matrix.platform.runner }}
Expand Down
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ celerybeat-schedule
.env

# virtualenv
venv/
venv*/
.venv*/
ENV/

# Spyder project settings
Expand Down Expand Up @@ -112,4 +113,3 @@ dependency-reduced-pom.xml
# Go binary
/go/vault
/go/vault
.venv
36 changes: 18 additions & 18 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ resolver = "2"

[workspace.package]
edition = "2021"
version = "2.1.2"
version = "2.2.0"

[profile.release]
lto = "thin"
42 changes: 35 additions & 7 deletions python-pyo3/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Python vault implementation using the Rust vault library.

See the [repo](https://github.com/NitorCreations/vault) root readme for more general information.

## Usage
## Vault CLI

```console
Encrypted AWS key-value storage utility
Expand Down Expand Up @@ -40,12 +40,13 @@ Options:
-V, --version Print version
```

## Install
### Install

### From PyPI
#### From PyPI

Use [pipx](https://github.com/pypa/pipx) or [uv](https://github.com/astral-sh/uv)
to install the Python vault package from [PyPI](https://pypi.org/project/nitor-vault/) globally in an isolated environment.
to install the Python vault package from [PyPI](https://pypi.org/project/nitor-vault/)
globally in an isolated environment.

```shell
pipx install nitor-vault
Expand All @@ -55,7 +56,7 @@ uv tool install nitor-vault

The command `vault` should now be available in path.

### From source
#### From source

Build and install locally from source code using pip.
This requires a [Rust toolchain](https://rustup.rs/) to be able to build the Rust library.
Expand All @@ -77,6 +78,33 @@ and will not be available in path globally.
which -a vault
```

## Vault library

This Python package can also be used as a Python library to interact with the Vault directly from Python code.

Add the `nitor-vault` package to your project dependencies,
or install directly with pip.

Example usage:

```python
from n_vault import Vault

if not Vault().exists("key"):
Vault().store("key", "value")

keys = Vault().list_all()

value = Vault().lookup("key")

if Vault().exists("key"):
Vault().delete("key")

# specify vault parameters
vault = Vault(vault_stack="stack-name", profile="aws-credentials-name")
value = vault.lookup("key")
```

## Development

Uses:
Expand Down Expand Up @@ -112,9 +140,9 @@ Run Python CLI:

```shell
# uv
uv run python/p_vault/vault.py -h
uv run python/n_vault/cli.py -h
# venv
python3 python/p_vault/vault.py -h
python3 python/n_vault/cli.py -h
```

Install and run vault inside virtual env:
Expand Down
15 changes: 8 additions & 7 deletions python-pyo3/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,23 @@ authors = [
{ name = "Pasi Niemi", email = "[email protected]" },
{ name = "Akseli Lukkarila", email = "[email protected]" },
]
license = { text = "Apache 2.0" }
license = { text = "Apache-2.0" }
classifiers = [
"Programming Language :: Rust",
"Programming Language :: Python :: Implementation :: CPython",
]
dependencies = []

[project.optional-dependencies]
build = ["maturin", "twine", "wheel"]
dev = ["ruff"]
build = ["maturin", "wheel"]
dev = ["maturin", "ruff"]

[project.urls]
Repository = "https://github.com/NitorCreations/vault"
Homepage = "https://github.com/NitorCreations/vault"

[project.scripts]
vault = "p_vault.vault:main"
vault = "n_vault.cli:main"

[build-system]
requires = ["maturin>=1.7,<2.0"]
Expand All @@ -46,9 +47,9 @@ build-backend = "maturin"
[tool.maturin]
bindings = "pyo3"
features = ["pyo3/extension-module"]
module-name = "p_vault.nitor_vault_rs"
module-name = "n_vault.nitor_vault_rs"
profile = "release"
python-packages = ["p_vault"]
python-packages = ["n_vault"]
python-source = "python"
strip = true

Expand All @@ -59,7 +60,7 @@ venv = ".venv"
[tool.ruff]
# https://docs.astral.sh/ruff/configuration/
include = ["*.py", "*.pyi", "**/pyproject.toml"]
target-version = "py311"
target-version = "py39"
line-length = 120

[tool.ruff.lint]
Expand Down
Loading
Loading