Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
12 changes: 7 additions & 5 deletions src/onepassword/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from __future__ import annotations
import weakref
from .core import UniffiCore
from .core import UniffiCore, InnerClient
from .desktop_core import DesktopCore
from .defaults import new_default_config, DesktopAuth
from .secrets import Secrets
Expand Down Expand Up @@ -34,12 +34,14 @@ async def authenticate(

client_id = int(await core.init_client(config))

inner_client = InnerClient(client_id, core, config)

authenticated_client = cls()

authenticated_client.secrets = Secrets(client_id, core)
authenticated_client.items = Items(client_id, core)
authenticated_client.vaults = Vaults(client_id, core)
authenticated_client.groups = Groups(client_id, core)
authenticated_client.secrets = Secrets(inner_client)
authenticated_client.items = Items(inner_client)
authenticated_client.vaults = Vaults(inner_client)
authenticated_client.groups = Groups(inner_client)

authenticated_client._finalizer = weakref.finalize(
cls, core.release_client, client_id
Expand Down
30 changes: 28 additions & 2 deletions src/onepassword/core.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,45 @@
from __future__ import annotations
import json
import platform
from typing import Protocol
from onepassword.errors import raise_typed_exception
from typing import Any, Protocol
from onepassword.desktop_core import DesktopCore
from onepassword.errors import raise_typed_exception, DesktopSessionExpired

# In empirical tests, we determined that maximum message size that can cross the FFI boundary
# is ~128MB. Past this limit, FFI will throw an error and the program will crash.
# We set the limit to 50MB to be safe and consistent with the other SDKs (where this limit is 64MB), to be reconsidered upon further testing
MESSAGE_LIMIT = 50 * 1024 * 1024


class Core(Protocol):
async def init_client(self, client_config: dict) -> str: ...
async def invoke(self, invoke_config: dict) -> str: ...
def invoke_sync(self, invoke_config: dict) -> str: ...
def release_client(self, client_id: int) -> None: ...


class InnerClient:
client_id: int
core: DesktopCore | UniffiCore
config: dict[str, Any]

def __init__(self, client_id: int, core: "DesktopCore | UniffiCore", config: dict[str, any]):
self.client_id = client_id
self.core = core
self.config = config

async def invoke(self, invoke_config: dict):
try:
return await self.core.invoke(invoke_config)
except DesktopSessionExpired as e:

Check failure on line 34 in src/onepassword/core.py

View workflow job for this annotation

GitHub Actions / Lint

Ruff (F841)

src/onepassword/core.py:34:41: F841 Local variable `e` is assigned to but never used

Check failure on line 34 in src/onepassword/core.py

View workflow job for this annotation

GitHub Actions / Lint

Ruff (F841)

src/onepassword/core.py:34:41: F841 Local variable `e` is assigned to but never used
new_client_id = await self.core.init_client(self.config)
self.client_id = new_client_id
invoke_config["invocation"]["clientId"] = self.client_id
return await self.core.invoke(invoke_config)
except Exception as e:
raise e


class UniffiCore:
def __init__(self):
machine_arch = platform.machine().lower()
Expand Down
4 changes: 3 additions & 1 deletion src/onepassword/desktop_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import platform
import base64
from pathlib import Path
from ctypes import c_uint8, c_size_t, c_int32, POINTER, byref, c_void_p

Check failure on line 7 in src/onepassword/desktop_core.py

View workflow job for this annotation

GitHub Actions / Lint

Ruff (F401)

src/onepassword/desktop_core.py:7:64: F401 `ctypes.c_void_p` imported but unused

Check failure on line 7 in src/onepassword/desktop_core.py

View workflow job for this annotation

GitHub Actions / Lint

Ruff (F401)

src/onepassword/desktop_core.py:7:64: F401 `ctypes.c_void_p` imported but unused
from onepassword.errors import raise_typed_exception


Expand Down Expand Up @@ -99,7 +99,9 @@

success = parsed.get("success", False)
if not success:
raise_typed_exception(Exception(str(payload)))
e = Exception()
e.msg = payload
raise_typed_exception(e)

return payload

Expand Down
10 changes: 9 additions & 1 deletion src/onepassword/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
import json


class DesktopSessionExpired(Exception):
def __init__(self, message):
self.message = message
super().__init__(self.message)


class RateLimitExceededException(Exception):
def __init__(self, message):
self.message = message
Expand All @@ -18,7 +24,9 @@ def raise_typed_exception(e: Exception):
error_name = typed_error.get("name")
message = typed_error.get("message")

if error_name == "RateLimitExceeded":
if error_name == "DesktopSessionExpired":
raise DesktopSessionExpired(message)
elif error_name == "RateLimitExceeded":
raise RateLimitExceededException(message)
elif message is not None:
raise Exception(message)
Expand Down
11 changes: 5 additions & 6 deletions src/onepassword/groups.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Code generated by op-codegen - DO NO EDIT MANUALLY

from .core import Core
from .core import InnerClient
from pydantic import TypeAdapter
from .types import Group, GroupGetParams

Expand All @@ -10,15 +10,14 @@ class Groups:
The Groups API holds all the operations the SDK client can perform on 1Password groups.
"""

def __init__(self, client_id, core: Core):
self.client_id = client_id
self.core = core
def __init__(self, inner_client: InnerClient):
self.inner_client = inner_client

async def get(self, group_id: str, group_params: GroupGetParams) -> Group:
response = await self.core.invoke(
response = await self.inner_client.invoke(
{
"invocation": {
"clientId": self.client_id,
"clientId": self.inner_client.client_id,
"parameters": {
"name": "GroupsGet",
"parameters": {
Expand Down
47 changes: 23 additions & 24 deletions src/onepassword/items.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Code generated by op-codegen - DO NO EDIT MANUALLY

from .core import Core
from .core import InnerClient
from typing import List
from pydantic import TypeAdapter
from .items_shares import ItemsShares
Expand All @@ -21,20 +21,19 @@
The Items API holds all operations the SDK client can perform on 1Password items.
"""

def __init__(self, client_id, core: Core):
self.client_id = client_id
self.core = core
self.shares = ItemsShares(client_id, core)
self.files = ItemsFiles(client_id, core)
def __init__(self, inner_client: InnerClient):
self.inner_client = inner_client
self.shares = ItemsShares(inner_client)
self.files = ItemsFiles(inner_client)

async def create(self, params: ItemCreateParams) -> Item:
"""
Create a new item.
"""
response = await self.core.invoke(
response = await self.inner_client.invoke(
{
"invocation": {
"clientId": self.client_id,
"clientId": self.inner_client.client_id,
"parameters": {
"name": "ItemsCreate",
"parameters": {"params": params.model_dump(by_alias=True)},
Expand All @@ -52,10 +51,10 @@
"""
Create items in batch, within a single vault.
"""
response = await self.core.invoke(
response = await self.inner_client.invoke(
{
"invocation": {
"clientId": self.client_id,
"clientId": self.inner_client.client_id,
"parameters": {
"name": "ItemsCreateAll",
"parameters": {
Expand All @@ -74,10 +73,10 @@
"""
Get an item by vault and item ID
"""
response = await self.core.invoke(
response = await self.inner_client.invoke(
{
"invocation": {
"clientId": self.client_id,
"clientId": self.inner_client.client_id,
"parameters": {
"name": "ItemsGet",
"parameters": {"vault_id": vault_id, "item_id": item_id},
Expand All @@ -93,10 +92,10 @@
"""
Get items by vault and their item IDs.
"""
response = await self.core.invoke(
response = await self.inner_client.invoke(
{
"invocation": {
"clientId": self.client_id,
"clientId": self.inner_client.client_id,
"parameters": {
"name": "ItemsGetAll",
"parameters": {"vault_id": vault_id, "item_ids": item_ids},
Expand All @@ -112,10 +111,10 @@
"""
Update an existing item.
"""
response = await self.core.invoke(
response = await self.inner_client.invoke(
{
"invocation": {
"clientId": self.client_id,
"clientId": self.inner_client.client_id,
"parameters": {
"name": "ItemsPut",
"parameters": {"item": item.model_dump(by_alias=True)},
Expand All @@ -131,10 +130,10 @@
"""
Delete an item.
"""
response = await self.core.invoke(
response = await self.inner_client.invoke(

Check failure on line 133 in src/onepassword/items.py

View workflow job for this annotation

GitHub Actions / Lint

Ruff (F841)

src/onepassword/items.py:133:9: F841 Local variable `response` is assigned to but never used

Check failure on line 133 in src/onepassword/items.py

View workflow job for this annotation

GitHub Actions / Lint

Ruff (F841)

src/onepassword/items.py:133:9: F841 Local variable `response` is assigned to but never used
{
"invocation": {
"clientId": self.client_id,
"clientId": self.inner_client.client_id,
"parameters": {
"name": "ItemsDelete",
"parameters": {"vault_id": vault_id, "item_id": item_id},
Expand All @@ -151,10 +150,10 @@
"""
Delete items in batch, within a single vault.
"""
response = await self.core.invoke(
response = await self.inner_client.invoke(
{
"invocation": {
"clientId": self.client_id,
"clientId": self.inner_client.client_id,
"parameters": {
"name": "ItemsDeleteAll",
"parameters": {"vault_id": vault_id, "item_ids": item_ids},
Expand All @@ -170,10 +169,10 @@
"""
Archive an item.
"""
response = await self.core.invoke(
response = await self.inner_client.invoke(

Check failure on line 172 in src/onepassword/items.py

View workflow job for this annotation

GitHub Actions / Lint

Ruff (F841)

src/onepassword/items.py:172:9: F841 Local variable `response` is assigned to but never used

Check failure on line 172 in src/onepassword/items.py

View workflow job for this annotation

GitHub Actions / Lint

Ruff (F841)

src/onepassword/items.py:172:9: F841 Local variable `response` is assigned to but never used
{
"invocation": {
"clientId": self.client_id,
"clientId": self.inner_client.client_id,
"parameters": {
"name": "ItemsArchive",
"parameters": {"vault_id": vault_id, "item_id": item_id},
Expand All @@ -188,10 +187,10 @@
"""
List items based on filters.
"""
response = await self.core.invoke(
response = await self.inner_client.invoke(
{
"invocation": {
"clientId": self.client_id,
"clientId": self.inner_client.client_id,
"parameters": {
"name": "ItemsList",
"parameters": {
Expand Down
23 changes: 11 additions & 12 deletions src/onepassword/items_files.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
# Code generated by op-codegen - DO NO EDIT MANUALLY

from .core import Core
from .core import InnerClient
from typing import List
from pydantic import TypeAdapter
from .types import DocumentCreateParams, FileAttributes, FileCreateParams, Item


class ItemsFiles:
def __init__(self, client_id, core: Core):
self.client_id = client_id
self.core = core
def __init__(self, inner_client: InnerClient):
self.inner_client = inner_client

async def attach(self, item: Item, file_params: FileCreateParams) -> Item:
"""
Attach files to Items
"""
response = await self.core.invoke(
response = await self.inner_client.invoke(
{
"invocation": {
"clientId": self.client_id,
"clientId": self.inner_client.client_id,
"parameters": {
"name": "ItemsFilesAttach",
"parameters": {
Expand All @@ -37,10 +36,10 @@ async def read(self, vault_id: str, item_id: str, attr: FileAttributes) -> bytes
"""
Read file content from the Item
"""
response = await self.core.invoke(
response = await self.inner_client.invoke(
{
"invocation": {
"clientId": self.client_id,
"clientId": self.inner_client.client_id,
"parameters": {
"name": "ItemsFilesRead",
"parameters": {
Expand All @@ -60,10 +59,10 @@ async def delete(self, item: Item, section_id: str, field_id: str) -> Item:
"""
Delete a field file from Item using the section and field IDs
"""
response = await self.core.invoke(
response = await self.inner_client.invoke(
{
"invocation": {
"clientId": self.client_id,
"clientId": self.inner_client.client_id,
"parameters": {
"name": "ItemsFilesDelete",
"parameters": {
Expand All @@ -85,10 +84,10 @@ async def replace_document(
"""
Replace the document file within a document item
"""
response = await self.core.invoke(
response = await self.inner_client.invoke(
{
"invocation": {
"clientId": self.client_id,
"clientId": self.inner_client.client_id,
"parameters": {
"name": "ItemsFilesReplaceDocument",
"parameters": {
Expand Down
Loading
Loading