Класс-клиент goo.gl и настройка API

    UPD: репозиторий теперь на Гитхабе.

    Здравствуйте, коллеги!

    Помню, в свое время меня очень обрадовала новость, что у гугловской сокращалки урлов появились официальные API. В то время я как раз разрабатывал приложение, которому часто требовалось сокращать ссылки новостных лент. Я как раз прикручивал bit.ly, но испытал соблазн попробовать новый сервис от Гугла. Воспользовавшись документацией, я за несколько часов набросал базовый функционал и встроил скрипт в проект.

    С течением времени в скрипт вносились изменения, и, наконец, я решил дополнить код комментариями, написать простую документацию и выложить всё на гуглокод.

    Основные возможности и особенности класса от конкурентов:
    • Малый размер (150 строк), всё в одном модуле, не требуется подключать тяжелый официальный питон-клиент;
    • Полное покрытие API, в отличии от аналогичного проекта;
    • Комментарии и документация в коде;
    • Поддержка авторизации через ClientLogin + функция для его получения;
    • Дополнительные параметры инициализации, если в ваших API выставлены ограничения по referer или IP;

    За три с лишним месяца я успел сократить около 12000 уникальных ссылок и в целом весьма доволен сервисом. Ниже я хочу привести примеры кода и рассказать о том, как настроить API для максимальной производительности.

    Для использования класса нужно сперва получить API-ключ. Вообще, пользоваться сокращалкой можно и без ключа, но тогда ваши лимиты крайне малы. Заходим на страницу консоли API, нажимаем «Add project» и в списке доступных сервисов включаем URL Shortener API (последний в списке).



    На закладке «Project home» в подпункте «API access» будет написан ваш ключ:



    Пока что пропустим описание аутенфикации и ограничения запросов, давайте посмотрим класс в действии:

    import googl
    
    client = googl.Googl("MyAPIAccessKey")
    
    result = client.shorten("http://code.google.com/p/python-googl-client/")
    print result
    >>> {u'kind': u'urlshortener#url', u'id': u'http://goo.gl/67TaW', u'longUrl': u'http://code.google.com/p/python-googl-client/'}
    
    print client.expand(result["id"])
    >>> {u'status': u'OK', u'kind': u'urlshortener#url', u'id': u'http://goo.gl/67TaW', u'longUrl': u'http://code.google.com/p/python-googl-client/'}
    

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

    Чтобы получить дополнительную статистику по кликам и временным периодам, передадим в метод expand() дополнительный параметр projection, его значение может быть одной из констант с префиксом PROJ_:
    info = client.expand('http://goo.gl/67TaW', projection=googl.PROJ_FULL)
    

    Это вернет нам примерно такую структуру:
    {
    	u'status': u'OK',
    	u'kind': u'urlshortener#url',
    	u'created': u'2011-05-19T05:47:13.058+00:00',
    	u'analytics': {
    		u'week': {
    			u'shortUrlClicks': u'0',
    			u'longUrlClicks': u'1'
    		},
    		u'allTime': {
    			u'shortUrlClicks': u'0',
    			u'longUrlClicks': u'1'
    		},
    		u'twoHours': {
    			u'shortUrlClicks': u'0',
    			u'longUrlClicks': u'1'
    		},
    		u'day': {
    			u'shortUrlClicks': u'0',
    			u'longUrlClicks': u'1'
    		},
    		u'month': {
    			u'shortUrlClicks': u'0',
    			u'longUrlClicks': u'1'
    		}
    	},
    	u'longUrl': u'http://code.google.com/p/python-googl-client/',
    	u'id': u'http://goo.gl/67TaW'
    }
    

    Смысловые значения каждого поля описаны в документации.

    Теперь рассмотрим авторизацию. Авторизация нужна для того, чтобы Гугл убедился, что запрос выполнил Пупкин, а не Сумкин. Во-первых, это дает доступ к статистике, а во-вторых, ощутимо поднимает лимиты. Авторизация может быть выполнена двумя способами: OAuth и ClientLogin. Пока что я реализовал второй способ, т.к. он проще (OAuth прикручу позже). Чтобы запросить токен, необходимо установить библиотеку gdata-python-client и вызвать функцию get_client_login(), передав ей логин и пароль от своей учетки. Задайте полученный токен в инициализации класса, после чего каждый запрос станет авторизированным:

    import googl
    
    client_login = googl.get_client_login("login", "pass")
    client = googl.Googl("MyAPIAccessKey", client_login=client_login)
    

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

    Если вы будете сокращать ссылки пакетно, то рано или поздно словите исключение «rate limits». Это потому, что по умолчанию в вашей консоли стоит лимит 1.0 requests/second/user:



    Увеличьте это значение до приемлемого, скажем, 1000 запросов.

    Наконец, рассмотрим фильтрацию запросов. Все API-запросы могут фильтроваться двумя способами: по IP и домену. На закладке «Traffic Controls» можно задать один из типов:



    Если вы выбрали пункт «Browser-embedded scripts», то в текстовом поле указываете маску адреса, с которго будут приходить запросы, например "*.example.com/*". При инициализации класса нужно указать параметр referer, удовлетворяющий этой маске:

    import googl
    
    client = googl.Googl("MyAPIAccessKey", referer="http://www.example.com")
    

    Ограничение по IP работает следующим образом. Вы указываете маску IP-адреса. В каждом запросе осуществляется поиск параметра userip (из адресной строки). Если он не найден, то ему присваивается реальный IP-адрес машины, с который был вызов. Полученный таким образом userip сравнивается с указанной маской. Параметр userip можно задать при инициализации класса:
    import googl
    
    client = googl.Googl("MyAPIAccessKey", userip="127.0.0.1")
    

    Ссылки:

    Similar posts

    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 3

      +2
      Спасибо. Полезно.
        +1
        Как раз думаю делать вебпроект на питоне, ваш пост как нельзя кстати — добавил в копилку TODO.
          +1
          А я только писал начал свой костыль… Автор, спасибо!

          Классно. :)

          Only users with full accounts can post comments. Log in, please.