Errors
Redash

Redash: Using API to create a new query on Redash

Ты решил автоматизировать создание запросов в Redash через API. Нашёл нужный эндпоинт, написал скрипт, а в ответ получаешь безликий `500`. Всё сломалось, или кв

Ты решил автоматизировать создание запросов в Redash через API. Нашёл нужный эндпоинт, написал скрипт, а в ответ получаешь безликий 500. Всё сломалось, или квазары?

Почему POST /api/queries возвращает 500

Код 500 — это Internal Server Error. Чаще всего он означает, что твой запрос дошёл до сервера, но там упал при обработке. В случае с Redash, если посмотреть на исходники, которые ты и приложил, становится ясно.

Эндпоинт POST /api/queries ожидает на вход конкретный набор полей. Взгляни на обработчик:

# redash/handlers/queries.py, строка 84
def post(self):
    ...
    query = models.Query.create(
        name=req.get('name'),
        description=req.get('description', ''),
        query_text=req.get('query'),
        data_source=data_source,
        user=self.current_user,
        ...
    )

Ключевые поля, которые метод create ждёт и без которых будет боль: name, query (текст запроса), data_source (который определяется через data_source_id).

А теперь посмотри на свой JSON:

query_info = {'query':query_content}

Ты отправляешь только текст запроса. Где name? Где data_source_id? Их нет. Модель не может создать объект — и падает с ошибкой валидации, которая на стороне сервера оборачивается в 500.

Как это исправить

Нужно формировать полное тело запроса. Минимально рабочий вариант должен включать три поля:

def new_query(url, api, f, query_id, data_source_id, query_name):
    headers = {'Authorization': 'Key {}'.format(api), 'Content-Type': 'application/json'}
    path = "{}/api/queries".format(url)
    query_content = get_query_content(f)

    query_info = {
        'name': query_name,               # Обязательно
        'query': query_content,           # Обязательно
        'data_source_id': data_source_id  # Обязательно
    }

    print(json.dumps(query_info, indent=2))  # Для отладки
    response = requests.post(path, headers=headers, json=query_info) # Используй json=
    print(response.status_code)
    print(response.text)  # Важно: иногда в теле ответа есть детали ошибки

Обрати внимание: используй requests.post(..., json=query_info). Библиотека сама сериализует dict в JSON и проставит заголовок Content-Type.

Откуда брать data_source_id

Это ID источника данных в твоём Redash. Его можно получить через тот же API, запросив GET /api/data_sources. В ответе будет список объектов с полями id и name.

Итог

Порядок отладки: сформируй правильный JSON с name, query, data_source_id → используй json= параметр в requests → смотри не только на статус, но и на response.text.

Если 500 остаётся — посмотри логи самого Redash. Но в 95% случаев проблема решается добавлением обязательных полей. API Redash не молчит, оно просто ждёт от тебя правильного запроса.

Ссылка на схему API в их документации или исходниках — твой лучший друг. Как и команда curl -v для проверки сырого запроса.