Skip to content

Commit

Permalink
Merge pull request #207 from zcutlip/development
Browse files Browse the repository at this point in the history
merge development into main: v5.1.0
  • Loading branch information
zcutlip authored Nov 22, 2024
2 parents 1002189 + c1f9aac commit 26501a5
Show file tree
Hide file tree
Showing 74 changed files with 931 additions and 54 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/testing-linting.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest]
python: ["3.9", "3.10", "3.11", "3.12"]
python: ["3.10", "3.11", "3.12", "3.13"]

steps:
- uses: actions/checkout@v4
Expand Down
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
rev: v5.0.0
hooks:
- id: check-json
exclude: ^\.vscode\/.*$
- id: check-yaml
- id: check-merge-conflict
- repo: https://github.com/PyCQA/flake8
rev: 7.1.0
rev: 7.1.1
hooks:
- id: flake8
- repo: https://github.com/hhatto/autopep8
Expand Down
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@
"3"
],
"search.useIgnoreFiles": true,
"makefile.configureOnOpen": false,

}
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,17 @@

All notable changes to this project will be documented in this file.

## [5.1.0] 2024-11-21

### Added

- Item sharing (gh-202)
- `OP.item_share()`

### Changed
- Added Python 3.13 support (gh-204)
- Removed Python 3.9 support (gh-204)

## [5.0.1] 2024-08-03

### Fixed
Expand Down
7 changes: 7 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,10 @@ clean-coverage:
-rm $(COV_STAMP)
-rm $(HTML_REPORT_STAMP)
-rm $(COV_REPORT_FILE)

clean: clean-coverage
-rm -r .*cache
-rm -r .tox*
-rm -r build
-rm -r .ipynb_checkpoints
-rm -r *egg-info
34 changes: 33 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ A Python API to sign into and query a 1Password account using the `op` command.

## Requirements

- Python >= 3.9
- Python >= 3.10
- 1Password command-line tool >= 2.26.0
- Versions >= 2.21.0, < 2.26.0 supported but deprecated
- Versions < 2.21.0 are unsupported and an exception will be raised
Expand Down Expand Up @@ -349,6 +349,38 @@ def main():
print(ope.err_output)
```

### Item Sharing

To generate a URL for sharing an item, use the `OP.item_share()` method. This is congruent to the `op item share` subcommand.

> NOTE: There is no way to revoke a share URL via `pyonepassword` or the `op` CLI command. It can be revoked in the 1Password application.
> NOTE: The `emails=` kwarg may be omitted or be an empty list. In this case the share URL returned will not be restricted. Anyone who has the URL may view the shared item.
Some of the parameters passed to `item_share()` are not validated by `pyonepassword`, but are validated by the `op` command. These include the expiration and email addresses.

Additionally, the email addresses may be a list of email address strings or a string object for one single email address.

```python
from pyonepassword import OP # noqa: E402
from pyonepassword.api.exceptions import OPItemShareException # noqa: E402


def main():
op: OP = do_signin()
try:
# op.item_share() can take any identifier accepted by the 'op' command:
# Usage: op item share { <itemName> | <itemID> }
share_url = op.item_share("Example Login Item 22", ["[email protected]", "[email protected]"], expires_in="2d")
print(share_url)
except OPItemShareException as ope:
# 'op' command can fail for a few reaons, including
# - item not found
# - duplicate item names
# - malformed emails or expiration duration
# Inspect the error message from the command
print(ope.err_output)
```

### Item Creation

Expand Down
34 changes: 33 additions & 1 deletion _readme_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ A Python API to sign into and query a 1Password account using the `op` command.

## Requirements

- Python >= 3.9
- Python >= 3.10
- 1Password command-line tool >= SUPPORTED_CLI_VERSION__
- Versions >= MINIMUM_CLI_VERSION__, < SUPPORTED_CLI_VERSION__ supported but deprecated
- Versions < MINIMUM_CLI_VERSION__ are unsupported and an exception will be raised
Expand Down Expand Up @@ -349,6 +349,38 @@ def main():
print(ope.err_output)
```

### Item Sharing

To generate a URL for sharing an item, use the `OP.item_share()` method. This is congruent to the `op item share` subcommand.

> NOTE: There is no way to revoke a share URL via `pyonepassword` or the `op` CLI command. It can be revoked in the 1Password application.
> NOTE: The `emails=` kwarg may be omitted or be an empty list. In this case the share URL returned will not be restricted. Anyone who has the URL may view the shared item.
Some of the parameters passed to `item_share()` are not validated by `pyonepassword`, but are validated by the `op` command. These include the expiration and email addresses.

Additionally, the email addresses may be a list of email address strings or a string object for one single email address.

```python
from pyonepassword import OP # noqa: E402
from pyonepassword.api.exceptions import OPItemShareException # noqa: E402


def main():
op: OP = do_signin()
try:
# op.item_share() can take any identifier accepted by the 'op' command:
# Usage: op item share { <itemName> | <itemID> }
share_url = op.item_share("Example Login Item 22", ["[email protected]", "[email protected]"], expires_in="2d")
print(share_url)
except OPItemShareException as ope:
# 'op' command can fail for a few reaons, including
# - item not found
# - duplicate item names
# - malformed emails or expiration duration
# Inspect the error message from the command
print(ope.err_output)
```

### Item Creation

Expand Down
52 changes: 52 additions & 0 deletions dev-docs/updating-python-support.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Updating Python Support

This file documents how to add a new python version and/or remove an old one to automated testing and GitHub CI.

To add python 3.13 & remove python 3.9:


Files to update:

- tox.ini
- replace all cases of `39,310,311,312` with `310,311,312,313`
- setup.py
- update minimum python: `python_requires='>=3.10'`
- update `classifiers`:

```"Programming Language :: Python :: 3.13"```
- Docker:
- rename py39.Dockerfile to py313.Dockerfile
- replace '3.9' with '3.13' globally
- replace 'py39' with 'py313' globally
- `clean.sh`
- add `docker_py313` to `docker image rm` command
- it's okay to leave `docker_py39` to ensure it gets removed
- If there's a really old docker python image, e.g., `docker_py38`, go ahead and remove that
- `build.sh`
- copy 'docker buildx' command for python 3.12
- replace all `py312` with `py313`
- delete `docker buildx` command for python 3.9
- `run.sh`
- duplicate run command for `docker_py312`, replacing container name with `docker_py313`
- delete `docker run` command for python 3.9
- `run-individual.sh`
- duplicate `elif` clause for python 3.12, updating it to `docker_py312`
- delete `if-elif` clause for python 3.9
- update help message: `"Specify py310, py311, py312, or py313"`
- rennovate.json
- add dict for 3.13 dockerfile
- Note the name of the dockerfile, as well as `allowedVersions` key:
```
{
"matchPaths": ["docker_testing/docker/py313.Dockerfile"],
"matchPackageNames":["python"],
"allowedVersions": "3.13"
}
```
- remove dict for 3.9
- .github/workflows/testing-linting.yml
- update python version matrix: `["3.10", "3.11", "3.12", "3.13"]`
- _readme_template.md
- Update minimum python version under requirements
- README.md:
- run `scripts/update_readme.py` to apply changes to README.md
2 changes: 1 addition & 1 deletion docker_testing/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"

echo "Building..."

docker buildx build "$SCRIPT_DIR"/docker/ -f "$SCRIPT_DIR"/docker/py39.Dockerfile -t docker_py39 || exit
docker buildx build "$SCRIPT_DIR"/docker/ -f "$SCRIPT_DIR"/docker/py310.Dockerfile -t docker_py310 || exit
docker buildx build "$SCRIPT_DIR"/docker/ -f "$SCRIPT_DIR"/docker/py311.Dockerfile -t docker_py311 || exit
docker buildx build "$SCRIPT_DIR"/docker/ -f "$SCRIPT_DIR"/docker/py312.Dockerfile -t docker_py312 || exit
docker buildx build "$SCRIPT_DIR"/docker/ -f "$SCRIPT_DIR"/docker/py313.Dockerfile -t docker_py313 || exit

echo "...done"
echo ""
2 changes: 1 addition & 1 deletion docker_testing/clean.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# this should not be an error
echo "Cleaning..."
echo "removing docker images"
docker image rm docker_py38 docker_py39 docker_py310 docker_py311 docker_py312
docker image rm docker_py39 docker_py310 docker_py311 docker_py312 docker_py313
echo "removing .tox-docker"
rm -rf .tox-docker
echo "...done"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM python:3.9
FROM python:3.13

RUN useradd -ms /bin/bash unpriv

Expand All @@ -14,6 +14,6 @@ ENV TESTDIR=/usr/src/testdir
# PYVER_FACTOR gets passed to:
# tox run -f $PYVER_FACTOR
# so e.g., all py311-{something,something-else} envs get run
ENV PYVER_FACTOR=py39
ENV PYVER_FACTOR=py313
COPY test.sh /test.sh
CMD [ "/test.sh" ]
12 changes: 6 additions & 6 deletions docker_testing/run-individual.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,7 @@ trap handle_sig INT

container=""

if [ "$1" = "py39" ];
then
container="docker_py39"
shift
elif [ "$1" = "py310" ];
if [ "$1" = "py310" ];
then
container="docker_py310"
shift
Expand All @@ -35,11 +31,15 @@ elif [ "$1" = "py312" ];
then
container="docker_py312"
shift
elif [ "$1" = "py313" ];
then
container="docker_py313"
shift
fi

if [ -z "$container" ];
then
quit "Specify py39, py310, py311, or py312" 1
quit "Specify py310, py311, py312, or py313" 1
fi


Expand Down
4 changes: 2 additions & 2 deletions docker_testing/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@ trap handle_sig INT
ret=0

echo "Running docker tests..."
docker run --rm -it -v "$(pwd):/usr/src/testdir" docker_py39 /test.sh "$@"
ret="$(($?+ret))"
docker run --rm -it -v "$(pwd):/usr/src/testdir" docker_py310 /test.sh "$@"
ret="$(($?+ret))"
docker run --rm -it -v "$(pwd):/usr/src/testdir" docker_py311 /test.sh "$@"
ret="$(($?+ret))"
docker run --rm -it -v "$(pwd):/usr/src/testdir" docker_py312 /test.sh "$@"
ret="$(($?+ret))"
docker run --rm -it -v "$(pwd):/usr/src/testdir" docker_py313 /test.sh "$@"
ret="$(($?+ret))"

echo "...done"
echo ""
Expand Down
36 changes: 36 additions & 0 deletions examples/example-item-share.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import os
import sys

from do_signin import do_signin

parent_path = os.path.dirname(
os.path.dirname(
os.path.abspath(__file__)
)
)
# isort: split
if parent_path not in sys.path:
sys.path.append(parent_path)

from pyonepassword import OP # noqa: E402
from pyonepassword.api.exceptions import OPItemShareException # noqa: E402


def main():
op: OP = do_signin()
try:
# op.item_share() can take any identifier accepted by the 'op' command:
# Usage: op item share { <itemName> | <itemID> }
share_url = op.item_share("Example Login Item 22", [], expires_in="2d")
print(share_url)
except OPItemShareException as ope:
# 'op' command can fail for a few reaons, including
# - item not found
# - duplicate item names
# - malformed emails or expiration duration
# Inspect the error message from the command
print(ope.err_output)


if __name__ == "__main__":
main()
17 changes: 17 additions & 0 deletions ipython_snippets/item_share.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import os

from _util.functions import get_op
from dotenv import load_dotenv

from pyonepassword import OP
from pyonepassword.api.exceptions import OPCmdFailedException # noqa: F401

os.environ["LOG_OP_ERR"] = "1"
# load_dotenv("./dot_env_files/.env_pyonepassword_test_rw")


item_name = "Example Login Item 22"
vault = "Test Data 1"
emails = "[email protected]"
op = OP()
print(open(__file__, "r").read())
2 changes: 1 addition & 1 deletion pyonepassword/__about__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
__title__ = "pyonepassword"
__version__ = "5.0.1"
__version__ = "5.1.0"
__summary__ = "A python API to query a 1Password account using the 'op' command-line tool"

"""
Expand Down
Loading

0 comments on commit 26501a5

Please sign in to comment.