b24api 0.3.3__tar.gz → 0.3.5__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.3/b24api.egg-info → b24api-0.3.5}/PKG-INFO +1 -1
- {b24api-0.3.3 → b24api-0.3.5}/b24api/api.py +21 -14
- {b24api-0.3.3 → b24api-0.3.5}/b24api/entity.py +11 -2
- {b24api-0.3.3 → b24api-0.3.5/b24api.egg-info}/PKG-INFO +1 -1
- {b24api-0.3.3 → b24api-0.3.5}/pyproject.toml +1 -1
- {b24api-0.3.3 → b24api-0.3.5}/LICENSE +0 -0
- {b24api-0.3.3 → b24api-0.3.5}/MANIFEST.in +0 -0
- {b24api-0.3.3 → b24api-0.3.5}/README.md +0 -0
- {b24api-0.3.3 → b24api-0.3.5}/b24api/__init__.py +0 -0
- {b24api-0.3.3 → b24api-0.3.5}/b24api/error.py +0 -0
- {b24api-0.3.3 → b24api-0.3.5}/b24api/query.py +0 -0
- {b24api-0.3.3 → b24api-0.3.5}/b24api/settings.py +0 -0
- {b24api-0.3.3 → b24api-0.3.5}/b24api/transport.py +0 -0
- {b24api-0.3.3 → b24api-0.3.5}/b24api/type.py +0 -0
- {b24api-0.3.3 → b24api-0.3.5}/b24api.egg-info/SOURCES.txt +0 -0
- {b24api-0.3.3 → b24api-0.3.5}/b24api.egg-info/dependency_links.txt +0 -0
- {b24api-0.3.3 → b24api-0.3.5}/b24api.egg-info/requires.txt +0 -0
- {b24api-0.3.3 → b24api-0.3.5}/b24api.egg-info/top_level.txt +0 -0
- {b24api-0.3.3 → b24api-0.3.5}/setup.cfg +0 -0
|
@@ -2,6 +2,7 @@ import contextlib
|
|
|
2
2
|
import json
|
|
3
3
|
import logging
|
|
4
4
|
from collections.abc import Generator, Iterable
|
|
5
|
+
from functools import partial
|
|
5
6
|
from itertools import chain, islice
|
|
6
7
|
from operator import itemgetter
|
|
7
8
|
|
|
@@ -22,7 +23,9 @@ class Bitrix24:
|
|
|
22
23
|
self.client = client
|
|
23
24
|
self.settings = settings
|
|
24
25
|
self.logger = logging.getLogger("b24api")
|
|
25
|
-
|
|
26
|
+
|
|
27
|
+
retry_ = partial(
|
|
28
|
+
retry,
|
|
26
29
|
exceptions=(
|
|
27
30
|
httpx.ConnectError,
|
|
28
31
|
httpx.ConnectTimeout,
|
|
@@ -34,13 +37,13 @@ class Bitrix24:
|
|
|
34
37
|
delay=self.settings.retry_delay,
|
|
35
38
|
backoff=self.settings.retry_backoff,
|
|
36
39
|
logger=self.logger,
|
|
37
|
-
)
|
|
40
|
+
)
|
|
41
|
+
self._call_retry = retry_()(self._call)
|
|
42
|
+
self._batch_retry = retry_()(self._batch)
|
|
38
43
|
|
|
39
44
|
def call(self, request: Request | dict) -> ApiTypes:
|
|
40
45
|
"""Call any method (with retries) and return just `result`."""
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
return response.result
|
|
46
|
+
return self._call_retry(request).result
|
|
44
47
|
|
|
45
48
|
def _call(self, request: Request | dict) -> Response:
|
|
46
49
|
"""Call any method and return full response."""
|
|
@@ -87,10 +90,10 @@ class Bitrix24:
|
|
|
87
90
|
|
|
88
91
|
tail_requests = iter(requests)
|
|
89
92
|
while batched_requests := list(islice(tail_requests, batch_size)):
|
|
90
|
-
for response in self.
|
|
93
|
+
for response in self._batch_retry(batched_requests):
|
|
91
94
|
yield response.result
|
|
92
95
|
|
|
93
|
-
def _batch(self, requests: Iterable[Request | dict]) ->
|
|
96
|
+
def _batch(self, requests: Iterable[Request | dict]) -> list[Response]:
|
|
94
97
|
"""Call batch of methods and return full responses."""
|
|
95
98
|
commands = {f"_{i}": Request.model_validate(request) for i, request in enumerate(requests)}
|
|
96
99
|
request = Request(
|
|
@@ -101,10 +104,10 @@ class Bitrix24:
|
|
|
101
104
|
},
|
|
102
105
|
)
|
|
103
106
|
|
|
104
|
-
result = self.
|
|
105
|
-
|
|
107
|
+
result = self._call(request).result
|
|
106
108
|
result = BatchResult.model_validate(result)
|
|
107
109
|
|
|
110
|
+
responses = []
|
|
108
111
|
for i in range(len(commands)):
|
|
109
112
|
key = f"_{i}"
|
|
110
113
|
|
|
@@ -121,13 +124,17 @@ class Bitrix24:
|
|
|
121
124
|
f"Expecting `result_time` to contain result for command {{`{key}`: {command}}}. Got: {result}",
|
|
122
125
|
)
|
|
123
126
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
127
|
+
responses.append(
|
|
128
|
+
Response(
|
|
129
|
+
result=result.result[key],
|
|
130
|
+
time=result.result_time[key],
|
|
131
|
+
total=result.result_total.get(key, None),
|
|
132
|
+
next=result.result_next.get(key, None),
|
|
133
|
+
),
|
|
129
134
|
)
|
|
130
135
|
|
|
136
|
+
return responses
|
|
137
|
+
|
|
131
138
|
def list_sequential(
|
|
132
139
|
self,
|
|
133
140
|
request: Request | dict,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from datetime import datetime
|
|
2
2
|
from typing import Annotated, Any, Self
|
|
3
3
|
|
|
4
|
-
from pydantic import BaseModel, BeforeValidator,
|
|
4
|
+
from pydantic import BaseModel, BeforeValidator, field_validator
|
|
5
5
|
|
|
6
6
|
from b24api.error import ApiResponseError, RetryApiResponseError
|
|
7
7
|
from b24api.query import build_query
|
|
@@ -45,9 +45,18 @@ class ListRequest(Request):
|
|
|
45
45
|
class ErrorResponse(BaseModel):
|
|
46
46
|
"""API error response."""
|
|
47
47
|
|
|
48
|
-
error:
|
|
48
|
+
error: str | int
|
|
49
49
|
error_description: str
|
|
50
50
|
|
|
51
|
+
@field_validator("error")
|
|
52
|
+
@classmethod
|
|
53
|
+
def error_to_lower_str(cls, value: Any) -> Any: # noqa: ANN401
|
|
54
|
+
if not isinstance(value, int):
|
|
55
|
+
value = str(value)
|
|
56
|
+
if isinstance(value, str):
|
|
57
|
+
value = value.lower()
|
|
58
|
+
return value
|
|
59
|
+
|
|
51
60
|
def raise_error(self, retry_errors: list[str]) -> Self:
|
|
52
61
|
if self.error in retry_errors:
|
|
53
62
|
raise RetryApiResponseError(
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|