Skip to content

Commit ba6d743

Browse files
SDK update: Use lazy loading to reduce import size
Co-authored-by: fern-api <115122769+fern-api[bot]@users.noreply.github.com>
1 parent ec265db commit ba6d743

File tree

169 files changed

+15546
-4707
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

169 files changed

+15546
-4707
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,3 +232,4 @@ while response.next is not None:
232232

233233

234234

235+

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name = "MergePythonClient"
33

44
[tool.poetry]
55
name = "MergePythonClient"
6-
version = "2.2.0"
6+
version = "2.3.0"
77
description = ""
88
readme = "README.md"
99
authors = []

src/merge/__init__.py

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,46 @@
22

33
# isort: skip_file
44

5-
from .resources import accounting, ats, crm, filestorage, hris, ticketing
6-
from .client import AsyncMerge, Merge
7-
from .environment import MergeEnvironment
8-
from .version import __version__
5+
import typing
6+
from importlib import import_module
7+
8+
if typing.TYPE_CHECKING:
9+
from .resources import accounting, ats, crm, filestorage, hris, ticketing
10+
from .client import AsyncMerge, Merge
11+
from .environment import MergeEnvironment
12+
from .version import __version__
13+
_dynamic_imports: typing.Dict[str, str] = {
14+
"AsyncMerge": ".client",
15+
"Merge": ".client",
16+
"MergeEnvironment": ".environment",
17+
"__version__": ".version",
18+
"accounting": ".resources",
19+
"ats": ".resources",
20+
"crm": ".resources",
21+
"filestorage": ".resources",
22+
"hris": ".resources",
23+
"ticketing": ".resources",
24+
}
25+
26+
27+
def __getattr__(attr_name: str) -> typing.Any:
28+
module_name = _dynamic_imports.get(attr_name)
29+
if module_name is None:
30+
raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}")
31+
try:
32+
module = import_module(module_name, __package__)
33+
result = getattr(module, attr_name)
34+
return result
35+
except ImportError as e:
36+
raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e
37+
except AttributeError as e:
38+
raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e
39+
40+
41+
def __dir__():
42+
lazy_attrs = list(_dynamic_imports.keys())
43+
return sorted(lazy_attrs)
44+
945

1046
__all__ = [
1147
"AsyncMerge",

src/merge/client.py

Lines changed: 118 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
11
# This file was auto-generated by Fern from our API Definition.
22

3+
from __future__ import annotations
4+
35
import typing
46

57
import httpx
68
from .core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
79
from .environment import MergeEnvironment
8-
from .resources.accounting.client import AccountingClient, AsyncAccountingClient
9-
from .resources.ats.client import AsyncAtsClient, AtsClient
10-
from .resources.crm.client import AsyncCrmClient, CrmClient
11-
from .resources.filestorage.client import AsyncFilestorageClient, FilestorageClient
12-
from .resources.hris.client import AsyncHrisClient, HrisClient
13-
from .resources.ticketing.client import AsyncTicketingClient, TicketingClient
10+
11+
if typing.TYPE_CHECKING:
12+
from .resources.accounting.client import AccountingClient, AsyncAccountingClient
13+
from .resources.ats.client import AsyncAtsClient, AtsClient
14+
from .resources.crm.client import AsyncCrmClient, CrmClient
15+
from .resources.filestorage.client import AsyncFilestorageClient, FilestorageClient
16+
from .resources.hris.client import AsyncHrisClient, HrisClient
17+
from .resources.ticketing.client import AsyncTicketingClient, TicketingClient
1418

1519

1620
class Merge:
@@ -82,12 +86,60 @@ def __init__(
8286
else httpx.Client(timeout=_defaulted_timeout),
8387
timeout=_defaulted_timeout,
8488
)
85-
self.ats = AtsClient(client_wrapper=self._client_wrapper)
86-
self.crm = CrmClient(client_wrapper=self._client_wrapper)
87-
self.filestorage = FilestorageClient(client_wrapper=self._client_wrapper)
88-
self.hris = HrisClient(client_wrapper=self._client_wrapper)
89-
self.ticketing = TicketingClient(client_wrapper=self._client_wrapper)
90-
self.accounting = AccountingClient(client_wrapper=self._client_wrapper)
89+
self._ats: typing.Optional[AtsClient] = None
90+
self._crm: typing.Optional[CrmClient] = None
91+
self._filestorage: typing.Optional[FilestorageClient] = None
92+
self._hris: typing.Optional[HrisClient] = None
93+
self._ticketing: typing.Optional[TicketingClient] = None
94+
self._accounting: typing.Optional[AccountingClient] = None
95+
96+
@property
97+
def ats(self):
98+
if self._ats is None:
99+
from .resources.ats.client import AtsClient # noqa: E402
100+
101+
self._ats = AtsClient(client_wrapper=self._client_wrapper)
102+
return self._ats
103+
104+
@property
105+
def crm(self):
106+
if self._crm is None:
107+
from .resources.crm.client import CrmClient # noqa: E402
108+
109+
self._crm = CrmClient(client_wrapper=self._client_wrapper)
110+
return self._crm
111+
112+
@property
113+
def filestorage(self):
114+
if self._filestorage is None:
115+
from .resources.filestorage.client import FilestorageClient # noqa: E402
116+
117+
self._filestorage = FilestorageClient(client_wrapper=self._client_wrapper)
118+
return self._filestorage
119+
120+
@property
121+
def hris(self):
122+
if self._hris is None:
123+
from .resources.hris.client import HrisClient # noqa: E402
124+
125+
self._hris = HrisClient(client_wrapper=self._client_wrapper)
126+
return self._hris
127+
128+
@property
129+
def ticketing(self):
130+
if self._ticketing is None:
131+
from .resources.ticketing.client import TicketingClient # noqa: E402
132+
133+
self._ticketing = TicketingClient(client_wrapper=self._client_wrapper)
134+
return self._ticketing
135+
136+
@property
137+
def accounting(self):
138+
if self._accounting is None:
139+
from .resources.accounting.client import AccountingClient # noqa: E402
140+
141+
self._accounting = AccountingClient(client_wrapper=self._client_wrapper)
142+
return self._accounting
91143

92144

93145
class AsyncMerge:
@@ -159,12 +211,60 @@ def __init__(
159211
else httpx.AsyncClient(timeout=_defaulted_timeout),
160212
timeout=_defaulted_timeout,
161213
)
162-
self.ats = AsyncAtsClient(client_wrapper=self._client_wrapper)
163-
self.crm = AsyncCrmClient(client_wrapper=self._client_wrapper)
164-
self.filestorage = AsyncFilestorageClient(client_wrapper=self._client_wrapper)
165-
self.hris = AsyncHrisClient(client_wrapper=self._client_wrapper)
166-
self.ticketing = AsyncTicketingClient(client_wrapper=self._client_wrapper)
167-
self.accounting = AsyncAccountingClient(client_wrapper=self._client_wrapper)
214+
self._ats: typing.Optional[AsyncAtsClient] = None
215+
self._crm: typing.Optional[AsyncCrmClient] = None
216+
self._filestorage: typing.Optional[AsyncFilestorageClient] = None
217+
self._hris: typing.Optional[AsyncHrisClient] = None
218+
self._ticketing: typing.Optional[AsyncTicketingClient] = None
219+
self._accounting: typing.Optional[AsyncAccountingClient] = None
220+
221+
@property
222+
def ats(self):
223+
if self._ats is None:
224+
from .resources.ats.client import AsyncAtsClient # noqa: E402
225+
226+
self._ats = AsyncAtsClient(client_wrapper=self._client_wrapper)
227+
return self._ats
228+
229+
@property
230+
def crm(self):
231+
if self._crm is None:
232+
from .resources.crm.client import AsyncCrmClient # noqa: E402
233+
234+
self._crm = AsyncCrmClient(client_wrapper=self._client_wrapper)
235+
return self._crm
236+
237+
@property
238+
def filestorage(self):
239+
if self._filestorage is None:
240+
from .resources.filestorage.client import AsyncFilestorageClient # noqa: E402
241+
242+
self._filestorage = AsyncFilestorageClient(client_wrapper=self._client_wrapper)
243+
return self._filestorage
244+
245+
@property
246+
def hris(self):
247+
if self._hris is None:
248+
from .resources.hris.client import AsyncHrisClient # noqa: E402
249+
250+
self._hris = AsyncHrisClient(client_wrapper=self._client_wrapper)
251+
return self._hris
252+
253+
@property
254+
def ticketing(self):
255+
if self._ticketing is None:
256+
from .resources.ticketing.client import AsyncTicketingClient # noqa: E402
257+
258+
self._ticketing = AsyncTicketingClient(client_wrapper=self._client_wrapper)
259+
return self._ticketing
260+
261+
@property
262+
def accounting(self):
263+
if self._accounting is None:
264+
from .resources.accounting.client import AsyncAccountingClient # noqa: E402
265+
266+
self._accounting = AsyncAccountingClient(client_wrapper=self._client_wrapper)
267+
return self._accounting
168268

169269

170270
def _get_base_url(*, base_url: typing.Optional[str] = None, environment: MergeEnvironment) -> str:

src/merge/core/__init__.py

Lines changed: 75 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,81 @@
22

33
# isort: skip_file
44

5-
from .api_error import ApiError
6-
from .client_wrapper import AsyncClientWrapper, BaseClientWrapper, SyncClientWrapper
7-
from .datetime_utils import serialize_datetime
8-
from .file import File, convert_file_dict_to_httpx_tuples, with_content_type
9-
from .http_client import AsyncHttpClient, HttpClient
10-
from .http_response import AsyncHttpResponse, HttpResponse
11-
from .jsonable_encoder import jsonable_encoder
12-
from .pydantic_utilities import (
13-
IS_PYDANTIC_V2,
14-
UniversalBaseModel,
15-
UniversalRootModel,
16-
parse_obj_as,
17-
universal_field_validator,
18-
universal_root_validator,
19-
update_forward_refs,
20-
)
21-
from .query_encoder import encode_query
22-
from .remove_none_from_dict import remove_none_from_dict
23-
from .request_options import RequestOptions
24-
from .serialization import FieldMetadata, convert_and_respect_annotation_metadata
25-
from .unchecked_base_model import UncheckedBaseModel, UnionMetadata, construct_type
5+
import typing
6+
from importlib import import_module
7+
8+
if typing.TYPE_CHECKING:
9+
from .api_error import ApiError
10+
from .client_wrapper import AsyncClientWrapper, BaseClientWrapper, SyncClientWrapper
11+
from .datetime_utils import serialize_datetime
12+
from .file import File, convert_file_dict_to_httpx_tuples, with_content_type
13+
from .http_client import AsyncHttpClient, HttpClient
14+
from .http_response import AsyncHttpResponse, HttpResponse
15+
from .jsonable_encoder import jsonable_encoder
16+
from .pydantic_utilities import (
17+
IS_PYDANTIC_V2,
18+
UniversalBaseModel,
19+
UniversalRootModel,
20+
parse_obj_as,
21+
universal_field_validator,
22+
universal_root_validator,
23+
update_forward_refs,
24+
)
25+
from .query_encoder import encode_query
26+
from .remove_none_from_dict import remove_none_from_dict
27+
from .request_options import RequestOptions
28+
from .serialization import FieldMetadata, convert_and_respect_annotation_metadata
29+
from .unchecked_base_model import UncheckedBaseModel, UnionMetadata, construct_type
30+
_dynamic_imports: typing.Dict[str, str] = {
31+
"ApiError": ".api_error",
32+
"AsyncClientWrapper": ".client_wrapper",
33+
"AsyncHttpClient": ".http_client",
34+
"AsyncHttpResponse": ".http_response",
35+
"BaseClientWrapper": ".client_wrapper",
36+
"FieldMetadata": ".serialization",
37+
"File": ".file",
38+
"HttpClient": ".http_client",
39+
"HttpResponse": ".http_response",
40+
"IS_PYDANTIC_V2": ".pydantic_utilities",
41+
"RequestOptions": ".request_options",
42+
"SyncClientWrapper": ".client_wrapper",
43+
"UncheckedBaseModel": ".unchecked_base_model",
44+
"UnionMetadata": ".unchecked_base_model",
45+
"UniversalBaseModel": ".pydantic_utilities",
46+
"UniversalRootModel": ".pydantic_utilities",
47+
"construct_type": ".unchecked_base_model",
48+
"convert_and_respect_annotation_metadata": ".serialization",
49+
"convert_file_dict_to_httpx_tuples": ".file",
50+
"encode_query": ".query_encoder",
51+
"jsonable_encoder": ".jsonable_encoder",
52+
"parse_obj_as": ".pydantic_utilities",
53+
"remove_none_from_dict": ".remove_none_from_dict",
54+
"serialize_datetime": ".datetime_utils",
55+
"universal_field_validator": ".pydantic_utilities",
56+
"universal_root_validator": ".pydantic_utilities",
57+
"update_forward_refs": ".pydantic_utilities",
58+
"with_content_type": ".file",
59+
}
60+
61+
62+
def __getattr__(attr_name: str) -> typing.Any:
63+
module_name = _dynamic_imports.get(attr_name)
64+
if module_name is None:
65+
raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}")
66+
try:
67+
module = import_module(module_name, __package__)
68+
result = getattr(module, attr_name)
69+
return result
70+
except ImportError as e:
71+
raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e
72+
except AttributeError as e:
73+
raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e
74+
75+
76+
def __dir__():
77+
lazy_attrs = list(_dynamic_imports.keys())
78+
return sorted(lazy_attrs)
79+
2680

2781
__all__ = [
2882
"ApiError",

src/merge/core/client_wrapper.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ def __init__(
2424

2525
def get_headers(self) -> typing.Dict[str, str]:
2626
headers: typing.Dict[str, str] = {
27-
"User-Agent": "MergePythonClient/2.2.0",
27+
"User-Agent": "MergePythonClient/2.3.0",
2828
"X-Fern-Language": "Python",
2929
"X-Fern-SDK-Name": "MergePythonClient",
30-
"X-Fern-SDK-Version": "2.2.0",
30+
"X-Fern-SDK-Version": "2.3.0",
3131
**(self.get_custom_headers() or {}),
3232
}
3333
if self._account_token is not None:

src/merge/resources/__init__.py

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,38 @@
22

33
# isort: skip_file
44

5-
from . import accounting, ats, crm, filestorage, hris, ticketing
5+
import typing
6+
from importlib import import_module
7+
8+
if typing.TYPE_CHECKING:
9+
from . import accounting, ats, crm, filestorage, hris, ticketing
10+
_dynamic_imports: typing.Dict[str, str] = {
11+
"accounting": ".",
12+
"ats": ".",
13+
"crm": ".",
14+
"filestorage": ".",
15+
"hris": ".",
16+
"ticketing": ".",
17+
}
18+
19+
20+
def __getattr__(attr_name: str) -> typing.Any:
21+
module_name = _dynamic_imports.get(attr_name)
22+
if module_name is None:
23+
raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}")
24+
try:
25+
module = import_module(module_name, __package__)
26+
result = getattr(module, attr_name)
27+
return result
28+
except ImportError as e:
29+
raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e
30+
except AttributeError as e:
31+
raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e
32+
33+
34+
def __dir__():
35+
lazy_attrs = list(_dynamic_imports.keys())
36+
return sorted(lazy_attrs)
37+
638

739
__all__ = ["accounting", "ats", "crm", "filestorage", "hris", "ticketing"]

0 commit comments

Comments
 (0)