Skip to content

Commit 5e23ca4

Browse files
committed
📝 код-ревью 20: разобрал fixme-комменты из задачи — валидация входа, схема ответа, async-параллелизм get_many
1 parent 5119755 commit 5e23ca4

1 file changed

Lines changed: 16 additions & 4 deletions

File tree

‎code-review-practice/solutions/20_api_response_parser.md‎

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,28 @@
3232
API отдаёт Кельвины; если формат/версия сменится (Цельсий/Фаренгейт), температура молча
3333
станет бессмысленной. Хотя бы вынести константу с именем и не хардкодить конверсию вслепую.
3434

35-
8. **`get_many` падает целиком из-за одного города** (строка 30). Dict-comprehension по всем
36-
городам: первое же исключение в `get_weather` (нет города, таймаут) уронит **весь** батч.
37-
Для устойчивого пакетного запроса стоит обрабатывать ошибки по городу отдельно (собрать
38-
успехи, а неудачи — в отдельный список/лог).
35+
8. **`get_many` падает целиком из-за одного города и работает последовательно** (строка 30).
36+
Dict-comprehension по всем городам: первое же исключение в `get_weather` (нет города, таймаут)
37+
уронит **весь** батч — стоит обрабатывать ошибки по городу отдельно (собрать успехи, а
38+
неудачи — в список/лог). Плюс запросы идут по одному, синхронно: на большом списке городов
39+
это долго. Параллелить — через `asyncio` + async-клиент (`httpx`) или `ThreadPoolExecutor`
40+
с ограничением конкурентности.
3941

4042
9. **`get_forecast` не считает статус/таймаут** — те же проблемы, что 3–5, плюс главный
4143
`eval` из п.1.
4244

4345
10. **Нет аннотаций типов** (все функции). `city: str`, `days: int`, тип результата.
4446

47+
11. **Вход `city`/`days` не валидируется и не нормализуется** (строки 9, 25). Город уходит в
48+
запрос как есть: пустая строка, лишние пробелы, произвольный регистр — всё летит на API
49+
(и ломает URL, см. п.6). Стоит нормализовать (`strip`, регистр) и отклонять заведомо
50+
невалидное; `days` — проверять на разумный диапазон, а не слать любое число.
51+
52+
12. **Ответ возвращается сырым dict без схемы** (строки 18–22, 28). Наружу отдаётся
53+
вручную собранный словарь — контракт клиента нигде не описан, опечатка в ключе не ловится.
54+
Возвращать стоит типизированную модель (dataclass/pydantic), тогда и результат `get_weather`,
55+
и элементы `get_forecast` имеют явный проверяемый формат.
56+
4557
**Итого:** `eval` над ответом (RCE), слепое доверие структуре и отсутствие проверки статуса/
4658
таймаутов. Мораль: ответ внешнего API — недоверенные данные; парсить его `json()` (никогда
4759
`eval`), проверять статус, обкладывать таймаутом и не доверять, что ключи на месте.

0 commit comments

Comments
 (0)