Skip to content

Commit 55c7792

Browse files
committed
Merge branch 'main' into omar/automate-wheel-build
2 parents 0a8e17a + 6885d22 commit 55c7792

File tree

17 files changed

+221
-89
lines changed

17 files changed

+221
-89
lines changed

.github/workflows/validate.yml

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@ on:
1313

1414
jobs:
1515

16-
integration-test-trusted:
16+
test-trusted:
1717
# actions that are trusted by default must only be opened from within the repo, and skipped for forks because they'll fail there
1818
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository
1919
strategy:
2020
matrix:
2121
os: [ubuntu-latest, windows-latest, macos-latest]
22-
python-version: ["3.9", "3.10", "3.11", "3.12"]
22+
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
2323
runs-on: ${{ matrix.os }}
2424
steps:
2525
- uses: actions/checkout@v3
@@ -35,7 +35,15 @@ jobs:
3535
pip install pytest-asyncio &&
3636
pip install pydantic &&
3737
python -m pytest src/onepassword/test_client.py
38-
38+
- name: Example Test
39+
if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.9'
40+
env:
41+
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.EXAMPLE_TESTS_OP_SERVICE_ACCOUNT_TOKEN }}
42+
OP_VAULT_ID: ${{ secrets.EXAMPLE_TESTS_OP_VAULT_ID }}
43+
run: |
44+
pip install cryptography &&
45+
pip install . &&
46+
python example/example.py
3947
lint:
4048
name: Lint
4149
runs-on: ubuntu-latest
@@ -84,7 +92,7 @@ jobs:
8492
uses: actions/setup-python@v4
8593
with:
8694
python-version: '3.x'
87-
95+
8896
- name: Integration Test
8997
env:
9098
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.TEST_SERVICE_ACCOUNT_TOKEN }}
@@ -94,8 +102,14 @@ jobs:
94102
pip install pydantic &&
95103
python -m pytest src/onepassword/test_client.py
96104
97-
- run: |
98-
echo "Integration tests completed successfully!"
105+
- name: Example Test
106+
if: matrix.os == 'ubuntu-latest'
107+
env:
108+
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.TEST_SERVICE_ACCOUNT_TOKEN }}
109+
OP_VAULT_ID: ${{ secrets.TEST_SERVICE_ACCOUNT_VAULT_ID }}
110+
run: |
111+
pip install . &&
112+
python example/example.py
99113
100114
# Update check run called "integration-fork" on the forked PR
101115
- uses: actions/github-script@v6
@@ -105,7 +119,7 @@ jobs:
105119
job: ${{ github.job }}
106120
ref: ${{ github.event.client_payload.pull_request.head.sha }}
107121
# Conveniently, job.status maps to https://developer.github.com/v3/checks/runs/#update-a-check-run
108-
conclusion: ${{ job.status }}
122+
conclusion: ${{ job.status }}
109123
with:
110124
github-token: ${{ secrets.GITHUB_TOKEN }}
111125
script: |

example/README.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# Examples
2+
This folder contains a code snippet demonstrating how to use the 1Password Python SDK for performing various operations on 1Password vaults and items. Specifically, the example showcases how to:
3+
4+
- Authenticate with the 1Password API using a service account token.
5+
- List available vaults and items within those vaults.
6+
- Retrieve a specific secret and resolve a one-time password (TOTP).
7+
- Create a new item in a vault with multiple fields and tags.
8+
- Update an existing item by modifying its fields and adding a new website.
9+
- Generate different types of passwords (PIN, memorable, and random).
10+
- Share an item with valid recipients and create a shareable link.
11+
- Archive or delete items from the vault.
12+
- Create and manage SSH key items.
13+
- Create and manage document items, including replacing and reading documents.
14+
- Create and manage file field items by attaching and deleting files.
15+
16+
## Prerequisites
17+
18+
1. Clone the repository and follow the steps to [get started](https://github.com/1Password/onepassword-sdk-python/blob/main/README.md).
19+
2. Ensure that you have a valid service account token by exporting it as an environment variable:
20+
```bash
21+
export OP_SERVICE_ACCOUNT_TOKEN="<your token>"
22+
```
23+
3. Export the vault UUID you wish to interact with as an environment variable:
24+
```bash
25+
export OP_VAULT_ID="<your vault uuid>"
26+
```
27+
28+
## How to Run
29+
30+
To run the example file, navigate to project root directory and run:
31+
```bash
32+
python example/example.py
33+
```
34+
35+
## Terminal Output
36+
37+
When running the example, the terminal will display:
38+
39+
- A list of vaults and items.
40+
- Retrieved secrets and TOTP codes.
41+
- Details of newly created and updated items.
42+
- Generated passwords (PIN, memorable, random).
43+
- A shareable link for shared items.
44+
- SSH key attributes like public key and fingerprint.
45+
- Document content after replacing the file.
46+
- A list of file field items and file deletions.
47+
48+
These outputs show the results of vault and item operations, password generation, item sharing, and management of SSH and document items.

example/example.py

Lines changed: 39 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,26 @@ async def main():
2525
# [developer-docs.sdk.python.client-initialization]-end
2626

2727
# [developer-docs.sdk.python.list-vaults]-start
28-
vaults = await client.vaults.list_all()
29-
async for vault in vaults:
28+
vaults = await client.vaults.list()
29+
for vault in vaults:
3030
print(vault.title)
3131
# [developer-docs.sdk.python.list-vaults]-end
3232

3333
# [developer-docs.sdk.python.list-items]-start
34-
items = await client.items.list_all(vault.id)
35-
async for item in items:
36-
print(item.title)
34+
overviews = await client.items.list(vault.id)
35+
for overview in overviews:
36+
print(overview.title)
3737
# [developer-docs.sdk.python.list-items]-end
38-
38+
# [developer-docs.sdk.python.use-item-filters]-start
39+
archived_overviews = await client.items.list(
40+
vault.id,
41+
ItemListFilterByState(
42+
content=ItemListFilterByStateInner(active=False, archived=True)
43+
),
44+
)
45+
for overview in archived_overviews:
46+
print(overview.title)
47+
# [developer-docs.sdk.python.use-item-filters]-end
3948
# [developer-docs.sdk.python.validate-secret-reference]-start
4049
# Validate secret reference to ensure no syntax errors
4150
try:
@@ -44,18 +53,16 @@ async def main():
4453
print(error)
4554
# [developer-docs.sdk.python.validate-secret-reference]-end
4655

47-
# [developer-docs.sdk.python.resolve-secret]-start
48-
# Retrieves a secret from 1Password. Takes a secret reference as input and returns the secret to which it points.
49-
value = await client.secrets.resolve("op://vault/item/field")
50-
print(value)
51-
# [developer-docs.sdk.python.resolve-secret]-end
56+
vault_id= os.getenv("OP_VAULT_ID")
57+
if vault_id is None:
58+
raise Exception("OP_VAULT_ID environment variable is not set")
5259

5360
# [developer-docs.sdk.python.create-item]-start
5461
# Create an Item and add it to your vault.
5562
to_create = ItemCreateParams(
5663
title="MyName",
5764
category=ItemCategory.LOGIN,
58-
vault_id="7turaasywpymt3jecxoxk5roli",
65+
vault_id=vault_id,
5966
fields=[
6067
ItemField(
6168
id="username",
@@ -95,6 +102,12 @@ async def main():
95102

96103
print(dict(created_item))
97104

105+
# [developer-docs.sdk.python.resolve-secret]-start
106+
# Retrieves a secret from 1Password. Takes a secret reference as input and returns the secret to which it points.
107+
value = await client.secrets.resolve(f"op://{created_item.vault_id}/{created_item.id}/username")
108+
print(value)
109+
# [developer-docs.sdk.python.resolve-secret]-end
110+
98111
# [developer-docs.sdk.python.resolve-totp-code]-start
99112
# Retrieves a secret from 1Password. Takes a secret reference as input and returns the secret to which it points.
100113
code = await client.secrets.resolve(
@@ -171,24 +184,22 @@ async def main():
171184
print(random_password)
172185
# [developer-docs.sdk.python.generate-random-password]-end
173186

174-
await share_item(client, created_item.vault_id, updated_item.id)
187+
await share_item(client, updated_item.vault_id, updated_item.id)
188+
189+
await create_ssh_key_item(client, vault_id)
175190

176-
await create_ssh_key_item(client)
191+
await create_and_replace_document_item(client, vault_id)
177192

178-
await create_and_replace_document_item(client)
193+
await create_attach_and_delete_file_field_item(client, vault_id)
179194

180-
await create_attach_and_delete_file_field_item(client)
195+
await archive_item(client, updated_item.vault_id, updated_item.id)
181196

182197
# [developer-docs.sdk.python.delete-item]-start
183198
# Delete a item from your vault.
184199
await client.items.delete(created_item.vault_id, updated_item.id)
185200
# [developer-docs.sdk.python.delete-item]-end
186201

187202

188-
## NOTE: this is in a separate function to avoid creating a new item
189-
## NOTE: just for the sake of archiving it. This is because the SDK
190-
## NOTE: only works with active items, so archiving and then deleting
191-
## NOTE: is not yet possible.
192203
async def archive_item(client: Client, vault_id: str, item_id: str):
193204
# [developer-docs.sdk.python.archive-item]-start
194205
# Archive a item from your vault.
@@ -230,7 +241,7 @@ async def share_item(client: Client, vault_id: str, item_id: str):
230241
# [developer-docs.sdk.python.item-share-create-share]-end
231242

232243

233-
async def create_ssh_key_item(client: Client):
244+
async def create_ssh_key_item(client: Client, vault_id: str):
234245
# [developer-docs.sdk.python.create-sshkey-item]-start
235246
# Generate a 2048-bit RSA private key
236247
private_key = rsa.generate_private_key(
@@ -249,7 +260,7 @@ async def create_ssh_key_item(client: Client):
249260
to_create = ItemCreateParams(
250261
title="SSH Key Item Created With Python SDK",
251262
category=ItemCategory.SSHKEY,
252-
vault_id="7turaasywpymt3jecxoxk5roli",
263+
vault_id=vault_id,
253264
fields=[
254265
ItemField(
255266
id="private_key",
@@ -273,13 +284,13 @@ async def create_ssh_key_item(client: Client):
273284
await client.items.delete(created_item.vault_id, created_item.id)
274285

275286

276-
async def create_and_replace_document_item(client: Client):
287+
async def create_and_replace_document_item(client: Client, vault_id: str):
277288
# [developer-docs.sdk.python.create-document-item]-start
278289
# Create a Document Item
279290
to_create = ItemCreateParams(
280291
title="Document Item Created with Python SDK",
281292
category=ItemCategory.DOCUMENT,
282-
vault_id="7turaasywpymt3jecxoxk5roli",
293+
vault_id=vault_id,
283294
sections=[
284295
ItemSection(id="", title=""),
285296
],
@@ -312,13 +323,13 @@ async def create_and_replace_document_item(client: Client):
312323
await client.items.delete(replaced_item.vault_id, replaced_item.id)
313324

314325

315-
async def create_attach_and_delete_file_field_item(client: Client):
326+
async def create_attach_and_delete_file_field_item(client: Client, vault_id: str):
316327
# [developer-docs.sdk.python.create-item-with-file-field]-start
317328
# Create a File Field Item
318329
to_create = ItemCreateParams(
319330
title="FileField Item created with Python SDK",
320331
category=ItemCategory.LOGIN,
321-
vault_id="7turaasywpymt3jecxoxk5roli",
332+
vault_id=vault_id,
322333
fields=[
323334
ItemField(
324335
id="username",
@@ -388,10 +399,10 @@ async def resolve_all_secrets(
388399
client: Client, vault_id: str, item_id: str, field_id: str, field_id2: str
389400
):
390401
# [developer-docs.sdk.python.resolve-bulk-secret]-start
391-
# Retrieves multiple secret from 1Password.
402+
# Retrieves multiple secrets from 1Password.
392403
secrets = await client.secrets.resolve_all(
393404
[
394-
f"op://{vault_id}//{item_id}/{field_id}",
405+
f"op://{vault_id}/{item_id}/{field_id}",
395406
f"op://{vault_id}/{item_id}/{field_id2}",
396407
]
397408
)

src/onepassword/build_number.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
SDK_BUILD_NUMBER = "0020101"
1+
SDK_BUILD_NUMBER = "0030001"

src/onepassword/items.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
# Code generated by op-codegen - DO NO EDIT MANUALLY
22

33
from .core import _invoke, _invoke_sync
4-
from .iterator import SDKIterator
54
from typing import Optional, List
65
from pydantic import TypeAdapter
76
from .items_shares import ItemsShares
87
from .items_files import ItemsFiles
9-
from .types import Item, ItemCreateParams, ItemOverview
8+
from .types import Item, ItemCreateParams, ItemListFilter, ItemOverview
109

1110

1211
class Items:
@@ -113,21 +112,24 @@ async def archive(self, vault_id: str, item_id: str) -> None:
113112

114113
return None
115114

116-
async def list_all(self, vault_id: str) -> SDKIterator[ItemOverview]:
115+
async def list(self, vault_id: str, *filters: ItemListFilter) -> List[ItemOverview]:
117116
"""
118-
List all items
117+
List items based on filters.
119118
"""
120119
response = await _invoke(
121120
{
122121
"invocation": {
123122
"clientId": self.client_id,
124123
"parameters": {
125-
"name": "ItemsListAll",
126-
"parameters": {"vault_id": vault_id},
124+
"name": "ItemsList",
125+
"parameters": {
126+
"vault_id": vault_id,
127+
"filters": [o.model_dump(by_alias=True) for o in filters],
128+
},
127129
},
128130
}
129131
}
130132
)
131133

132134
response = TypeAdapter(List[ItemOverview]).validate_json(response)
133-
return SDKIterator(response)
135+
return response

src/onepassword/items_files.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
# Code generated by op-codegen - DO NO EDIT MANUALLY
22

33
from .core import _invoke, _invoke_sync
4-
from .iterator import SDKIterator
54
from typing import Optional, List
65
from pydantic import TypeAdapter
76
from .types import DocumentCreateParams, FileAttributes, FileCreateParams, Item

src/onepassword/items_shares.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
# Code generated by op-codegen - DO NO EDIT MANUALLY
22

33
from .core import _invoke, _invoke_sync
4-
from .iterator import SDKIterator
54
from typing import Optional, List
65
from pydantic import TypeAdapter
76
from .types import Item, ItemShareAccountPolicy, ItemShareParams, ValidRecipient

src/onepassword/iterator.py

Lines changed: 0 additions & 25 deletions
This file was deleted.

0 commit comments

Comments
 (0)