b24api 0.3.9__tar.gz → 0.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {b24api-0.3.9/b24api.egg-info → b24api-0.4.0}/PKG-INFO +2 -2
- {b24api-0.3.9 → b24api-0.4.0}/b24api/api.py +90 -57
- {b24api-0.3.9 → b24api-0.4.0}/b24api/query.py +1 -4
- {b24api-0.3.9 → b24api-0.4.0}/b24api/settings.py +10 -8
- {b24api-0.3.9 → b24api-0.4.0/b24api.egg-info}/PKG-INFO +2 -2
- {b24api-0.3.9 → b24api-0.4.0}/b24api.egg-info/SOURCES.txt +0 -1
- {b24api-0.3.9 → b24api-0.4.0}/b24api.egg-info/requires.txt +1 -1
- {b24api-0.3.9 → b24api-0.4.0}/pyproject.toml +1 -1
- b24api-0.3.9/b24api/transport.py +0 -14
- {b24api-0.3.9 → b24api-0.4.0}/LICENSE +0 -0
- {b24api-0.3.9 → b24api-0.4.0}/MANIFEST.in +0 -0
- {b24api-0.3.9 → b24api-0.4.0}/README.md +0 -0
- {b24api-0.3.9 → b24api-0.4.0}/b24api/__init__.py +0 -0
- {b24api-0.3.9 → b24api-0.4.0}/b24api/entity.py +0 -0
- {b24api-0.3.9 → b24api-0.4.0}/b24api/error.py +0 -0
- {b24api-0.3.9 → b24api-0.4.0}/b24api/type.py +0 -0
- {b24api-0.3.9 → b24api-0.4.0}/b24api.egg-info/dependency_links.txt +0 -0
- {b24api-0.3.9 → b24api-0.4.0}/b24api.egg-info/top_level.txt +0 -0
- {b24api-0.3.9 → b24api-0.4.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: b24api
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: Bitrix24 API
|
|
5
5
|
Requires-Python: >=3.10
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
@@ -9,7 +9,7 @@ Requires-Dist: fast-depends>=2.4.12
|
|
|
9
9
|
Requires-Dist: httpx[http2]>=0.28.1
|
|
10
10
|
Requires-Dist: pydantic>=2.10.6
|
|
11
11
|
Requires-Dist: pydantic-settings>=2.8.1
|
|
12
|
-
Requires-Dist:
|
|
12
|
+
Requires-Dist: tenacity>=9.1.2
|
|
13
13
|
Dynamic: license-file
|
|
14
14
|
|
|
15
15
|
# API client for Bitrix24
|
|
@@ -1,49 +1,50 @@
|
|
|
1
1
|
import contextlib
|
|
2
|
-
import json
|
|
3
2
|
import logging
|
|
4
3
|
from collections.abc import Generator, Iterable
|
|
5
|
-
from functools import partial
|
|
6
4
|
from itertools import chain, islice
|
|
7
5
|
from operator import itemgetter
|
|
6
|
+
from typing import Any
|
|
8
7
|
|
|
9
8
|
import h2.exceptions
|
|
10
9
|
import httpx
|
|
11
10
|
from fast_depends import inject
|
|
11
|
+
from httpx import Client
|
|
12
12
|
from pydantic import ValidationError
|
|
13
|
-
from
|
|
13
|
+
from tenacity import Retrying, before_sleep_log, retry_if_exception_type, stop_after_attempt, wait_exponential
|
|
14
14
|
|
|
15
15
|
from b24api.entity import ApiTypes, BatchResult, ErrorResponse, ListRequest, Request, Response
|
|
16
16
|
from b24api.error import RetryApiResponseError, RetryHTTPStatusError
|
|
17
17
|
from b24api.settings import ApiSettings
|
|
18
|
-
from b24api.transport import HttpxClient
|
|
19
18
|
|
|
20
19
|
|
|
21
20
|
class Bitrix24:
|
|
21
|
+
http: Client = Client(http2=True)
|
|
22
|
+
|
|
22
23
|
@inject
|
|
23
|
-
def __init__(self,
|
|
24
|
-
self.client = client
|
|
24
|
+
def __init__(self, settings: ApiSettings) -> None:
|
|
25
25
|
self.settings = settings
|
|
26
26
|
self.logger = logging.getLogger("b24api")
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
28
|
+
self.http.timeout = self.settings.http_timeout
|
|
29
|
+
|
|
30
|
+
self.retry = Retrying(
|
|
31
|
+
retry=retry_if_exception_type(
|
|
32
|
+
(
|
|
33
|
+
httpx.TransportError,
|
|
34
|
+
h2.exceptions.ProtocolError,
|
|
35
|
+
RetryHTTPStatusError,
|
|
36
|
+
RetryApiResponseError,
|
|
37
|
+
),
|
|
35
38
|
),
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
39
|
+
wait=wait_exponential(multiplier=self.settings.retry_delay, exp_base=self.settings.retry_backoff),
|
|
40
|
+
stop=stop_after_attempt(self.settings.retry_attempts),
|
|
41
|
+
before_sleep=before_sleep_log(self.logger, logging.WARNING),
|
|
42
|
+
reraise=True,
|
|
40
43
|
)
|
|
41
|
-
self._call_retry = retry_()(self._call)
|
|
42
|
-
self._batch_retry = retry_()(self._batch)
|
|
43
44
|
|
|
44
45
|
def call(self, request: Request | dict) -> ApiTypes:
|
|
45
|
-
"""Call any method (with retries) and return
|
|
46
|
-
return self.
|
|
46
|
+
"""Call any method (with retries) and return `result` from response."""
|
|
47
|
+
return self.retry(self._call, request).result
|
|
47
48
|
|
|
48
49
|
def _call(self, request: Request | dict) -> Response:
|
|
49
50
|
"""Call any method and return full response."""
|
|
@@ -51,17 +52,17 @@ class Bitrix24:
|
|
|
51
52
|
|
|
52
53
|
self.logger.debug("Sending request: %s", request)
|
|
53
54
|
|
|
54
|
-
http_response = self.
|
|
55
|
+
http_response = self.http.post(
|
|
55
56
|
f"{self.settings.webhook_url}{request.method}",
|
|
56
57
|
headers={"Content-Type": "application/json"},
|
|
57
58
|
json=request.model_dump(mode="json")["parameters"],
|
|
58
59
|
)
|
|
59
60
|
|
|
60
|
-
with contextlib.suppress(httpx.ResponseNotRead,
|
|
61
|
-
ErrorResponse.
|
|
61
|
+
with contextlib.suppress(httpx.ResponseNotRead, ValidationError):
|
|
62
|
+
ErrorResponse.model_validate_json(http_response.content).raise_error(self.settings.retry_errors)
|
|
62
63
|
|
|
63
64
|
try:
|
|
64
|
-
|
|
65
|
+
http_response.raise_for_status()
|
|
65
66
|
except httpx.HTTPStatusError as error:
|
|
66
67
|
if http_response.status_code in self.settings.retry_statuses:
|
|
67
68
|
raise RetryHTTPStatusError(
|
|
@@ -71,30 +72,36 @@ class Bitrix24:
|
|
|
71
72
|
) from error
|
|
72
73
|
raise
|
|
73
74
|
|
|
74
|
-
|
|
75
|
-
ErrorResponse.model_validate(json_response).raise_error(self.settings.retry_errors)
|
|
76
|
-
|
|
77
|
-
response = Response.model_validate(json_response)
|
|
78
|
-
|
|
75
|
+
response = Response.model_validate_json(http_response.content)
|
|
79
76
|
self.logger.debug("Received response: %s", response)
|
|
80
77
|
|
|
81
78
|
return response
|
|
82
79
|
|
|
83
80
|
def batch(
|
|
84
81
|
self,
|
|
85
|
-
requests: Iterable[Request | dict],
|
|
82
|
+
requests: Iterable[Request | dict | tuple[Request | dict, Any]],
|
|
83
|
+
*,
|
|
86
84
|
batch_size: int | None = None,
|
|
87
|
-
|
|
88
|
-
|
|
85
|
+
with_payload: bool = False,
|
|
86
|
+
) -> Generator[ApiTypes | tuple[ApiTypes, Any]]:
|
|
87
|
+
"""Call unlimited sequence of methods within batches and return `result` from responses."""
|
|
89
88
|
batch_size = batch_size or self.settings.batch_size
|
|
90
89
|
|
|
91
90
|
tail_requests = iter(requests)
|
|
92
91
|
while batched_requests := list(islice(tail_requests, batch_size)):
|
|
93
|
-
|
|
94
|
-
|
|
92
|
+
if with_payload:
|
|
93
|
+
batched_requests, batched_payloads = zip(*batched_requests, strict=True)
|
|
94
|
+
else:
|
|
95
|
+
batched_payloads = None
|
|
96
|
+
|
|
97
|
+
for i, response in enumerate(self.retry(self._batch, batched_requests)):
|
|
98
|
+
if with_payload:
|
|
99
|
+
yield response.result, batched_payloads[i]
|
|
100
|
+
else:
|
|
101
|
+
yield response.result
|
|
95
102
|
|
|
96
103
|
def _batch(self, requests: Iterable[Request | dict]) -> list[Response]:
|
|
97
|
-
"""Call batch of methods and return full responses."""
|
|
104
|
+
"""Call limited batch of methods and return full responses."""
|
|
98
105
|
commands = {f"_{i}": Request.model_validate(request) for i, request in enumerate(requests)}
|
|
99
106
|
request = Request(
|
|
100
107
|
method="batch",
|
|
@@ -138,8 +145,9 @@ class Bitrix24:
|
|
|
138
145
|
def list_sequential(
|
|
139
146
|
self,
|
|
140
147
|
request: Request | dict,
|
|
148
|
+
*,
|
|
141
149
|
list_size: int | None = None,
|
|
142
|
-
) -> Generator[ApiTypes
|
|
150
|
+
) -> Generator[ApiTypes]:
|
|
143
151
|
"""Call `list` method and return full `result`.
|
|
144
152
|
|
|
145
153
|
Slow (sequential tail) list gathering for methods without `filter` parameter (e.g. `department.get`).
|
|
@@ -150,7 +158,7 @@ class Bitrix24:
|
|
|
150
158
|
head_request = request.model_copy(deep=True)
|
|
151
159
|
head_request.parameters["start"] = 0
|
|
152
160
|
|
|
153
|
-
head_response = self.
|
|
161
|
+
head_response = self.retry(self._call, head_request)
|
|
154
162
|
yield from self._fix_list_result(head_response.result)
|
|
155
163
|
|
|
156
164
|
if head_response.next and head_response.next != list_size:
|
|
@@ -160,7 +168,7 @@ class Bitrix24:
|
|
|
160
168
|
for start in range(list_size, total, list_size):
|
|
161
169
|
tail_request = head_request.model_copy(deep=True)
|
|
162
170
|
tail_request.parameters["start"] = start
|
|
163
|
-
tail_response = self.
|
|
171
|
+
tail_response = self.retry(self._call, tail_request)
|
|
164
172
|
|
|
165
173
|
if tail_response.next and tail_response.next != start + list_size:
|
|
166
174
|
raise ValueError(
|
|
@@ -171,9 +179,10 @@ class Bitrix24:
|
|
|
171
179
|
def list_batched(
|
|
172
180
|
self,
|
|
173
181
|
request: Request | dict,
|
|
182
|
+
*,
|
|
174
183
|
list_size: int | None = None,
|
|
175
184
|
batch_size: int | None = None,
|
|
176
|
-
) -> Generator[ApiTypes
|
|
185
|
+
) -> Generator[ApiTypes]:
|
|
177
186
|
"""Call `list` method and return full `result`.
|
|
178
187
|
|
|
179
188
|
Faster (batched tail) list gathering for methods without `filter` parameter (e.g. `department.get`).
|
|
@@ -185,20 +194,20 @@ class Bitrix24:
|
|
|
185
194
|
head_request = request.model_copy(deep=True)
|
|
186
195
|
head_request.parameters["start"] = 0
|
|
187
196
|
|
|
188
|
-
head_response = self.
|
|
197
|
+
head_response = self.retry(self._call, head_request)
|
|
189
198
|
yield from self._fix_list_result(head_response.result)
|
|
190
199
|
|
|
191
200
|
if head_response.next and head_response.next != list_size:
|
|
192
201
|
raise ValueError(f"Expecting chunk size to be {list_size}. Got: {head_response.next}")
|
|
193
202
|
|
|
194
|
-
def _tail_requests() -> Generator[Request
|
|
203
|
+
def _tail_requests() -> Generator[Request]:
|
|
195
204
|
total = head_response.total or 0
|
|
196
205
|
for start in range(list_size, total, list_size):
|
|
197
206
|
tail_request = head_request.model_copy(deep=True)
|
|
198
207
|
tail_request.parameters["start"] = start
|
|
199
208
|
yield tail_request
|
|
200
209
|
|
|
201
|
-
tail_responses = self.batch(_tail_requests(), batch_size)
|
|
210
|
+
tail_responses = self.batch(_tail_requests(), batch_size=batch_size)
|
|
202
211
|
tail_responses = map(self._fix_list_result, tail_responses)
|
|
203
212
|
tail_responses = chain.from_iterable(tail_responses)
|
|
204
213
|
yield from tail_responses
|
|
@@ -206,10 +215,11 @@ class Bitrix24:
|
|
|
206
215
|
def list_batched_no_count(
|
|
207
216
|
self,
|
|
208
217
|
request: ListRequest | dict,
|
|
218
|
+
*,
|
|
209
219
|
id_key: str = "ID",
|
|
210
220
|
list_size: int | None = None,
|
|
211
221
|
batch_size: int | None = None,
|
|
212
|
-
) -> Generator[ApiTypes
|
|
222
|
+
) -> Generator[ApiTypes]:
|
|
213
223
|
"""Call `list` method and return full `result`.
|
|
214
224
|
|
|
215
225
|
Fastest (batched, no count) list gathering for methods with `filter` parameter (e.g. `crm.lead.list`).
|
|
@@ -232,7 +242,7 @@ class Bitrix24:
|
|
|
232
242
|
)
|
|
233
243
|
|
|
234
244
|
if request.parameters.order:
|
|
235
|
-
raise ValueError("Ordering parameters are reserved
|
|
245
|
+
raise ValueError("Ordering parameters are reserved in `list_batched_no_count`")
|
|
236
246
|
|
|
237
247
|
head_request = request.model_copy(deep=True)
|
|
238
248
|
head_request.parameters.start = -1
|
|
@@ -242,14 +252,14 @@ class Bitrix24:
|
|
|
242
252
|
tail_request.parameters.start = -1
|
|
243
253
|
tail_request.parameters.order = {"ID": "DESC"}
|
|
244
254
|
|
|
245
|
-
head_tail_result = self.batch([head_request, tail_request])
|
|
255
|
+
head_tail_result = self.batch([head_request, tail_request], batch_size=batch_size)
|
|
246
256
|
head_result, tail_result = tuple(map(self._fix_list_result, head_tail_result))
|
|
247
257
|
yield from head_result
|
|
248
258
|
|
|
249
259
|
max_head_id = max(map(int, map(get_id, head_result)), default=None)
|
|
250
260
|
min_tail_id = min(map(int, map(get_id, tail_result)), default=None)
|
|
251
261
|
|
|
252
|
-
def _body_requests() -> Generator[ListRequest
|
|
262
|
+
def _body_requests() -> Generator[ListRequest]:
|
|
253
263
|
for start in range(max_head_id, min_tail_id, list_size):
|
|
254
264
|
body_request = head_request.model_copy(deep=True)
|
|
255
265
|
body_request.parameters.filter[id_from] = start
|
|
@@ -257,7 +267,7 @@ class Bitrix24:
|
|
|
257
267
|
yield body_request
|
|
258
268
|
|
|
259
269
|
if max_head_id and min_tail_id and max_head_id < min_tail_id:
|
|
260
|
-
body = self.batch(_body_requests(), batch_size)
|
|
270
|
+
body = self.batch(_body_requests(), batch_size=batch_size)
|
|
261
271
|
body = map(self._fix_list_result, body)
|
|
262
272
|
body = chain.from_iterable(body)
|
|
263
273
|
yield from body
|
|
@@ -269,12 +279,14 @@ class Bitrix24:
|
|
|
269
279
|
def reference_batched_no_count(
|
|
270
280
|
self,
|
|
271
281
|
request: ListRequest | dict,
|
|
272
|
-
updates: Iterable[dict],
|
|
282
|
+
updates: Iterable[dict | tuple[dict, Any]],
|
|
283
|
+
*,
|
|
273
284
|
id_key: str = "ID",
|
|
274
285
|
list_size: int | None = None,
|
|
275
286
|
batch_size: int | None = None,
|
|
276
|
-
|
|
277
|
-
|
|
287
|
+
with_payload: bool = False,
|
|
288
|
+
) -> Generator[ApiTypes | tuple[ApiTypes, Any]]:
|
|
289
|
+
"""Call `list` method with reference `updates` for `filter` and return full `result`.
|
|
278
290
|
|
|
279
291
|
Fastest (batched, no count) list gathering for methods with `filter` parameter and required `reference`
|
|
280
292
|
(e.g. `crm.timeline.comment.list`).
|
|
@@ -299,8 +311,13 @@ class Bitrix24:
|
|
|
299
311
|
if request.parameters.order:
|
|
300
312
|
raise ValueError("Ordering parameters are reserved `order`in `reference_batched_no_count`")
|
|
301
313
|
|
|
302
|
-
def _tail_requests() -> Generator[ListRequest
|
|
314
|
+
def _tail_requests() -> Generator[ListRequest | tuple[ListRequest, Any]]:
|
|
303
315
|
for update in updates:
|
|
316
|
+
if with_payload:
|
|
317
|
+
update, payload = update
|
|
318
|
+
else:
|
|
319
|
+
payload = None
|
|
320
|
+
|
|
304
321
|
if id_from in update:
|
|
305
322
|
raise ValueError(
|
|
306
323
|
f"Filter parameters `{id_from}` is reserved in `reference_batched_no_count`",
|
|
@@ -309,21 +326,37 @@ class Bitrix24:
|
|
|
309
326
|
tail_request.parameters.filter |= update
|
|
310
327
|
tail_request.parameters.start = -1
|
|
311
328
|
tail_request.parameters.order = {"ID": "ASC"}
|
|
312
|
-
|
|
329
|
+
|
|
330
|
+
if with_payload:
|
|
331
|
+
yield tail_request, payload
|
|
332
|
+
else:
|
|
333
|
+
yield tail_request
|
|
313
334
|
|
|
314
335
|
head_requests = []
|
|
315
336
|
tail_requests = iter(_tail_requests())
|
|
316
337
|
while body_requests := head_requests + list(islice(tail_requests, batch_size - len(head_requests))):
|
|
317
|
-
|
|
338
|
+
if with_payload:
|
|
339
|
+
body_requests, body_payloads = zip(*body_requests, strict=True)
|
|
340
|
+
else:
|
|
341
|
+
body_payloads = None
|
|
342
|
+
|
|
343
|
+
body_results = self.batch(body_requests, batch_size=batch_size)
|
|
318
344
|
body_results = map(self._fix_list_result, body_results)
|
|
319
345
|
|
|
320
346
|
head_requests = []
|
|
321
|
-
for body_request, body_result in zip(body_requests, body_results, strict=True):
|
|
347
|
+
for i, (body_request, body_result) in enumerate(zip(body_requests, body_results, strict=True)):
|
|
322
348
|
if len(body_result) == list_size:
|
|
323
349
|
max_id = max(map(int, map(get_id, body_result)), default=None)
|
|
324
350
|
head_request = body_request.model_copy(deep=True)
|
|
325
351
|
head_request.parameters.filter[id_from] = max_id
|
|
326
|
-
|
|
352
|
+
if with_payload:
|
|
353
|
+
head_requests.append((head_request, body_payloads[i]))
|
|
354
|
+
else:
|
|
355
|
+
head_requests.append(head_request)
|
|
356
|
+
|
|
357
|
+
if with_payload:
|
|
358
|
+
body_payload = [body_payloads[i]] * len(body_result)
|
|
359
|
+
body_result = zip(body_result, body_payload, strict=True)
|
|
327
360
|
|
|
328
361
|
yield from body_result
|
|
329
362
|
|
|
@@ -354,6 +387,6 @@ class Bitrix24:
|
|
|
354
387
|
value = result[key]
|
|
355
388
|
|
|
356
389
|
if not isinstance(value, list):
|
|
357
|
-
raise TypeError(f"If `result` is a `dict`, expecting single `list
|
|
390
|
+
raise TypeError(f"If `result` is a `dict`, expecting single item to be a `list`. Got: {result}")
|
|
358
391
|
|
|
359
392
|
return value
|
|
@@ -5,10 +5,7 @@ from b24api.type import ApiTypes
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
def build_query(parameters: dict[int | str, ApiTypes], path: str = "%s") -> str:
|
|
8
|
-
query = []
|
|
9
|
-
|
|
10
|
-
if parameters is None:
|
|
11
|
-
return ""
|
|
8
|
+
query: list[str] = []
|
|
12
9
|
|
|
13
10
|
for key, value in parameters.items():
|
|
14
11
|
if value is None:
|
|
@@ -8,14 +8,10 @@ from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
class Settings(BaseSettings):
|
|
11
|
-
model_config = SettingsConfigDict(
|
|
12
|
-
env_prefix="bitrix24_api_",
|
|
13
|
-
env_file=".env",
|
|
14
|
-
extra="ignore",
|
|
15
|
-
)
|
|
16
|
-
|
|
17
11
|
webhook_url: HttpUrl
|
|
18
12
|
|
|
13
|
+
http_timeout: int = 30
|
|
14
|
+
|
|
19
15
|
retry_statuses: list[int] = (
|
|
20
16
|
codes.LOCKED,
|
|
21
17
|
codes.TOO_EARLY,
|
|
@@ -27,15 +23,21 @@ class Settings(BaseSettings):
|
|
|
27
23
|
)
|
|
28
24
|
retry_errors: list[str] = ["query_limit_exceeded", "operation_time_limit"]
|
|
29
25
|
|
|
30
|
-
|
|
26
|
+
retry_attempts: int = 5
|
|
31
27
|
retry_delay: float = 5
|
|
32
28
|
retry_backoff: float = 2
|
|
33
29
|
|
|
34
30
|
list_size: int = 50
|
|
35
31
|
batch_size: int = 50
|
|
36
32
|
|
|
33
|
+
model_config = SettingsConfigDict(
|
|
34
|
+
env_prefix="bitrix24_api_",
|
|
35
|
+
env_file=".env",
|
|
36
|
+
extra="ignore",
|
|
37
|
+
)
|
|
38
|
+
|
|
37
39
|
|
|
38
|
-
def api_settings(**kwargs: dict) -> Generator[Settings
|
|
40
|
+
def api_settings(**kwargs: dict) -> Generator[Settings]:
|
|
39
41
|
settings = Settings(**kwargs)
|
|
40
42
|
yield settings
|
|
41
43
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: b24api
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: Bitrix24 API
|
|
5
5
|
Requires-Python: >=3.10
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
@@ -9,7 +9,7 @@ Requires-Dist: fast-depends>=2.4.12
|
|
|
9
9
|
Requires-Dist: httpx[http2]>=0.28.1
|
|
10
10
|
Requires-Dist: pydantic>=2.10.6
|
|
11
11
|
Requires-Dist: pydantic-settings>=2.8.1
|
|
12
|
-
Requires-Dist:
|
|
12
|
+
Requires-Dist: tenacity>=9.1.2
|
|
13
13
|
Dynamic: license-file
|
|
14
14
|
|
|
15
15
|
# API client for Bitrix24
|
b24api-0.3.9/b24api/transport.py
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
from collections.abc import Generator
|
|
2
|
-
from typing import Annotated
|
|
3
|
-
|
|
4
|
-
from fast_depends import Depends
|
|
5
|
-
from httpx import Client
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
def httpx_client() -> Generator[Client, None, None]:
|
|
9
|
-
client = Client(http2=True, timeout=30)
|
|
10
|
-
|
|
11
|
-
yield client
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
HttpxClient = Annotated[Client, Depends(httpx_client)]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|