Проверили первую строку файла, а в копии она пропала
Учебный импорт открывает поток, читает первую строку и убеждается, что это знакомый заголовок. Затем он копирует поток в архив. Файл открывается, данные на месте, но заголовка нет. Причина в позиции чтения: shutil.copyfileobj начинает копирование с того места, на котором остановился источник.
from io import BytesIO
from shutil import copyfileobj
source = BytesIO(b"id,name\n1,Anna\n")
assert source.readline() == b"id,name\n"
tail = BytesIO()
copyfileobj(source, tail)
assert tail.getvalue() == b"1,Anna\n"
source.seek(0)
whole = BytesIO()
copyfileobj(source, whole)
assert whole.getvalue() == b"id,name\n1,Anna\n"
Сначала реши, что должна содержать копия. Если сохраняешь оригинал для разбора ошибок, заголовок должен остаться. Если задача переносит только записи в уже открытый отчёт с таким же заголовком, копирование с текущей позиции может быть как раз тем, что нужно. Лучше явно назвать это решение в коде: «архив всего входа» и «перенос оставшихся строк» подразумевают разные ожидания.
В примере источник поддерживает возврат в начало. Сетевой поток может его не поддерживать. Тогда для полного архива надо спланировать чтение заранее: сохранить первые байты вместе с оставшимися или открыть источник повторно, если операция допустима. Отдельно от позиции стоит помнить о буферизации назначения: если следующий шаг сразу откроет реальный файл для чтения, заверши запись или сбрось буфер перед передачей.
В проверку включи короткий файл с уникальной первой строкой. Сверь не только размер, но и то, с какой строки начинается результат. Так тест покажет, какой договор выполнила программа, даже если оба получившихся файла технически читаются.
Практические заметки об импорте данных — в личном Telegram.
Пример учебный; текст подготовлен с помощью ИИ.




