Skip to content

Commit

Permalink
Merge pull request #94 from raphapassini/feat-timeout-on-client
Browse files Browse the repository at this point in the history
[Feat] Allow custom timeout using env vars
  • Loading branch information
volodymyrZotov authored Apr 2, 2024
2 parents cdefdd1 + d01e535 commit 80afcc1
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 5 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ Check the [Python Connect SDK Example](example/README.md) to see an example of i
export OP_CONNECT_HOST=<your-connect-host> && \
export OP_CONNECT_TOKEN=<your-connect-token>
```

2.1 If you need a higher timeout on the client requests you can export `OP_CLIENT_REQUEST_TIMEOUT` environment variable:
```sh
# set the timeout to 90 seconds
export OP_CLIENT_REQUEST_TIMEOUT=90
```

3. Use the SDK:

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 @@ -5,7 +5,7 @@
import os

from onepasswordconnectsdk.serializer import Serializer
from onepasswordconnectsdk.utils import build_headers, is_valid_uuid, PathBuilder
from onepasswordconnectsdk.utils import build_headers, is_valid_uuid, PathBuilder, get_timeout
from onepasswordconnectsdk.errors import (
FailedToRetrieveItemException,
FailedToRetrieveVaultException,
Expand All @@ -24,7 +24,8 @@ def __init__(self, url: str, token: str) -> None:
self.serializer = Serializer()

def create_session(self, url: str, token: str) -> httpx.AsyncClient:
return httpx.AsyncClient(base_url=url, headers=self.build_headers(token))
# import here to avoid circular import
return httpx.AsyncClient(base_url=url, headers=self.build_headers(token), timeout=get_timeout())

def build_headers(self, token: str) -> Dict[str, str]:
return build_headers(token)
Expand Down
6 changes: 3 additions & 3 deletions src/onepasswordconnectsdk/client.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
"""Python Client for connecting to 1Password Connect"""
import httpx
from httpx import HTTPError
from httpx import HTTPError, USE_CLIENT_DEFAULT
import json
from typing import Dict, List, Union
import os

from onepasswordconnectsdk.async_client import AsyncClient
from onepasswordconnectsdk.serializer import Serializer
from onepasswordconnectsdk.utils import build_headers, is_valid_uuid, PathBuilder
from onepasswordconnectsdk.utils import build_headers, is_valid_uuid, PathBuilder, get_timeout
from onepasswordconnectsdk.errors import (
FailedToRetrieveItemException,
FailedToRetrieveVaultException,
Expand All @@ -32,7 +32,7 @@ def __init__(self, url: str, token: str) -> None:
self.serializer = Serializer()

def create_session(self, url: str, token: str) -> httpx.Client:
return httpx.Client(base_url=url, headers=self.build_headers(token))
return httpx.Client(base_url=url, headers=self.build_headers(token), timeout=get_timeout())

def build_headers(self, token: str) -> Dict[str, str]:
return build_headers(token)
Expand Down
13 changes: 13 additions & 0 deletions src/onepasswordconnectsdk/utils.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
import os
from typing import Union

from httpx import USE_CLIENT_DEFAULT
from httpx._client import UseClientDefault

UUIDLength = 26
ENV_CLIENT_REQUEST_TIMEOUT = "OP_CONNECT_CLIENT_REQ_TIMEOUT"


def is_valid_uuid(uuid):
Expand Down Expand Up @@ -59,3 +66,9 @@ def _append_path(self, path_chunk: str = None, query: str = None) -> 'PathBuilde
self.path += f"/{path_chunk}"
if query is not None:
self.path += f"?{query}"


def get_timeout() -> Union[int, UseClientDefault]:
"""Get the timeout to be used in the HTTP Client"""
timeout = int(os.getenv(ENV_CLIENT_REQUEST_TIMEOUT, 0))
return timeout if timeout else USE_CLIENT_DEFAULT
17 changes: 17 additions & 0 deletions src/tests/test_client_items.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import os
import pytest
from unittest import mock

from httpx import Response
from onepasswordconnectsdk import client, models
from onepasswordconnectsdk.utils import ENV_CLIENT_REQUEST_TIMEOUT

VAULT_ID = "hfnjvi6aymbsnfc2xeeoheizda"
VAULT_TITLE = "VaultA"
Expand Down Expand Up @@ -440,3 +444,16 @@ def generate_full_item():
id="Section_47DC4DDBF26640AB8B8618DA36D5A499"))],
sections=[models.Section(id="id", label="label")])
return item


def test_set_timeout_using_env_variable():
with mock.patch.dict(os.environ, {ENV_CLIENT_REQUEST_TIMEOUT: '120'}):
client_instance = client.new_client(HOST, TOKEN)
assert client_instance.session.timeout.read == 120


@pytest.mark.asyncio
def test_set_timeout_using_env_variable_async():
with mock.patch.dict(os.environ, {ENV_CLIENT_REQUEST_TIMEOUT: '120'}):
client_instance = client.new_client(HOST, TOKEN, is_async=True)
assert client_instance.session.timeout.read == 120

0 comments on commit 80afcc1

Please sign in to comment.