diff --git a/example/example.py b/example/example.py index 02996cd2..a2f3b293 100644 --- a/example/example.py +++ b/example/example.py @@ -25,17 +25,26 @@ async def main(): # [developer-docs.sdk.python.client-initialization]-end # [developer-docs.sdk.python.list-vaults]-start - vaults = await client.vaults.list_all() - async for vault in vaults: + vaults = await client.vaults.list() + for vault in vaults: print(vault.title) # [developer-docs.sdk.python.list-vaults]-end # [developer-docs.sdk.python.list-items]-start - items = await client.items.list_all(vault.id) - async for item in items: - print(item.title) + overviews = await client.items.list(vault.id) + for overview in overviews: + print(overview.title) # [developer-docs.sdk.python.list-items]-end - + # [developer-docs.sdk.python.use-item-filters]-start + archived_overviews = await client.items.list( + vault.id, + ItemListFilterByState( + content=ItemListFilterByStateInner(active=False, archived=True) + ), + ) + for overview in archived_overviews: + print(overview.title) + # [developer-docs.sdk.python.use-item-filters]-end # [developer-docs.sdk.python.validate-secret-reference]-start # Validate secret reference to ensure no syntax errors try: @@ -175,7 +184,7 @@ async def main(): print(random_password) # [developer-docs.sdk.python.generate-random-password]-end - await share_item(client, created_item.vault_id, updated_item.id) + await share_item(client, updated_item.vault_id, updated_item.id) await create_ssh_key_item(client, vault_id) @@ -183,16 +192,14 @@ async def main(): await create_attach_and_delete_file_field_item(client, vault_id) + await archive_item(client, updated_item.vault_id, updated_item.id) + # [developer-docs.sdk.python.delete-item]-start # Delete a item from your vault. await client.items.delete(created_item.vault_id, updated_item.id) # [developer-docs.sdk.python.delete-item]-end -## NOTE: this is in a separate function to avoid creating a new item -## NOTE: just for the sake of archiving it. This is because the SDK -## NOTE: only works with active items, so archiving and then deleting -## NOTE: is not yet possible. async def archive_item(client: Client, vault_id: str, item_id: str): # [developer-docs.sdk.python.archive-item]-start # Archive a item from your vault. diff --git a/src/onepassword/build_number.py b/src/onepassword/build_number.py index 595a8ca9..01889e45 100644 --- a/src/onepassword/build_number.py +++ b/src/onepassword/build_number.py @@ -1 +1 @@ -SDK_BUILD_NUMBER = "0020101" +SDK_BUILD_NUMBER = "0030001" diff --git a/src/onepassword/items.py b/src/onepassword/items.py index 8d0bf013..0093e00d 100644 --- a/src/onepassword/items.py +++ b/src/onepassword/items.py @@ -1,12 +1,11 @@ # Code generated by op-codegen - DO NO EDIT MANUALLY from .core import _invoke, _invoke_sync -from .iterator import SDKIterator from typing import Optional, List from pydantic import TypeAdapter from .items_shares import ItemsShares from .items_files import ItemsFiles -from .types import Item, ItemCreateParams, ItemOverview +from .types import Item, ItemCreateParams, ItemListFilter, ItemOverview class Items: @@ -113,21 +112,24 @@ async def archive(self, vault_id: str, item_id: str) -> None: return None - async def list_all(self, vault_id: str) -> SDKIterator[ItemOverview]: + async def list(self, vault_id: str, *filters: ItemListFilter) -> List[ItemOverview]: """ - List all items + List items based on filters. """ response = await _invoke( { "invocation": { "clientId": self.client_id, "parameters": { - "name": "ItemsListAll", - "parameters": {"vault_id": vault_id}, + "name": "ItemsList", + "parameters": { + "vault_id": vault_id, + "filters": [o.model_dump(by_alias=True) for o in filters], + }, }, } } ) response = TypeAdapter(List[ItemOverview]).validate_json(response) - return SDKIterator(response) + return response diff --git a/src/onepassword/items_files.py b/src/onepassword/items_files.py index 62d05709..28213c99 100644 --- a/src/onepassword/items_files.py +++ b/src/onepassword/items_files.py @@ -1,7 +1,6 @@ # Code generated by op-codegen - DO NO EDIT MANUALLY from .core import _invoke, _invoke_sync -from .iterator import SDKIterator from typing import Optional, List from pydantic import TypeAdapter from .types import DocumentCreateParams, FileAttributes, FileCreateParams, Item diff --git a/src/onepassword/items_shares.py b/src/onepassword/items_shares.py index c0cabaae..473292de 100644 --- a/src/onepassword/items_shares.py +++ b/src/onepassword/items_shares.py @@ -1,7 +1,6 @@ # Code generated by op-codegen - DO NO EDIT MANUALLY from .core import _invoke, _invoke_sync -from .iterator import SDKIterator from typing import Optional, List from pydantic import TypeAdapter from .types import Item, ItemShareAccountPolicy, ItemShareParams, ValidRecipient diff --git a/src/onepassword/iterator.py b/src/onepassword/iterator.py deleted file mode 100644 index f153137c..00000000 --- a/src/onepassword/iterator.py +++ /dev/null @@ -1,25 +0,0 @@ -# Code generated by op-codegen - DO NOT EDIT MANUALLY - -import asyncio -from typing import AsyncIterator, Iterable, TypeVar - -T = TypeVar("T") - - -class SDKIterator(AsyncIterator[T]): - def __init__(self, obj: Iterable[T]): - self.obj = obj - self.index = 0 - self.lock = asyncio.Lock() - - def __aiter__(self) -> AsyncIterator[T]: - return self - - async def __anext__(self) -> T: - async with self.lock: - if self.index >= len(self.obj): - raise StopAsyncIteration - - next_obj = self.obj[self.index] - self.index += 1 - return next_obj diff --git a/src/onepassword/lib/aarch64/libop_uniffi_core.dylib b/src/onepassword/lib/aarch64/libop_uniffi_core.dylib index 8d4211be..ef3b866d 100755 Binary files a/src/onepassword/lib/aarch64/libop_uniffi_core.dylib and b/src/onepassword/lib/aarch64/libop_uniffi_core.dylib differ diff --git a/src/onepassword/lib/aarch64/libop_uniffi_core.so b/src/onepassword/lib/aarch64/libop_uniffi_core.so index a386ee58..45f4bc0c 100755 Binary files a/src/onepassword/lib/aarch64/libop_uniffi_core.so and b/src/onepassword/lib/aarch64/libop_uniffi_core.so differ diff --git a/src/onepassword/lib/x86_64/libop_uniffi_core.dylib b/src/onepassword/lib/x86_64/libop_uniffi_core.dylib index 8ccf2801..d8d8e23b 100755 Binary files a/src/onepassword/lib/x86_64/libop_uniffi_core.dylib and b/src/onepassword/lib/x86_64/libop_uniffi_core.dylib differ diff --git a/src/onepassword/lib/x86_64/libop_uniffi_core.so b/src/onepassword/lib/x86_64/libop_uniffi_core.so index 015db2f9..d2e94554 100755 Binary files a/src/onepassword/lib/x86_64/libop_uniffi_core.so and b/src/onepassword/lib/x86_64/libop_uniffi_core.so differ diff --git a/src/onepassword/lib/x86_64/op_uniffi_core.dll b/src/onepassword/lib/x86_64/op_uniffi_core.dll index 21b3ef66..93257d49 100644 Binary files a/src/onepassword/lib/x86_64/op_uniffi_core.dll and b/src/onepassword/lib/x86_64/op_uniffi_core.dll differ diff --git a/src/onepassword/secrets.py b/src/onepassword/secrets.py index 9d16e64e..c5f77a2d 100644 --- a/src/onepassword/secrets.py +++ b/src/onepassword/secrets.py @@ -1,7 +1,6 @@ # Code generated by op-codegen - DO NO EDIT MANUALLY from .core import _invoke, _invoke_sync -from .iterator import SDKIterator from typing import Optional, List from pydantic import TypeAdapter from .types import GeneratePasswordResponse, PasswordRecipe, ResolveAllResponse diff --git a/src/onepassword/types.py b/src/onepassword/types.py index c7379c66..ded9b2cf 100644 --- a/src/onepassword/types.py +++ b/src/onepassword/types.py @@ -332,7 +332,7 @@ class ItemFile(BaseModel): class Item(BaseModel): """ - Represents a 1Password item. + Represents an active 1Password item. """ model_config = ConfigDict(populate_by_name=True) @@ -448,6 +448,21 @@ class ItemCreateParams(BaseModel): """ +class ItemState(str, Enum): + """ + Represents the state of an item in the SDK. + """ + + ACTIVE = "active" + """ + The item is active + """ + ARCHIVED = "archived" + """ + The item is archived meaning it's hidden from regular view and stored in the archive. + """ + + class ItemOverview(BaseModel): """ Represents a decrypted 1Password item overview. @@ -495,6 +510,10 @@ class ItemOverview(BaseModel): """ The time the item was updated at """ + state: ItemState + """ + Indicates the state of the item + """ class ItemShareDuration(str, Enum): @@ -967,6 +986,27 @@ class VaultOverview(BaseModel): """ +class ItemListFilterByStateInner(BaseModel): + """ + Generated type representing the anonymous struct variant `ByState` of the `ItemListFilter` Rust enum + """ + + active: bool + archived: bool + + +class ItemListFilterTypes(str, Enum): + BY_STATE = "ByState" + + +class ItemListFilterByState(BaseModel): + type: Literal[ItemListFilterTypes.BY_STATE] = ItemListFilterTypes.BY_STATE + content: ItemListFilterByStateInner + + +ItemListFilter = ItemListFilterByState + + class PasswordRecipeMemorableInner(BaseModel): """ Generated type representing the anonymous struct variant `Memorable` of the `PasswordRecipe` Rust enum diff --git a/src/onepassword/vaults.py b/src/onepassword/vaults.py index 738e8b6c..2b066d5c 100644 --- a/src/onepassword/vaults.py +++ b/src/onepassword/vaults.py @@ -1,7 +1,6 @@ # Code generated by op-codegen - DO NO EDIT MANUALLY from .core import _invoke, _invoke_sync -from .iterator import SDKIterator from typing import Optional, List from pydantic import TypeAdapter from .types import VaultOverview @@ -15,7 +14,7 @@ class Vaults: def __init__(self, client_id): self.client_id = client_id - async def list_all(self) -> SDKIterator[VaultOverview]: + async def list(self) -> List[VaultOverview]: """ List all vaults """ @@ -23,10 +22,10 @@ async def list_all(self) -> SDKIterator[VaultOverview]: { "invocation": { "clientId": self.client_id, - "parameters": {"name": "VaultsListAll", "parameters": {}}, + "parameters": {"name": "VaultsList", "parameters": {}}, } } ) response = TypeAdapter(List[VaultOverview]).validate_json(response) - return SDKIterator(response) + return response diff --git a/src/release/RELEASE-NOTES b/src/release/RELEASE-NOTES index 72513733..f0801b84 100644 --- a/src/release/RELEASE-NOTES +++ b/src/release/RELEASE-NOTES @@ -1,20 +1,66 @@ -# 1Password Python SDK v0.2.1 +# 1Password Python SDK v0.3.0 ## NEW -- **`CreatedAt` and `UpdatedAt` item metadata:** Items and item overviews now expose attributes with their creation and last edit times. -- **Resolving secrets in bulk**: With the `client.secrets.resolveAll` function, the SDK is now able to resolve multiple secrets at once, improving the performance of the operation. +- **Support for item states**: You can now fetch an item's state using the SDK. `ItemOverview` exposes one of two states: `Active` or `Archived`. + - `Active`: An item located inside a vault. (Default) + - `Archived`: An item that has been moved to the Archive. 1Password doesn't include archived items in search results or suggest them when you fill in apps and browsers. You can keep archived items as long as you'd like. +- **Filtering listed items by state**: You can now filter the results of the item list function by item state. -## IMPROVED +## FIXED -- **Support for new field types:** Items with `Address` and `Date` fields can now be created, retrieved, and edited using the 1Password SDK. -- **Item sharing for attachments and documents**: Items with files attached now can also be shared using the `client.items.shares` functions. -- **Adding custom fields in sections automatically**: The SDK now automatically adds custom fields without a section to an empty section within the item, creating it if necessary. -- **`Tags` in item overviews**: The return type of `items.listAll` now also contains the item tags. -- **Broader item editing capabilities**: You are now able to use the `items.put` function on more items, including those with fields that are not directly editable through the SDK (such as legacy fields, passkeys etc.) +- **Deleting Archived Items:** The SDK now supports deleting items from the archive. -## FIXED +## ⚠️ BREAKING CHANGES ⚠️ +This release contains breaking changes for two functions in the Python SDK. + +**Vault listing** + +* The function name has changed from `list_all` to `list`. To use this in your code, replace: +```python +vaults = await client.vaults.list_all(vault_id) +``` +with: +```python +vaults = await client.vaults.list(vault_id) +``` + +* The return type of the vault listing function has changed from `SDKIterator[VaultOverview]` to `List[VaultOverview]`. To use this in your code, replace: + +```python +async for vault in vaults: + # using vault overview +``` +with: +```python +for vault in vaults: + # using vault overview +``` +**Item listing** + +* The function name has changed from `ListAll` to `List`. To use this in your code, replace: +```python +overviews = await client.items.list_all(vault_id) +``` +with: +```python +overviews = await client.items.list(vault_id, ItemListFilter( + content=ItemListFilterByStateInner( + active=True, + archived=True, + ) + )) +``` + +* The return type of the item listing function has changed from `SDKIterator[ItemOverview]` to `List[ItemOverview]`. To use this in your code, replace: +```python +async for overview in overviews: + # using item overview +``` +with: +```python +for overview in overviews: + # using item overview +``` -- **Improvements to resolving secret references:** - - Archived items are no longer used for secret references. - - When multiple sections match a section query in resolving secret references, the SDK look through the fields in all sections, instead of erroring. +This does not affect any code that's already deployed, and will not take effect in your codebase until you choose to update to version 0.3.0 or later of the 1Password Python SDK. diff --git a/version.py b/version.py index 05a2fb11..b2637133 100644 --- a/version.py +++ b/version.py @@ -1 +1 @@ -SDK_VERSION = "0.2.1" +SDK_VERSION = "0.3.0"