1

Python библиотека для Remote Api от Gurtam

Тема: Python библиотека для Remote Api от Gurtam

C недавнего времени на сервисе GitHub (хостинга проектов и их совместная разработка) доступна python библиотека  для работы на сервере с remote API.

Ссылка на страницу: https://github.com/wialon/python-wialon

Denis Strakh, Gurtam
2

Python библиотека для Remote Api от Gurtam

Re: Python библиотека для Remote Api от Gurtam

О, круто. Классная задумка. Вот бы еще на Яве че-нить сделали wink

3

Python библиотека для Remote Api от Gurtam

Re: Python библиотека для Remote Api от Gurtam

Java в работе

Denis Strakh, Gurtam
4

Python библиотека для Remote Api от Gurtam

Re: Python библиотека для Remote Api от Gurtam

stde пишет:

Java в работе

Вау! Я тапер прям уся горю в нетерпении... Испробовать хоцца.

5

Python библиотека для Remote Api от Gurtam

Re: Python библиотека для Remote Api от Gurtam

Здравствуйте.
Подскажите как использовать данный пакет:


Взял сорцы. Проверил на тестовом - работает.
Теперь решил использовать свои логин и пароль, изменил в классе

class Wialon(object):
    def __init__(self, scheme='http',  host="hst-api.wialon.com", port=80, sid=None, **extra_params):

значение параметра host на свой.  Пытаюсь подконнектиться - не идет. 

Предположения:
1) Не верно указываю свой хост
2) Не подключен sdk
3) Что-то еще?

С чего рекомендуете начать расследование?

P.S. Если заходит через браузер на мой хост, то через форму заходит спокойно.

6

Python библиотека для Remote Api от Gurtam

Re: Python библиотека для Remote Api от Gurtam

SapronovAlexander

Здравствуйте.

По предположениям:

Первое вполне может быть. (Отпишите в личку  для проверки вместе с логином и паролем).
По второму пункту - модуль sdk должен быть подключен иначе при попытки логина будет возвращен код ошибки 7 (Access denied).
По третьему - маловероятно - думаю проблемы в вышеуказанных пунктах.

7

Python библиотека для Remote Api от Gurtam

Re: Python библиотека для Remote Api от Gurtam

Возможно ли привести на python пример search_items с условиями поиска? Например, вывести все доступные машины.

ООО "Курс"
www.gpskurs.com
8

Python библиотека для Remote Api от Gurtam

(02/09/2013 08:45:34 отредактировано chal)

Re: Python библиотека для Remote Api от Gurtam

nbush

from wialon import Wialon, flags

def main():    
    wialon = Wialon()
    try:
        login = wialon.core_login(user='wialon_test', password='test')        
    except WialonError as e:
        print e
        return
    wialon.sid = login['eid']
    
    spec = {
        'itemsType': 'avl_unit',    
        'propName': 'sys_name',    
        'propValueMask': '*',    
        'sortType': 'sys_name'
    }
    interval = {"from": 0, "to": 0}
    try:
        units = wialon.core_search_items(spec=spec, force=1, flags=flags.ITEM_DATAFLAG_BASE, **interval)
    except WialonError as e:
        print e
        return

    print units

if __name__ == '__main__':
    main()
9

Python библиотека для Remote Api от Gurtam

Re: Python библиотека для Remote Api от Gurtam

Спасибо
Просто я пробовал вызов типа

units = wialon.core_search_items(spec=spec, force=1, from = 0, to=0, flags=flags.ITEM_DATAFLAG_BASE)

Понятно, при этом python ругался на ключевое слово from в параметрах smile

ООО "Курс"
www.gpskurs.com
10

Python библиотека для Remote Api от Gurtam

(12/01/2014 14:50:11 отредактировано solveMe)

Re: Python библиотека для Remote Api от Gurtam

Нашел небольшой баг. В функции __unicode__() класса WialonError при каждом вызове (а следовательно и функций __str__() , __repr__()) будет наращиваться значение self._text на строку error[self._code]. Т.е. будет такой вывод например:

WialonError(Error performing request Ho-ho (5))
WialonError(Error performing request Error performing request Ho-ho (5))
WialonError(Error performing request Error performing request Error performing request Ho-ho (5))

Я решил что пусть self._text остается таки каким его передали в конструктор и поправил это следующи образом:

    def __unicode__(self):
        if (self._code in wError.errors):
            explanation = " ".join([wError.errors[self._code], self._text])
        message = u'{explanation} ({code})'.format(explanation=explanation, code=self._code)
        return u'WialonError({message})'.format(message=message)

Вот собственно и все. Кстати наверняка у автора либы будут мысли получше чем мои.

P.S. Очень понравилась ваша идея с вызовом команд Виалону, как будто они методы экземпляра Wialon(). Я ввиду своей неопытности в ближайшие года бы до такого не додумался.

11

Python библиотека для Remote Api от Gurtam

Re: Python библиотека для Remote Api от Gurtam

solveMe пишет:

Нашел небольшой баг. В функции __unicode__() класса WialonError при каждом вызове (а следовательно и функций __str__() , __repr__()) будет наращиваться значение self._text на строку error[self._code]. Т.е. будет такой вывод например:

WialonError(Error performing request Ho-ho (5))
WialonError(Error performing request Error performing request Ho-ho (5))
WialonError(Error performing request Error performing request Error performing request Ho-ho (5))

Я решил что пусть self._text остается таки каким его передали в конструктор и поправил это следующи образом:

    def __unicode__(self):
        if (self._code in wError.errors):
            explanation = " ".join([wError.errors[self._code], self._text])
        message = u'{explanation} ({code})'.format(explanation=explanation, code=self._code)
        return u'WialonError({message})'.format(message=message)

Вот собственно и все. Кстати наверняка у автора либы будут мысли получше чем мои.

P.S. Очень понравилась ваша идея с вызовом команд Виалону, как будто они методы экземпляра Wialon(). Я ввиду своей неопытности в ближайшие года бы до такого не додумался.

Да, действительно есть такой баг. И ваше решение вполне подходит. Спасибо.

12

Python библиотека для Remote Api от Gurtam

Re: Python библиотека для Remote Api от Gurtam

Сегодня просматривал код данной библиотеки и заступорился на методе getattr(...). В частности никак не могу понять что делает данное выражение:

return get.__get__(self)

Ну т.е. я понимаю что оно возвращает в итоге функцию которую нужно вызвать вместо Wialon.action_name(...). Но на каких механизмах основывается работа данного кода понять не могу. Почитал про дескрипторы Python (метод __get__() вроде только для них применим), но осталось недопонимание откуда у метода

def get(self, *args, **kwargs)

взялся метод __get__()? Он ведь вроде по умолчанию не существует и его необходимо переопределять, да и вызывается он тоже неявно.
Был бы признателен если бы кто-нибудь объяснил где мои рассуждения свернули не туда. Интерес у меня чисто академический так сказать. Так получилось что подвернулась данная библиотека по работе, а я с Python'ом даже не то чтобы на "Вы", а скорее даже на "Ваше превосходительство" поэтому решил, что разбор использующихся тут приемов будет хорошим началом для изучения языка.

13

Python библиотека для Remote Api от Gurtam

Re: Python библиотека для Remote Api от Gurtam

Библиотеку писал не я, но ответить попробую. Академический интерес заразителен)

solveMe пишет:

откуда ... взялся метод __get__()? Он ведь вроде по умолчанию не существует и его необходимо переопределять ... да и вызывается он тоже неявно

Простая проверка показывает что метод очень даже существует у обычной функции.

>>> def test(var): print var
>>> test.__get__
<method-wrapper '__get__' of function object at 0x7f4f75798320>
>>>test.__get__('go')
<bound method ?.test of 'go'>

Документация гласит, что данный метод вызывается для получения атрибута owner класса, т.е. в нашем случае у Wialon. И вызвать функцию явно никто не запрещает.

Вообще мне очень нравится идея вызова не объявленных явно методов. Логика примерно следующая (на примере 'core_login'):
1) создается объект wialon класса Wialon
2) вызывается wialon.core_login(...)
3) функция 'core_login' явно не объявлена - вызывается wialon.__getattr__(self, 'core_login')
4) объявляется функция get(), которая по сути вызывает метод call('core/login')
5) вызывается get.__get__(...), которая вызывает get() owner'a (т.е. wialon)
6) результат ретурнится

Та же логика в библиотеке php-wialon, но выглядит прозрачнее)

14

Python библиотека для Remote Api от Gurtam

(11/02/2014 13:59:52 отредактировано solveMe)

Re: Python библиотека для Remote Api от Gurtam

Большое спасибо за ответ. Оказывается мой больной разум, все это время глядя в документации на слово owner, воспринимал его как parent. Остался непонятен только один момент: если в функции __getattr__(..) мы подсовываем вместо вызванной функции метод call() то зачем было запиливать функцию get и потом вызывать get.__get__()? Можно ли сразу напрямую сделать так:

def __getattr__(self, action_name):
     return self.call

Или я опять что-то упустил?

15

Python библиотека для Remote Api от Gurtam

(11/02/2014 19:18:57 отредактировано chal)

Re: Python библиотека для Remote Api от Gurtam

Спасибо за ваш интерес.

Метод __getattr__http://u.to/vi83Bg вызывается, если не найден подходящий метод (свойство) в объекте или в классах родителях. И, следовательно, он должен вернуть либо значение, если это свойство объекта или, так называемый, callable объект, что и просходит в нашем случаи. Этот callable объект и будет вызываться с параметрами. Пример ниже.

wialon_api = Wialon()
result = wialon_api.core_login(user='wialon_test', password='test')

Т.е. в цепочка вызова будет такая:
- __getattr__(self, 'core_login') - который и должен вернуть callable объект - назовем его callable_login
- вызовется callable_login в который, собственно, и передастся параметры user и password в словаре.

Вот для того, что бы __getattr__ и вернул callable объект и нужна нижеуказанная манипуляция.

def __getattr__(self, action_name):
        """
        Enable the calling of Wialon API methods through Python method calls
        of the same name.
        """
        def get(self, *args, **kwargs):
            return self.call(action_name, *args, **kwargs)

        return get.__get__(self)

Про __get__ можно почитать по ссылке http://u.to/lTA3Bg.

А по поводу вызова напрямую:

def __getattr__(self, action_name):
        return self.call

В таком случаи в метод call ни как не передается action_name. Можно было бы сделать это так:

from  functools import partial

def __getattr__(self, action_name):
        return partial(self.call, action_name)

Но мне, как автору, решение, которое и реализовано, показалось более прозначным и близким smile

Надеюсь вам стало понятнее.

16

Python библиотека для Remote Api от Gurtam

Re: Python библиотека для Remote Api от Gurtam

chal пишет:

nbush

from wialon import Wialon, flags

def main():    
    wialon = Wialon()
    try:
        login = wialon.core_login(user='wialon_test', password='test')        
    except WialonError as e:
        print e
        return
    wialon.sid = login['eid']
    
    spec = {
        'itemsType': 'avl_unit',    
        'propName': 'sys_name',    
        'propValueMask': '*',    
        'sortType': 'sys_name'
    }
    interval = {"from": 0, "to": 0}
    try:
        units = wialon.core_search_items(spec=spec, force=1, flags=flags.ITEM_DATAFLAG_BASE, **interval)
    except WialonError as e:
        print e
        return

    print units

if __name__ == '__main__':
    main()

Добрый день,
Данный пример проверил, работает.

По аналогии пытаюсь выполнить загрузку сообщений, пример взят с документации https://sdk.wialon.com/wiki/ru/sidebar/ … s/messages
Далее собираю в следующий скрипт:

# -*- coding: utf-8 -*-
from wialon import Wialon, WialonError, flags
def main():    
    wialon = Wialon()
    try:
        result = wialon.token_login(token='token')        
    except WialonError as e:
        print e
        return
    wialon.sid = result['eid']

    params = {"itemId":928675,"timeFrom":1478147204,"timeTo":1478518392,"flags":0x0000,"flagsMask":0xFF00,"loadCount":0xffffffff}

    try:
        units = wialon.messages_load_interval(params)
    except WialonError as e:
        print e
        return
    print units
if __name__ == '__main__':
    main()

Вопрос, что тут не правильно, подскажите пожалуйста..

17

Python библиотека для Remote Api от Gurtam

Re: Python библиотека для Remote Api от Gurtam

Здравствуйте, togachev!

units = wialon.messages_load_interval(params)

Вам необходимо распаковать params при передаче функции:

units = wialon.messages_load_interval(**params)
18

Python библиотека для Remote Api от Gurtam

Re: Python библиотека для Remote Api от Gurtam

asal пишет:

Здравствуйте, togachev!

units = wialon.messages_load_interval(params)

Вам необходимо распаковать params при передаче функции:

units = wialon.messages_load_interval(**params)

Сработало!
Спасибо!

19

Python библиотека для Remote Api от Gurtam

Re: Python библиотека для Remote Api от Gurtam

смотрю сейчас на строчку

wialon.sid = login['eid']

очередная магия ?

"eid":<long>,    /* login operations count of current user */

подпись сломали .. впрочем не удивительно
20

Python библиотека для Remote Api от Gurtam

Re: Python библиотека для Remote Api от Gurtam

tdt66 пишет:

смотрю сейчас на строчку

wialon.sid = login['eid']

очередная магия ?

"eid":<long>,    /* login operations count of current user */

В eid идентификатор сессии содержится и, видимо, в Pro он был просто числом.

В актуальной версии:

"eid":<text>,            /* session ID */

Вопрос, почему в ответе при логине он называется eid, а в запросы подаётся как sid — интересный.