Запросы API

paulwinex
Сообщения: 83
Зарегистрирован: Пт июл 14, 2017 9:50 am

Запросы API

Сообщение paulwinex »

Разбираюсь с API, стараюсь понять что и как омжно получать потравляя запросы в виде JSON.
Появляются порой вопросы которые буду спрашивать в этйо ветке.

Начну с такого вопроса:
Пример запросов из консоли WebGUI (сокращёные)

Код: Выделить всё

{"get":{"type":"jobs","ids":[2],"mode":"progress"}}
{"get":{"type":"jobs","mode":"info","ids":[2],"block_ids":[0],"task_ids":[0]}}
{"get":{"type":"jobs","mode":"error_hosts","ids":[2],"block_ids":[0],"task_ids":[0]}}
Во всех запросах есть поля типа ids, block_ids, task_ids в которых содержится список id. Очевидно что в ответе придёт тоже список объектов с соответствующим id. Но в консоли список всегда состоит из одного элемнета и возвращается всегда один объект. Даже если я в список подкину несколько id то всё равно приходит один объект.
Список приходит в некоторых командах когда не задаю списка вообще, приходят все объекты.

Код: Выделить всё

{"get":{"type":"jobs"}}
Вопрос. Зачем есть возможность указывать список id? Быть может для каких-то отдельных команд? Например как получить info обо всех или выборочных тасках блока? По одному же вытаскивать даже если из 10000? Или указать список нужных id и получить список словариков?
Аватара пользователя
Timur
Site Admin
Сообщения: 178
Зарегистрирован: Вс июл 09, 2017 4:59 pm
Откуда: Королёв
Контактная информация:

Re: Запросы API

Сообщение Timur »

Некоторые типы запросов поддерживают список, некоторые нет.
Для унификации (просто меньше с++ кода), парсит одна и таже ф-ия, которая ожидает array.
Вам нужен прогресс сразу от списка задачь? Обычно наблюдаешь за одной, иногда за несколькими.
Тоже самое могу сказать про "info" и "error_hosts".
Вы пишете упрощенное гуи, или вы хотите написать гуи которое будет иметь функционал выше чем afwatch/web?
Если не выше - то всё что вам нужно есть. Совершаете действие - смотрите логи.
Если выше - не получится.
API не разрабатывалось на все случаи жизни, думаю так делается везде.
API обслуживает только текущие нужды интерфейсов.
Тимур Хайрулин
CGRU 3.3.1 Ubuntu 22.04LTS, MS Windows 10 (clients only).
paulwinex
Сообщения: 83
Зарегистрирован: Пт июл 14, 2017 9:50 am

Re: Запросы API

Сообщение paulwinex »

Я делаю что-то вроде WebUI но очень минималистичный. Я так понимаю что в стандартном используются мониторы, а у меня их нет. Тут надо либо поштучно все собирать либо монитор писать.
Тогда требуется мне на Python сделать простой монитор. Как он выглядит? Есть где пример? Я видел только примеры регистрации, а пример создания пока не встречал. В исходниках искать сложновато. Что он вообще из себя представляет? Хотя бы общая концепция.
Аватара пользователя
Timur
Site Admin
Сообщения: 178
Зарегистрирован: Вс июл 09, 2017 4:59 pm
Откуда: Королёв
Контактная информация:

Re: Запросы API

Сообщение Timur »

На питоне примера зарегистрированного монитора нет.
В питон API такого тоже не предусмотрено, так как никому не надо было.
Как сделать монитор, надо искать в исходниках WebGUI, я бы сам там искал, или вы думаете я всё всегда помню?
Т.е. не существует ни одного монитора на питоне.
Вам придётся делать (разрабатывать с "0") это первым.
Можно ещё переписать JavaScript (WebGUI) на питон.

пс
А зачем гуи типа клиент-сервер на питоне?
HTML5 уже давно лидер в таких видах гуи.
Питон лучше подходит для скриптов, для API, для написания собственных окошек, в программах с питоном.
Можно локальный диалог сделать при помощи PyQt (когда надо запускать локальные команды и нет сервера, например mass-rename).
Но у вас уже есть HTTP сервер и Web браузер.
Браузер легко устанавливается на любом клиенте, а так вам ещё и питон и PyQt (или что у вас рисует) ставить.
Вы если сделаете лёгкое WebGUI, то потом его с лёгкостью на любом телефоне запустите.
Тимур Хайрулин
CGRU 3.3.1 Ubuntu 22.04LTS, MS Windows 10 (clients only).
paulwinex
Сообщения: 83
Зарегистрирован: Пт июл 14, 2017 9:50 am

Re: Запросы API

Сообщение paulwinex »

А зачем гуи типа клиент-сервер на питоне?
Я не точно объяснил. Сам GUI конечно на HTML5 но находится он на сервере удалённом. На локальном компе находится процесс написаный на питоне который собирает данные с afserver, формирует правильный вид и отправляет на основной сервер по WS. У него вообще нет интерфейса. На удалённой сервер такие данные отправляют несколько ферм и там отображается общая статистика, почти без возможности управления кроме базовых вкл\выкл.

Если нет монитора на python то я готов сделать свой, только мне бы понять принцип действия. Это сервер который просто ждет входящие сообщения на конкретный порт, или соединение по WebSocket или TCP, или запросы на свервер с какойто периодичностью с указанием id монитора?
Как именно соединяется он с сервером и получает обновления если говорить о принципе работы?

Я пошерстил исходники и нашел таку функцию
https://github.com/CGRU/cgru/blob/f7d94 ... er.js#L311
В которой ясно видно что идет запрос на сервер раз в 1 сек. При этом отправляется такой JSON

Код: Выделить всё

{get: {type: "monitors", ids: [1], mode: "events"}}
Ок, значит сервер для нас собирает изменения и возвращает по запросу. Остается только периодически спршивать обновления. Тогда нам надо зарегистрировать свой монитор.
Следуя примеру отсюда https://github.com/CGRU/cgru/blob/maste ... ister.json отправляем запрос на сервер.

Код: Выделить всё

cmd = af.Cmd()
cmd.data = {'user_name': "paul", 'host_name': "hostname", 'engine': "python"}
cmd.action = 'monitor'
r = cmd._sendRequest()
И из полученного результата

Код: Выделить всё

{
  "monitor": {
    "address": {
      "family": 4,
      "ip": "127.0.0.1",
      "port": 0
    },
    "engine": "python",
    "events": [],
    "id": 2,
    "name": "paul@hostname",
    "priority": 99,
    "time_activity": 0,
    "time_launch": 1512490576,
    "time_register": 1512490576,
    "time_update": 1512490576,
    "uid": -1,
    "user_name": "paul"
  }
}
получаем id своего монитора — 2
Теперь остаётся спрашивать сервер про обновления каждые N времени. https://github.com/CGRU/cgru/blob/maste ... evets.json

Код: Выделить всё

{"get":{"type":"monitors","ids":[2],"mode":"events"}}
Если на сервер чтото поменялось то при следующем запросе мы получаем что-то вроде такого

Код: Выделить всё

{"events":{ "jobs_change":[3] } }
После чего можем сделать обычный запрос информации о джобах

Код: Выделить всё

{"get":{"type":"jobs","ids":[3]}}
И получаем обновки.

Надеюсь я всё написал хотя бы близко к действительности. Но возникает два вопроса:

1. Почему при запросе об изменениях:
{"get":{"type":"monitors","ids":[2],"mode":"events"}}
я получаю всегда только такое:
{u'monitor': {u'id': 0}}
Определённо что-то не то сделал. Во вкладке MONITORS наротив моего зарегистрированного монитора можно видеть такие данные
EVTs: jobs_add, jobs_change, jobs_del

2. Помимо примера monitor_register.json есть еще несколько:
monitor_renders.json
monitor_tasks.json
monitor_message.json
monitor_jobs.json
monitor_announce.json

Могу предположить что они добавляют дополнительные эвенты, например сообщают об изменениях тасков или хостов.
Судя по сообщениям в консоли вотча при открытии тасков мы отправляем на сервер такой запрос https://github.com/CGRU/cgru/blob/maste ... tasks.json,
и тогда нам будут сообщать об изменениях в тасках. А когда окно закрывается status меняется на unsubscribe.
Аналогично подписываемся и на другие события. На соклько верно я описал?
Аватара пользователя
Timur
Site Admin
Сообщения: 178
Зарегистрирован: Вс июл 09, 2017 4:59 pm
Откуда: Королёв
Контактная информация:

Re: Запросы API

Сообщение Timur »

Класс !!!
Почти на 100% !!!
monitor_announce.json и monitor_announce.json - это вспомогательное, для отображения объявления на другом или всех мониторах, практически не нужно, так обычно есть другие средства связи. А остальные monitor_*.json экзамплы это да, подписка.
Ну вот, вы уже практически всё знаете чтобы сделать свой монитор на питоне.
Так как он не будет вперемешку с гуями (как в afanasy/browser/*.js), то c хорошими коментами, вы ещё можете сделать и отличный пример-руководство.
Тимур Хайрулин
CGRU 3.3.1 Ubuntu 22.04LTS, MS Windows 10 (clients only).
paulwinex
Сообщения: 83
Зарегистрирован: Пт июл 14, 2017 9:50 am

Re: Запросы API

Сообщение paulwinex »

Это замечательно, но я не могу разобраться с первым вопросом
1. Почему при запросе об изменениях:
{"get":{"type":"monitors","ids":[2],"mode":"events"}}
я получаю всегда только такое:
{u'monitor': {u'id': 0}}
Есть идеи?
paulwinex
Сообщения: 83
Зарегистрирован: Пт июл 14, 2017 9:50 am

Re: Запросы API

Сообщение paulwinex »

В общем ковырятие вариантов вот что даёт.
1. Создаем монитор

Код: Выделить всё

{'monitor': {'user_name': "paul", 'host_name': "i7", 'engine': "python"}}
2. Создаем подписку на стндартные эвенты про джобы

Код: Выделить всё

{'action': {"user_name":'paul',
            "host_name":"i7","type":"monitors","ids":[2],
            "operation":{"type":"watch","class":"jobs","status":"subscribe"}
             }
}
монитрим

Код: Выделить всё

{'get': {"type":"monitors","ids":[id],"mode":"events"}}
в основном получаем такое если изменений нет

Код: Выделить всё

{'events': None}
Но если есть то что-то такое

Код: Выделить всё

{'events': {'jobs_change': [2]}}
Теперь вопросы.

1. Если монитор не использовать (не делать запросы на сервер) то он автоматически пропадает (наверна удаляется) секунд через 30. Можно ли это время увеличить например до 3 мин?
Сразу ответ: В конфиге параметр: "af_monitor_zombietime":40

2. В данный момент изменения присылаются только по тем джобам которые принадлежат тому же юзеру что указан в мониторе или в команде создания подписки. В каком месте я указываю джобы какого юзера хочу следить?

3. В дефолтном мониторе юзер coord с хостом pc это типа админа который видит все джобы (хотя он следит за мониторами)? И вообще можно както одним монитором получать задачи всех юзеров?

PS
Т.е. не существует ни одного монитора на питоне.
Вам придётся делать (разрабатывать с "0") это первым.
А как же это?

Код: Выделить всё

import af, time
cmd = af.Cmd()
id = cmd.monitorRegister()
cmd.monitorSubscribe(id, 'jobs')
while True:
    try:
        print cmd.monitorEvents(id)
        time.sleep(1)
    except KeyboardInterrupt:
        break
Оказывается на питоне то всё уже готово, встраивай куда надо)))
Аватара пользователя
Timur
Site Admin
Сообщения: 178
Зарегистрирован: Вс июл 09, 2017 4:59 pm
Откуда: Королёв
Контактная информация:

Re: Запросы API

Сообщение Timur »

Чтобы подписаться на задачи всех пользователей, надо подписаться на юзера с ID=0.
Вы же можете это сделать в гуях и посмотреть?
Это можно также увидеть в гуях под админом наблюдая за мониторами.
Монитор в Python API я как-то прозевал, это делал не я.
По и идее для монитора свой класс нужен, это не одноразовый Cmd, это свой долгоживущий класс.
Я бы всё же сделал свой, и отдельном .py файле.
Тем более у вас уже есть пример на питоне.
Тимур Хайрулин
CGRU 3.3.1 Ubuntu 22.04LTS, MS Windows 10 (clients only).
paulwinex
Сообщения: 83
Зарегистрирован: Пт июл 14, 2017 9:50 am

Re: Запросы API

Сообщение paulwinex »

По и идее для монитора свой класс нужен, это не одноразовый Cmd, это свой долгоживущий класс.
Я бы всё же сделал свой, и отдельном .py файле.
Да, почти доделал. Пытаюсь понять что означает ответ от сервера. Помогите разобраться.
Вот параметры монитора:

Код: Выделить всё

{
  "name": "paul@i7",
  "id": 3,
  "priority": 99,
  "user_name": "paul",
  "time_register": 1512557369,
  "time_launch": 1512557369,
  "time_update": 1512558152,
  "address": {
    "family": 4,
    "ip": "127.0.0.1",
    "port": 0
  },
  "engine": "python",
  "uid": 3,
  "time_activity": 1512557447,
  "events": [
    "jobs_add",
    "jobs_change",
    "jobs_del"
  ],
  "jobs_ids": [
    2
  ]
}
То есть у меня три эвента jobs_add, jobs_change и jobs_del, а так же подписан на обновление тасков джоба 2.

Вот что я получаю в эвенте tasks_progress
(в этот момент считаются 2 таска)

Код: Выделить всё

[{'progress': [
    {'tdn': 1512558862, 'per': 40, 'st': 4611686018427387906L, 'hst': 'i7', 'state': ' RUN', 'pfr': 40, 'str': 1, 'tst': 1512558851},
    {'tdn': 1512558863, 'per': 50, 'st': 4611686018427387906L, 'hst': 'i7', 'state': ' RUN', 'pfr': 50, 'str': 1, 'tst': 1512558851},
    {'tdn': 1512558863,            'st': 2,                    'hst': 'i7', 'state': ' RUN',            'str': 1, 'tst': 1512558861},
    {'tdn': 1512558864, 'per': 50, 'st': 4611686018427387906L, 'hst': 'i7', 'state': ' RUN', 'pfr': 50, 'str': 1, 'tst': 1512558851},
    {'tdn': 1512558864,            'st': 2,                    'hst': 'i7', 'state': ' RUN',            'str': 1, 'tst': 1512558861}
    ],
    'tasks': [1, 1, 2, 1, 2], 
    'blocks': [0, 0, 0, 0, 0], 
    'job_id': 2}
]
В массиве progress мы видим оперативную информацию о таске, id которого можно взять в массиве tasks в той же последовательности.
Вопрос 1.
Мне тут не ясно только одно значение: st, и некоторое его состояние типа 4611686018427387906L. Что оно значит? Где почитать?
Вопрос 2.
Учитывая что есть повторения id тасков могу предположить что сюда записаны все события таска с момента последнего запроса. И на самом деле актуальным будет только полседний (то есть последнее значение одинаковых id тасков с одинаковым id блока). Верно?
Ответить