LINUX.ORG.RU

Level3 cdn API

 , ,


0

1

Всем привет, нужна ваша помощь. Надо вытягивать информацию с cdn провайдера level3, с помощью API. Ключ API и секретный ключ есть. На офф сайте есть вот такой скрипт на python (перепробовал много разных вариантов с этим скриптом, но так и не понял как мне вытянуть инфу):


from datetime import datetime
import hmac
import hashlib
import base64
import urllib2, urllib
from xml.dom import minidom

class ForbiddenException(Exception):
    pass

def _convert(val):
    if isinstance(val, basestring):
        if val.isdigit():
            return int(val)
        try:
            return float(val)
        except:
            pass
    return val

class NodeTraverser(object):
    def __init__(self, node):
        self.node = node

    def keys(self):
        return self.node._attrs.keys()
    def children_keys(self):
        result = []
        for child in self.node.childNodes:
            result.append(child.tagName)
        return result

    @property
    def children(self):
        return [NodeTraverser(n) for n in self.node.childNodes]

    def getattribute(self, name):
        return self.node.getAttribute(name)
        
    def getnode(self, name):
        for child in self.node.childNodes:
            if child.tagName == name:
                return NodeTraverser(child)

    def __getattr__(self, name):
        if type(name) == int or name.isdigit():
            return self.children[int(name)]
        if self.node.hasAttribute(name):
            return self.getattribute(name)
        return self.getnode(name)
    __getitem__ = __getattr__
    @property
    def val(self):
        if self.node.nodeType == self.node.TEXT_NODE:
            return _convert(self.node.data)
        for node in self.node.childNodes:
            if node.nodeType == node.TEXT_NODE:
                return _convert(node.wholeText)
        return None
        
    def html(self):
        return self.node.toxml()

class XMLWrapper(object):
    def __init__(self, xml):
        self.xml = xml
        self.dom = minidom.parseString(xml)
        setattr(self, self.dom.documentElement.tagName, NodeTraverser(self.dom.documentElement))

class Level3Service(object):
    """
    Parameters :
        key_id(required)
        secret(required)
        service_url : optional that defaults to https://mediaportal.level3.com:443
        content_type : optional that defaults to text/xml
        resource : optional that defaults to /api/v1.0
        method : optional that defaults to GET
        wrap : optional that defaults to True. Will wrap the results in a friendly 
            class that allows you to easily retrieve the values from the xml(see example).
    
    Example Usages:
    
    >>> from level3 import Level3Service
    >>> service = Level3Service('<key id>', '<secret>')
    >>> result = service('rtm/<access group>', {'serviceType' : 'caching', 'accessGroupChildren' : 'false', 'geo' : 'none' })
    >>> result.accessGroup.missPerSecond.val
    50.67
    >>> result.accessGroup.metros[0].name
    Atlanta, GA
    >>> result.accessGroup.metros[0].region
    North America
    >>> result.accessGroup.metros[0].requestsPerSecond.val
    600.45
    """
    
    def __init__(self, key_id, secret, 
      service_url="",
      content_type='text/xml', resource="/api/v1.0", method="GET",
      wrap=True):
        self.key_id = key_id
        self.secret = secret
        self.service_url = service_url
        self.content_type = content_type
        self.resource = resource
        self.method = method
        
        self.current_date = datetime.utcnow()
        self.wrap = wrap
        
    def gen_new_date(self):
        self.current_date = datetime.utcnow()

    @property
    def formatted_date(self):
        return self.current_date.strftime("%a, %d %b %Y %H:%M:%S GMT")
        
    def generate_auth_string(self, method):
        authstring = "%s\n%s/%s/%s\n%s\n%s\n" % (
            self.formatted_date,
            self.service_url.rstrip('/'),
            self.resource.strip('/'),
            method.strip('/'),
            self.content_type,
            self.method
        )
        
        hash = hmac.new(self.secret, authstring, hashlib.sha1).digest()
        return "MPA %s:%s" % (self.key_id, base64.b64encode(hash))
        
    def __call__(self, method, options={}):
        self.gen_new_date()
        url = "https://ws.level3.com" +  self.service_url.rstrip('/') + '/' + self.resource.strip('/')
        url = url + '/' + method.strip('/')
        
        headers = {
            'Date' : self.formatted_date,
            'Authorization' : self.generate_auth_string(method),
            'Content-Type' : self.content_type
        }
        
        req_opts = {'headers' : headers}
        
        if options:
            encoded = urllib.urlencode(options)
            if self.method.upper() == 'GET':
                url += '?' + encoded
            else:
                req_opts['data'] = encoded
        
        req = urllib2.Request(url, **req_opts)
        try:
            result = urllib2.urlopen(req)
        except urllib2.HTTPError, ex:
            if ex.getcode() == 403:
                raise ForbiddenException("something went wrong authorizing this request. %s" % str(ex.readlines()))
            else:
                raise Exception("There was an erorr %s" % str(ex.readlines()))
        data = result.read()
        if self.wrap:
            data = XMLWrapper(data)
        return data



Когда в python ввожу:

from level3 import Level3Service
No module named level3

Когда ставлю модуль:

pip install level3

Could not find any downloads that satisfy the requirement level3 No distributions at all found for level3 Storing complete log in /root/.pip/pip.log

maison999 ()
Ответ на: комментарий от maison999

До примера и идет код level3, чудо.

anonymous ()
Ответ на: комментарий от anonymous

Тфу это все вместе и есть level3.py

anonymous ()
Ответ на: комментарий от anonymous

Не работает, делаю импорт этого файла (level3.py):

from level3 import Level3Service service = Level3Service('***', '***') result = service('rtm/114746', {'serviceType' : 'caching', 'accessGroupChildren' : 'false', 'geo' : 'none' })

File «level3.py», line 158, in __call__ raise Exception(«There was an erorr %s» % str(ex.readlines())) Exception: There was an erorr ['{ «error»: { «errorCode»: 21708,«message»: «Unknown service type.»,«httpStatus»: 400,«apiCorrelationId»: «API-e837bd1b-22fa-4488-9c43-e2bfb8eea324»} }']

maison999 ()
Ответ на: комментарий от maison999

В том же каталоге, где лежит файл level3.py создай пустой файл __init__.py и попробуй еще раз.

KernelPanic ()
Ответ на: комментарий от maison999

Делай по пунктам:

1) Создай новую директорию (например, «test_level»).

2) Создай в этой директории пустой файл с именет __init__.py

3) Скопируй аккуратненько приведенный тобой листинг в файл level3.py и помести его в директорию «test_level»

4) В томже каталоге создай файл, например «main.py»

5) Открой main.py на редактирование и запиши туда (key_id и secret ты знаешь?):

from level3 import Level3Service

service = Level3Service('<key id>', '<secret>')

result = service('rtm/<access group>', {'serviceType' : 'caching', 'accessGroupChildren' : 'false', 'geo' : 'none' })

result.accessGroup.missPerSecond.val
result.accessGroup.metros[0].name
result.accessGroup.metros[0].region
result.accessGroup.metros[0].requestsPerSecond.val
6) Сохрани измения. 7) Находясь в директории «test_level» выполни:
python main.py
PROFIT ) !!!

KernelPanic ()
Ответ на: комментарий от KernelPanic

Извини, но все сделал как ты написал...

File "main.py", line 5, in <module>
    result = service('rtm/******', {'serviceType' : 'caching', 'accessGroupChildren' : 'false', 'geo' : 'none' })
  File "/root/test_level/level3.py", line 158, in __call__
    raise Exception("There was an erorr %s" % str(ex.readlines()))
Exception: There was an erorr ['{ "error": { "errorCode": 21708,"message": "Unknown service type.","httpStatus": 400,"apiCorrelationId": "API-37efb0cf-90c5-4986-8c45-299e174f235e"} }']

Да, ключ id и secret я знаю, пробовал через их дебаггер то все подключается, а вот через python никак

maison999 ()
Ответ на: комментарий от maison999

У тебя все импортится ОК. Теперь проблема с самим скриптом. Дело, видимо, в том, что неполучается что-либо «взять» по url.

try:
   result = urllib2.urlopen(req)
except urllib2.HTTPError, ex:
   if ex.getcode() == 403:
       raise ForbiddenException("something went wrong authorizing this request. %s" % str(ex.readlines()))
   else:
       raise Exception("There was an erorr %s" % str(ex.readlines()))

Т.е. отарбатывается исключение, при попытке получить данные по url (req). Больше сказать не могу, так как надо вникать в работу скрипта.

KernelPanic ()
Ответ на: комментарий от maison999

Ошибка 400 - это неверно составленный http-запрос. Проверь правильность ввода id, secret и access group.

KernelPanic ()
Ответ на: комментарий от KernelPanic

Проверял, и много раз. Пробовал через их дебаггер и все работало с этими данными.

maison999 ()
Ответ на: комментарий от maison999

Пробовал через их дебаггер и все работало с этими данными.

Что за «их дебаггер»? Можно ссылку на него?

KernelPanic ()
Ответ на: комментарий от KernelPanic

MPAPIDebugger. Ссылки нету, так как он находится в help на оф сайте, а что бы увидеть нужно залогинится.

maison999 ()
Ответ на: комментарий от maison999

Хммм... А как ты работаешь с их дебаггером, что ты запускаешь в нем?

KernelPanic ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.