Search code examples
pythonurllibyandex

Yandex.Direct - API in Python


I am relatively new to Python, however I am trying to get my head around some mid-high level code which perhaps someone could help explain.

Basically, I am building an API connection to Yandex.Direct (the equivalent of Google Adwords in Russia). Here you can find an API code example: http://api.yandex.com/direct/doc/examples/python-json.xml

The actual code to establish a connection to the server follows (in Python 2.7):

import json, urllib2, httplib

#name and path to files with the secret key and certificate 
KEYFILE = '/path/to/private.key'
CERTFILE = '/path/to/cert.crt' 

class YandexCertConnection(httplib.HTTPSConnection):
    def __init__(self, host, port=None, key_file=KEYFILE, cert_file=CERTFILE, timeout=30):
        httplib.HTTPSConnection.__init__(self, host, port, key_file, cert_file)

class YandexCertHandler(urllib2.HTTPSHandler):
    def https_open(self, req):
        return self.do_open(YandexCertConnection, req) 
    https_request = urllib2.AbstractHTTPHandler.do_request_

urlopener = urllib2.build_opener(*[YandexCertHandler()])

#address for sending JSON requests
url = 'https://api.direct.yandex.ru/json-api/v4/'

#input data structure (dictionary)
data = {
   'method': 'GetClientInfo',
   'param': ['agrom'],
   'locale': 'en'
}

#convert the dictionary to JSON format and change encoding to UTF-8
jdata = json.dumps(data, ensure_ascii=False).encode('utf8')

#implement the request
response = urlopener.open(url, jdata)

#output results
print response.read().decode('utf8')

I don't fully comprehend the following part of this code:

class YandexCertConnection(httplib.HTTPSConnection):
    def __init__(self, host, port=None, key_file=KEYFILE, cert_file=CERTFILE, timeout=30):
        httplib.HTTPSConnection.__init__(self, host, port, key_file, cert_file)

class YandexCertHandler(urllib2.HTTPSHandler):
    def https_open(self, req):
        return self.do_open(YandexCertConnection, req) 
    https_request = urllib2.AbstractHTTPHandler.do_request_

urlopener = urllib2.build_opener(*[YandexCertHandler()])

Would appreciate it if someone could answer the following questions: 1. How does the code above work step by step? For example how do the different objects interact with each other? A detailed explanation would be great! :) 2. What does the * indicate here: urllib2.build_opener(*[YandexCertHandler()]) 3. How would one write the code above in Python 3.3 without using classes?

Thank you very much!

Aivoric


Solution

  • 2. func(*args) means func(arg1, arg2, arg3, ...), and if args is [x] then it's just func(x).

    In the example it should've been build_opener(YandexCertHandler()), I see no reason to complicate the code with argument list unpacking.

    3. In Python 3.3 without using classes I would use requests module:

    import json
    import requests
    
    # name and path to files with the secret key and certificate
    KEYFILE = '/path/to/private.key'
    CERTFILE = '/path/to/cert.crt' 
    
    # address for sending JSON requests
    url = 'https://api.direct.yandex.ru/json-api/v4/'
    
    # input data structure (dictionary)
    data = {
       'method': 'GetClientInfo',
       'param': ['agrom'],
       'locale': 'en'
    }
    
    # convert the dictionary to JSON format and change encoding to UTF-8
    jdata = json.dumps(data, ensure_ascii=False).encode('utf-8')
    
    response = requests.post(url, data=jdata, cert=(CERTFILE, KEYFILE))
    
    print(response.content)
    

    If it works (didn't test it), it also works in Python 2.