Python: конвертация и скачивание архива
import os
import time
from urllib.parse import urljoin
import requests
BASE_URL = "https://aivio.ru"
API_KEY = os.environ["AIVIO_API_KEY"]
headers = {
"Authorization": f"Api-Key {API_KEY}",
}
def make_url(path_or_url: str) -> str:
return urljoin(BASE_URL, path_or_url)
with open("source.xlsx", "rb") as source_file:
start = requests.post(
make_url("/api/documents/convert/"),
headers=headers,
files={"file": source_file},
timeout=60,
)
start.raise_for_status()
status_url = make_url(start.json()["status_url"])
while True:
status_response = requests.get(status_url, headers=headers, timeout=30)
status_response.raise_for_status()
status = status_response.json()
if status["status"] == "ok":
download_url = make_url(status["download_url"])
archive_response = requests.get(
download_url,
headers=headers,
timeout=120,
stream=True,
allow_redirects=False,
)
archive_response.raise_for_status()
with open("converted_archive.zip", "wb") as archive_file:
for chunk in archive_response.iter_content(chunk_size=1024 * 1024):
if chunk:
archive_file.write(chunk)
print("Архив сохранён: converted_archive.zip")
break
if status["status"] == "error":
print("Ошибка:", status.get("message", "Неизвестная ошибка"))
break
time.sleep(2)
Пример запускает конвертацию, опрашивает status_url и скачивает ZIP-архив отдельным авторизованным запросом.
- Ключ берётся из переменной окружения
AIVIO_API_KEY, а не хранится в коде.
urljoin корректно работает и с относительными, и с абсолютными ссылками из API.
allow_redirects=False помогает увидеть неожиданный редирект вместо скачивания файла.
Python: генерация и скачивание архива
import os
import time
from urllib.parse import urljoin
import requests
BASE_URL = "https://aivio.ru"
API_KEY = os.environ["AIVIO_API_KEY"]
headers = {
"Authorization": f"Api-Key {API_KEY}",
}
def make_url(path_or_url: str) -> str:
return urljoin(BASE_URL, path_or_url)
with open("template.docx", "rb") as template_file, open("data.xlsx", "rb") as data_file:
start = requests.post(
make_url("/api/documents/generate/"),
headers=headers,
files={
"template_file": template_file,
"data_file": data_file,
},
timeout=60,
)
start.raise_for_status()
status_url = make_url(start.json()["status_url"])
while True:
status_response = requests.get(status_url, headers=headers, timeout=30)
status_response.raise_for_status()
status = status_response.json()
if status["status"] == "ok":
download_url = make_url(status["download_url"])
archive_response = requests.get(
download_url,
headers=headers,
timeout=120,
stream=True,
allow_redirects=False,
)
archive_response.raise_for_status()
with open("generated_archive.zip", "wb") as archive_file:
for chunk in archive_response.iter_content(chunk_size=1024 * 1024):
if chunk:
archive_file.write(chunk)
print("Архив сохранён: generated_archive.zip")
break
if status["status"] == "error":
print("Ошибка:", status.get("message", "Неизвестная ошибка"))
break
time.sleep(2)
Пример запускает генерацию документов, ждёт готового статуса и скачивает архив через API-ссылку с тем же ключом.
template_file — шаблон DOCX для генерации.
data_file — Excel-файл с данными.
download_url ведёт на /api/documents/generate/<archive_id>/download/.