Skip to content

Commit

Permalink
Исправить и упростить обработку вложенных результатов с сервера (#237)
Browse files Browse the repository at this point in the history
* Fix and simplify extraction of nested single item non-batch results
Fixes #235

* Remove double spaces
  • Loading branch information
leshchenko1979 authored May 21, 2024
1 parent 158af5c commit 30a5bc0
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 21 deletions.
2 changes: 1 addition & 1 deletion fast_bitrix24/mult_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ def process_done_tasks(self, done: list) -> int:
elif isinstance(extracted, dict):
self.results.update(extracted)

extracted_len += len(extracted)
extracted_len += len(extracted) if isinstance(extracted, list) else 1

return extracted_len

Expand Down
20 changes: 6 additions & 14 deletions fast_bitrix24/server_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,29 +70,19 @@ def is_batch(self) -> bool:
return isinstance(self.result, dict) and "result" in self.result

def extract_from_single_response(self, result: dict):
# если результат вызова содержит только словарь {ключ: список},
# то вернуть этот список.
# если результат вызова содержит только словарь из одного элемента {ключ: содержимое},
# то вернуть это содержимое.
# См. https://github.com/leshchenko1979/fast_bitrix24/issues/132

# метод `crm.stagehistory.list` возвращает dict["items", list] --
# разворачиваем его в список

if self.is_nested(result):
contents = self.extract_from_nested(result)
if isinstance(contents, list):
return contents

return result
return next(iter(result.values())) if self.is_nested(result) else result

@staticmethod
def is_nested(result) -> bool:
return isinstance(result, dict) and len(result) == 1

@staticmethod
def extract_from_nested(result: dict):
return next(iter(result.values()))


def extract_from_batch_response(self, result) -> list:

if not result:
Expand All @@ -111,7 +101,9 @@ def extract_from_batch_response(self, result) -> list:
for element in result.values()
]

result_list = list(chain(*result_list))
# если получился вложенный список, то уплощаем
if isinstance(result_list[0], list):
result_list = list(chain(*result_list))

return result_list

Expand Down
11 changes: 5 additions & 6 deletions fast_bitrix24/user_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -327,13 +327,12 @@ async def run(self):
get_by_ID=False,
).run()

if isinstance(raw_results, dict):
results = tuple(raw_results.values())
if isinstance(raw_results, dict) and not is_single_item:
return tuple(raw_results.values())
elif raw_results and isinstance(raw_results, list) and is_single_item:
return raw_results[0]
else:
# бывают случаи, что возвращается список
results = raw_results

return results[0] if results and is_single_item else results
return raw_results

def prepare_item_list(self):
# При отправке батчей на сервер результаты приходят не в том порядке,
Expand Down
41 changes: 41 additions & 0 deletions tests/real_responses/crm_item_add.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
response = {
"result": {
"result": {
"order0000000000": {
"item": {
"id": 247,
"xmlId": "",
"title": "Андрей Макарцев\n",
"createdBy": 6511,
"updatedBy": 6511,
"movedBy": 6511,
"createdTime": "2024-05-21T15:14:26+03:00",
"updatedTime": "2024-05-21T15:14:27+03:00",
"movedTime": "2024-05-21T15:14:26+03:00",
"entityTypeId": 133,
}
}
},
"result_error": [],
"result_total": [],
"result_next": [],
"result_time": {
"order0000000000": {
"start": 1716293667.476324,
"finish": 1716293667.52081,
"duration": 0.04448580741882324,
"processing": 0.04400205612182617,
"date_start": "2024-05-21T15:14:27+03:00",
"date_finish": "2024-05-21T15:14:27+03:00",
}
},
},
"time": {
"start": 1716293667.454244,
"finish": 1716293667.52083,
"duration": 0.06658601760864258,
"processing": 0.04455399513244629,
"date_start": "2024-05-21T15:14:27+03:00",
"date_finish": "2024-05-21T15:14:27+03:00",
},
}
10 changes: 10 additions & 0 deletions tests/test_server_responses.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,3 +260,13 @@ def test_socialnetwork_api_workgroup_list(bx_dummy):
)

assert len(results) == 50


def test_crm_add_item(bx_dummy):
from tests.real_responses.crm_item_add import response

bx_dummy.srh = MockSRH(response)
result = bx_dummy.call(
"crm.item.add", {"entityTypeId": 1, "fields": {"first_name": "first_name"}}
)
assert result != "item" and isinstance(result, dict) and "id" in result

0 comments on commit 30a5bc0

Please sign in to comment.