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

[Feat] Allow custom timeout using env vars #94

Merged
merged 3 commits into from
Apr 2, 2024
Merged
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
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
Loading