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

Add is_async switch to new_client_from_enviroment #89

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
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
36 changes: 6 additions & 30 deletions poetry.lock

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

1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ repository = "https://github.com/1Password/connect-sdk-python"
python = "^3.7"
python-dateutil = "^2.8.1"
httpx = "^0.23.3"
typing-extensions = "<4.8.0"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typing-extensions 1.4.8 drops support for Python 3.7, so the version is pinned.


[tool.poetry.group.dev.dependencies]
pytest = "^7.2.0"
Expand Down
5 changes: 3 additions & 2 deletions src/onepasswordconnectsdk/async_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from httpx import HTTPError
import json
import os
from typing import Optional

from onepasswordconnectsdk.serializer import Serializer
from onepasswordconnectsdk.utils import build_headers, is_valid_uuid, PathBuilder
Expand Down Expand Up @@ -56,7 +57,7 @@ async def get_files(self, item_id: str, vault_id: str):
)
return self.serializer.deserialize(response.content, "list[File]")

async def get_file_content(self, file_id: str, item_id: str, vault_id: str, content_path: str = None):
async def get_file_content(self, file_id: str, item_id: str, vault_id: str, content_path: Optional[str] = None):
url = content_path
if content_path is None:
url = PathBuilder().vaults(vault_id).items(item_id).files(file_id).content().build()
Expand Down Expand Up @@ -164,7 +165,7 @@ async def get_item_by_title(self, title: str, vault_id: str):
item_summary = self.serializer.deserialize(response.content, "list[SummaryItem]")[0]
return await self.get_item_by_id(item_summary.id, vault_id)

async def get_items(self, vault_id: str, filter_query: str = None):
async def get_items(self, vault_id: str, filter_query: Optional[str] = None):
"""Returns a list of item summaries for the specified vault

Args:
Expand Down
64 changes: 57 additions & 7 deletions src/onepasswordconnectsdk/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
from httpx import HTTPError
import json
import os
from typing import Optional, Union, overload
from typing_extensions import Literal
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typing.Literal was added in Python 3.8, which is why we need the backported version here.

If this project were to drop support for 3.7, the import could be updated.


from onepasswordconnectsdk.async_client import AsyncClient
from onepasswordconnectsdk.serializer import Serializer
Expand Down Expand Up @@ -63,7 +65,7 @@ def get_files(self, item_id: str, vault_id: str):
)
return self.serializer.deserialize(response.content, "list[File]")

def get_file_content(self, file_id: str, item_id: str, vault_id: str, content_path: str = None):
def get_file_content(self, file_id: str, item_id: str, vault_id: str, content_path: Optional[str] = None):
url = content_path
if content_path is None:
url = PathBuilder().vaults(vault_id).items(item_id).files(file_id).content().build()
Expand Down Expand Up @@ -170,7 +172,7 @@ def get_item_by_title(self, title: str, vault_id: str):
item_summary = self.serializer.deserialize(response.content, "list[SummaryItem]")[0]
return self.get_item_by_id(item_summary.id, vault_id)

def get_items(self, vault_id: str, filter_query: str = None):
def get_items(self, vault_id: str, filter_query: Optional[str] = None):
"""Returns a list of item summaries for the specified vault

Args:
Expand Down Expand Up @@ -380,7 +382,29 @@ def sanitize_for_serialization(self, obj):
return self.serializer.sanitize_for_serialization(obj)


def new_client(url: str, token: str, is_async: bool = False):
@overload
def new_client(
url: str, token: str, is_async: Literal[False] = ...
) -> Client:
...


@overload
def new_client(
url: str, token: str, is_async: Literal[True] = ...
) -> AsyncClient:
...

@overload
def new_client(
url: str, token: str, is_async: bool = ...
) -> Union[Client, AsyncClient]:
...


def new_client(
url: str, token: str, is_async: bool = False
) -> Union[Client, AsyncClient]:
"""Builds a new client for interacting with 1Password Connect
Parameters:
url: The url of the 1Password Connect API
Expand All @@ -395,19 +419,45 @@ def new_client(url: str, token: str, is_async: bool = False):
return Client(url, token)


def new_client_from_environment(url: str = None):
@overload
def new_client_from_environment(
url: Optional[str] = ..., is_async: Literal[False] = ...
) -> Client:
...


@overload
def new_client_from_environment(
url: Optional[str] = ..., is_async: Literal[True] = ...
) -> AsyncClient:
...


@overload
def new_client_from_environment(
url: Optional[str] = ..., is_async: None = ...
) -> Union[Client, AsyncClient]:
...


def new_client_from_environment(
url: Optional[str] = None, is_async: Optional[bool] = None
) -> Union[Client, AsyncClient]:
"""Builds a new client for interacting with 1Password Connect
using the OP_TOKEN environment variable

Parameters:
url: The url of the 1Password Connect API
token: The 1Password Service Account token
is_async: If set to True, return an async client; if False, return a sync client.
If not set or set to None, return an async client if the OP_CONNECT_CLIENT_ASYNC
environment variable is set to "True", a sync client otherwise.

Returns:
Client: The 1Password Connect client
Client or AsyncClient: The 1Password Connect client
"""
token = os.environ.get(ENV_SERVICE_ACCOUNT_JWT_VARIABLE)
is_async = os.environ.get(ENV_IS_ASYNC_CLIENT) == "True"
if is_async is None:
is_async = os.environ.get(ENV_IS_ASYNC_CLIENT).lower() in ("t", "true", "1")

if url is None:
url = os.environ.get(CONNECT_HOST_ENV_VARIABLE)
Expand Down
4 changes: 2 additions & 2 deletions src/onepasswordconnectsdk/config.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import os
import shlex
from typing import List, Dict
from typing import List, Dict, Optional
from onepasswordconnectsdk.client import Client
from onepasswordconnectsdk.models import (
SummaryItem,
Expand Down Expand Up @@ -166,7 +166,7 @@ def _set_values_for_item(
client: Client,
parsed_item: ParsedItem,
config_dict={},
config_object: object = None,
config_object: Optional[object] = None,
):
# Fetching the full item
item: Item = client.get_item(parsed_item.item_title, parsed_item.vault_uuid)
Expand Down
Loading