0

I would like to be able to pass a call of either get, post, delete, etc, into my requests function. So instead of having all these different functions for each RESTFULness, I'd like to have a func like:

I have:

class BitbucketAPIHoss(object):

    API_URL_1 = 'https://api.bitbucket.org/1.0/'

    API_URL_2 = 'https://api.bitbucket.org/2.0/'

    HEADERS = {'Content-Type': 'application/json'}

    def __init__(self, username='codyc54321', password='trump_4_dictator_of_milky_way'):
        self.username = username
        self.password = password

    def get_bitbucket_project_names(self):
        repo_dicts = self.get_bitbucket_response_as_dict('user/repositories', "1")
        repo_names = extract_values(key='name', dictionaries=repo_dicts)
        return repo_names

    def create_repository(self, name=None):
        payload = {'scm': 'git',
                   'name': name,
                   'is_private': 'true',

        }
        json_payload = json.dumps(payload)
        url_ending = os.path.join('repositories', self.username, name)
        print(url_ending)
        response = self.post_to_bitbucket(url_ending=url_ending, payload=json_payload)
        print(response)

    def delete_repository(self, name=None):
        url_ending = os.path.join('repositories', self.username, name)
        print(url_ending)
        (url_ending=url_ending)


    def get_bitbucket_response_as_dict(self, url_ending, api_version="2"):
        if api_version == "2":
            api_url = self.API_URL_2
        elif api_version == "1":
            api_url = self.API_URL_1

        url = os.path.join(api_url, url_ending)
        r = requests.get(url, auth=(self.username, self.password), headers=self.HEADERS)
        content = r.text
        payload = demjson.decode(content)
        return payload

    def post_to_bitbucket(self, url_ending, payload=None, api_version="2"):
        if api_version == "2":
            api_url = self.API_URL_2
        elif api_version == "1":
            api_url = self.API_URL_1

        url = os.path.join(api_url, url_ending)
        if payload:
            r = requests.post(url, auth=(self.username, self.password), data=payload, headers=self.HEADERS)
        else:
            r = requests.post(url, auth=(self.username, self.password), headers=self.HEADERS)

try

def call_request(style):
    r = requests.style(url, auth=(username, pw), headers=headers)

call_request('get')

but no:

In [6]: def call(style):
    r = requests.style('https://api.bitbucket.org/1.0/', auth=('codyc54321', 'pw'), headers={'Content-Type': 'application/json'})
   ...:     

In [7]: call(get)
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-7-72b682ad376c> in <module>()
----> 1 call(get)

NameError: name 'get' is not defined

In [8]: call('get')
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-8-6a61a82da77f> in <module>()
----> 1 call('get')

<ipython-input-6-6ef72c4981c2> in call(style)
      1 def call(style):
----> 2     r = requests.style('https://api.bitbucket.org/1.0/', auth=('codyc54321', 'pw'), headers={'Content-Type': 'application/json'})
      3 

AttributeError: 'module' object has no attribute 'style'

Can I call any func I want w a string? I can't see how to use getattr here. Thank you

ANSWER:

    class BitbucketAPIHoss(object):

        API_URL_1 = 'https://api.bitbucket.org/1.0/'

        API_URL_2 = 'https://api.bitbucket.org/2.0/'

        HEADERS = {'Content-Type': 'application/json'}

        def __init__(self, username='codyc54321', password='why_so_broke_kanye?'):
            self.username = username
            self.password = password
            self.d = {'auth': (self.username, self.password), 'headers': self.HEADERS}

        def get_bitbucket_project_names(self):
            repo_dicts = self.call_api('get', 'user/repositories', api_version="1")
            repo_names = extract_values(key='name', dictionaries=repo_dicts)
            return repo_names

        def call_api(self, method, url_ending, api_version="2", **kwargs):
            if api_version == "2":
                api_url = self.API_URL_2
            elif api_version == "1":
                api_url = self.API_URL_1

            url = os.path.join(api_url, url_ending) # 'user/repositories'
            request_call_function = getattr(requests, method)
            kwargs.update(self.d)        
            r = request_call_function(url, **kwargs)
            payload = demjson.decode(r.content)
            return payload


In [1]: from my_scripting_library import *

In [2]: hoss = BitbucketAPIHoss()

In [3]: names = hoss.get
hoss.get_bitbucket_project_names     hoss.get_bitbucket_response_as_dict  

In [3]: names = hoss.get_bitbucket_project_names()

In [4]: names
Out[4]: 
[u'autohelper',
 u'bookwormbuddy',
 u'bytesized_python',
 u'fakething',
 u'foodpro',
 ...]
codyc4321
  • 9,014
  • 22
  • 92
  • 165
  • 4
    By the way ... It looks like you might have inadvertently given away your bitbucket password. I'd recommend you change it :-). – mgilson Feb 23 '16 at 04:15
  • 1
    And just to be completely clear -- I was suggesting that you change your password on bitbucket, not just on this post. It's still visible in the edit history and who knows what attackers saw it before you changed it anyway :-). – mgilson Feb 23 '16 at 04:21
  • ya, I got to it within a few seconds lol – codyc4321 Feb 23 '16 at 04:50

1 Answers1

2

I think you probably want getattr:

def call(method):
    f = getattr(requests, method)
    return f('https://api....', ...);
mgilson
  • 300,191
  • 65
  • 633
  • 696
  • I'm so bad w getattr – codyc4321 Feb 23 '16 at 04:16
  • with `f` there you made a function, but didnt actually call it till below? – codyc4321 Feb 23 '16 at 04:17
  • 1
    @codyc4321 -- Yep. You could do it all in one line: `getattr(requests, method)('https://...', ...)`, but I find it easier to grok if I split it into 2 lines with suitably named variables. If I knew more about the problem at hand, or was feeling more creative, I'd probably use something that isn't `f` :-P – mgilson Feb 23 '16 at 04:20
  • ima try a basic version. Now I gotta make it take args and kwargs, you should stay up and help and get a free bitbucket api robot ;) – codyc4321 Feb 23 '16 at 04:21
  • I see, requests is clearly an object which has all those methods, so the getattr works on requests, not my class. thanks – codyc4321 Feb 23 '16 at 04:36
  • Ok I give you good results, very clean and good for scripting – codyc4321 Feb 23 '16 at 04:50