Skip to content

Commit 0decd81

Browse files
authored
Optionally import httpx in async service (#1508)
**Pull Request Checklist** - [ ] Fixes #<!--issue number goes here--> - [ ] Tests added - [ ] Documentation/examples added - [x] [Good commit messages](https://cbea.ms/git-commit/) and/or PR title **Description of PR** importing hera 5.25.0 breaks because it tries to import httpx anyway. (httpx is installed when hera is installed with async-client extras) https://github.com/argoproj-labs/hera/blob/5072bb938ecd46a1ab7a229eaf7927ee15faa105/src/hera/workflows/__init__.py#L23 https://github.com/argoproj-labs/hera/blob/5072bb938ecd46a1ab7a229eaf7927ee15faa105/src/hera/workflows/async_service.py#L8 so in this pr, importing httpx only will be done when it is used. Signed-off-by: Ukjae Jeong <JeongUkJae@gmail.com>
1 parent 5072bb9 commit 0decd81

File tree

4 files changed

+36
-24
lines changed

4 files changed

+36
-24
lines changed

scripts/async_service.py

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ def __str__(self) -> str:
182182
183183
if resp.is_success:
184184
return {ret_val}
185-
185+
186186
raise exception_from_server_response(resp)
187187
"""
188188

@@ -397,16 +397,18 @@ def get_service_def() -> str:
397397
\"\"\"Interact with the {doc_models_type} REST service asynchronously. Requires you to `pip install hera[async-client]`.\"\"\"
398398
# [DO NOT MODIFY] Auto-generated by `hera/scripts/async_service.py`
399399
from urllib.parse import urljoin
400-
import httpx
401400
import os
402401
from hera.{module}.models import {imports}
403402
from hera.shared import global_config
404403
from hera.exceptions import exception_from_server_response
405-
from typing import Optional, Tuple, cast
404+
from typing import Optional, Tuple, cast, TYPE_CHECKING
405+
406+
if TYPE_CHECKING:
407+
import httpx
406408
407409
def valid_host_scheme(host: str) -> bool:
408410
\"\"\"Validates the the given `host` starts with either `http` or `https`.\"\"\"
409-
return host.startswith("http://") or host.startswith("https://")
411+
return host.startswith("http://") or host.startswith("https://")
410412
411413
class {models_type}Service:
412414
\"\"\"The asynchronous {doc_models_type} service for interacting with the Argo server.\"\"\"
@@ -417,20 +419,22 @@ def __init__(
417419
token: Optional[str] = None,
418420
client_certs: Optional[Tuple[str, str]] = None,
419421
namespace: Optional[str] = None,
420-
session: Optional[httpx.AsyncClient] = None,
422+
session: Optional["httpx.AsyncClient"] = None,
421423
) -> None:
422424
\"\"\"{models_type} service constructor.\"\"\"
425+
import httpx
426+
423427
self.host = cast(str, host or global_config.host)
424428
self.verify_ssl = verify_ssl if verify_ssl is not None else global_config.verify_ssl
425429
self.client_certs = client_certs if client_certs is not None else global_config.client_certs
426430
427-
# some users reported in https://github.com/argoproj-labs/hera/issues/1016 that it can be a bit awkward for
431+
# some users reported in https://github.com/argoproj-labs/hera/issues/1016 that it can be a bit awkward for
428432
# Hera to assume a `Bearer` prefix on behalf of users. Some might pass it and some might not. Therefore, Hera
429433
# only prefixes the token with `Bearer ` if it's not already specified and lets the uses specify it otherwise.
430-
# Note that the `Bearer` token can be specified through the global configuration as well. In order to deliver
434+
# Note that the `Bearer` token can be specified through the global configuration as well. In order to deliver
431435
# a fix on Hera V5 without introducing breaking changes, we have to support both
432436
global_config_token = global_config.token # call only once because it can be a user specified function!
433-
437+
434438
def format_token(t):
435439
parts = t.strip().split()
436440
if len(parts) == 1:
@@ -447,19 +451,19 @@ def format_token(t):
447451
self.session = session or httpx.AsyncClient(verify=self.verify_ssl, cert=self.client_certs)
448452
449453
self.namespace = namespace or global_config.namespace
450-
454+
451455
async def _request(self, method, **kwargs):
452456
\"\"\"Make a request using the session if enabled.\"\"\"
453457
return await self.session.request(method, **kwargs)
454-
458+
455459
async def close(self):
456460
\"\"\"Close the service session.\"\"\"
457-
await self.session.aclose()
458-
461+
await self.session.aclose()
462+
459463
async def __aenter__(self):
460464
\"\"\"Open the service - session doesn't need to be opened.\"\"\"
461465
return self
462-
466+
463467
async def __aexit__(self, *_):
464468
\"\"\"Close the service.\"\"\"
465469
await self.close()

src/hera/events/async_service.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
"""Interact with the events REST service asynchronously. Requires you to `pip install hera[async-client]`."""
22

33
# [DO NOT MODIFY] Auto-generated by `hera/scripts/async_service.py`
4-
from typing import Optional, Tuple, cast
4+
from typing import TYPE_CHECKING, Optional, Tuple, cast
55
from urllib.parse import urljoin
66

7-
import httpx
8-
97
from hera.events.models import (
108
CreateEventSourceRequest,
119
CreateSensorRequest,
@@ -31,6 +29,9 @@
3129
from hera.exceptions import exception_from_server_response
3230
from hera.shared import global_config
3331

32+
if TYPE_CHECKING:
33+
import httpx
34+
3435

3536
def valid_host_scheme(host: str) -> bool:
3637
"""Validates the the given `host` starts with either `http` or `https`."""
@@ -47,9 +48,11 @@ def __init__(
4748
token: Optional[str] = None,
4849
client_certs: Optional[Tuple[str, str]] = None,
4950
namespace: Optional[str] = None,
50-
session: Optional[httpx.AsyncClient] = None,
51+
session: Optional["httpx.AsyncClient"] = None,
5152
) -> None:
5253
"""AsyncEvents service constructor."""
54+
import httpx
55+
5356
self.host = cast(str, host or global_config.host)
5457
self.verify_ssl = verify_ssl if verify_ssl is not None else global_config.verify_ssl
5558
self.client_certs = client_certs if client_certs is not None else global_config.client_certs

src/hera/exceptions/__init__.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@
66

77
import json
88
from http import HTTPStatus
9-
from typing import Dict, Type, Union
9+
from typing import TYPE_CHECKING, Dict, Type, Union
1010

11-
import httpx
1211
from requests import Response
1312

13+
if TYPE_CHECKING:
14+
import httpx
15+
1416

1517
class HeraException(Exception):
1618
"""Base class for exceptions in this module."""
@@ -76,7 +78,7 @@ def exception_from_status_code(status_code: int, msg: str) -> HeraException:
7678
return status_code_to_exception_map.get(status_code, HeraException)(msg)
7779

7880

79-
def exception_from_server_response(resp: Union[Response, httpx.Response]) -> HeraException:
81+
def exception_from_server_response(resp: Union[Response, "httpx.Response"]) -> HeraException:
8082
"""Return a `HeraException` mapped from the given `Response`."""
8183
is_success = resp.ok if isinstance(resp, Response) else resp.is_success
8284
assert not is_success, "This function should only be called with non-2xx responses"

src/hera/workflows/async_service.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,9 @@
22

33
# [DO NOT MODIFY] Auto-generated by `hera/scripts/async_service.py`
44
import os
5-
from typing import Optional, Tuple, cast
5+
from typing import TYPE_CHECKING, Optional, Tuple, cast
66
from urllib.parse import urljoin
77

8-
import httpx
9-
108
from hera.exceptions import exception_from_server_response
119
from hera.shared import global_config
1210
from hera.workflows.models import (
@@ -54,6 +52,9 @@
5452
WorkflowTerminateRequest,
5553
)
5654

55+
if TYPE_CHECKING:
56+
import httpx
57+
5758

5859
def valid_host_scheme(host: str) -> bool:
5960
"""Validates the the given `host` starts with either `http` or `https`."""
@@ -70,9 +71,11 @@ def __init__(
7071
token: Optional[str] = None,
7172
client_certs: Optional[Tuple[str, str]] = None,
7273
namespace: Optional[str] = None,
73-
session: Optional[httpx.AsyncClient] = None,
74+
session: Optional["httpx.AsyncClient"] = None,
7475
) -> None:
7576
"""AsyncWorkflows service constructor."""
77+
import httpx
78+
7679
self.host = cast(str, host or global_config.host)
7780
self.verify_ssl = verify_ssl if verify_ssl is not None else global_config.verify_ssl
7881
self.client_certs = client_certs if client_certs is not None else global_config.client_certs

0 commit comments

Comments
 (0)