2014-09-16 3 views
0

Je ne suis pas sûr si j'ai utilisé la bonne terminologie dans la question.Quelle est la meilleure façon de forcer un mot clé en utilisant ** kwargs?

Actuellement, j'essaie de créer un wrapper/interface autour de l'API Blogger de Google (service Blog). [Je sais que cela a déjà été fait, mais j'utiliser cela comme un projet pour apprendre POO/python.]

J'ai fait une méthode qui obtient un ensemble de 25 messages d'un blog:

def get_posts(self, **kwargs): 
    """ Makes an API request. Returns list of posts. """ 

    api_url = '/blogs/{id}/posts'.format(id=self.id) 
    return self._send_request(api_url, kwargs) 

def _send_request(self, url, parameters={}): 
    """ Sends an HTTP GET request to the Blogger API. 
     Returns JSON decoded response as a dict. """ 

    url = '{base}{url}?'.format(base=self.base, url=url) 

# Requests formats the parameters into the URL for me 
    try: 
     r = requests.get(url, params=parameters) 
    except: 
     print "** Could not reach url:\n", url 
     return 
    api_response = r.text 
    return self._jload(api_response) 

le problème est, je dois spécifier la clé API chaque fois que j'appelle la fonction get_posts:

someblog = BloggerClient(url='http://someblog.blogger.com', key='0123') 
someblog.get_posts(key=self.key) 

chaque appel de l'API exige que la clé soit envoyée en tant que paramètre sur l'URL. Alors, quelle est la meilleure façon de le faire?

Je pense une façon possible (? Mais probablement pas la meilleure façon), est d'ajouter la clé du kwargs dictionnaire dans le _send_request():

def _send_request(self, url, parameters={}): 
    """ Sends an HTTP get request to Blogger API. 
     Returns JSON decoded response. """ 
# Format the full API URL: 
    url = '{base}{url}?'.format(base=self.base, url=url) 

# The api key will be always be added: 
    parameters['key']= self.key 
    try: 
     r = requests.get(url, params=parameters) 
    except: 
     print "** Could not reach url:\n", url 
     return 
    api_response = r.text 
    return self._jload(api_response) 

Je ne peux pas vraiment obtenir ma tête quel est le meilleur moyen (ou le plus pythonique) de le faire.

Répondre

0

Le problème est, je dois spécifier la clé API chaque fois que j'appelle la fonction get_posts:

S'il est vraiment juste cette méthode, l'idée évidente est d'écrire un wrapper:

def get_posts(blog, *args, **kwargs): 
    returns blog.get_posts(*args, key=key, **kwargs) 

Ou, mieux, envelopper la classe de le faire pour vous:

class KeyRememberingBloggerClient(BloggerClient): 
    def __init__(self, *args, **kwargs): 
     self.key = kwargs.pop('key') 
     super(KeyRememberingBloggerClient, self).__init__(*args, **kwargs) 
    def get_posts(self, *args, **kwargs): 
     return super(KeyRememberingBloggerClient, self).get_posts(
      *args, key=self.key, **kwargs) 

Alors maintenant:

someblog = KeyRememberingBloggerClient(url='http://someblog.blogger.com', key='0123') 
someblog.get_posts() 

Oui, vous pouvez remplacer ou monkey-patch la méthode _send_request qui utilisent toutes les autres méthodes, mais s'il n'y a que 1 ou 2 méthodes qui doivent être fixes, pourquoi plonger dans les entrailles sans-papiers de la classe, et fourchette le corps d'une de ces méthodes juste pour que vous puissiez le changer d'une manière que vous n'étiez pas attendu à, au lieu de le faire proprement?

Bien sûr, si vous disposez de 90 méthodes réparties sur 4 classes différentes, vous pouvez envisager de créer ces enveloppes par programme (et/ou de masquer les classes) ... ou de simplement patcher la méthode privée, comme vous le faites. Cela semble raisonnable.

1

Vous pouvez le stocker dans une constante nommée.

Si ce code n'a pas besoin d'être sûr, il suffit

API_KEY = '1ih3f2ihf2f' 

S'il va être hébergé sur un serveur quelque part ou doit être plus sûr, vous pouvez stocker la valeur dans une variable d'environnement

dans votre terminal:

export API_KEY='1ih3f2ihf2f' 

alors dans votre script python:

import os 
API_KEY = os.environ.get('API_KEY') 
Questions connexes