Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to group methods in Python class?

Just started learning OOP using python so I apologise if this question comes as too simplistic and welcome any improvements to my code. I am trying to write a wrapper for an API using the requests library and SurveyMonkey's API. This is what I have so far:

class SurveyMonkey:

    def __init__(self, access_token, base_url = "https://api.surveymonkey.com"):
        self.access_token = access_token
        self.base_url = base_url
        self.headers = {
            "Authorization": f"Bearer {self.access_token}",
            "Content-Type": "application/json"
        }
        self.survey_id = str()
        self.params = dict()
    
    def get_json(self):
        return requests.get(self.url, headers=self.headers, params=self.params).json()

    def list_surveys(self):
        self.url = f"{self.base_url}/v3/surveys"
        return self.get_json()

    def get_survey(self, survey_id):
        self.survey_id = survey_id
        self.url = f"{self.base_url}/v3/surveys/{self.survey_id}"
        return self.get_json()
    
    def get_survey_details(self, survey_id):
        self.survey_id = survey_id
        self.url = f"{self.base_url}/v3/surveys/{self.survey_id}/details"
        return self.get_json()
    
    def get_survey_responses_page(self, survey_id, params=dict()):
        self.survey_id = survey_id
        self.params = params
        self.url = f"{self.base_url}/v3/surveys/{self.survey_id}/responses"
        return self.get_json()
    
    def get_survey_responses_bulk_page(self, survey_id, params=dict()):
        self.survey_id = survey_id
        self.params = params
        self.url = f"{self.base_url}/v3/surveys/{self.survey_id}/responses/bulk"
        return self.get_json()
sm = SurveyMonkey(access_token)

I have used libraries where I've noticed the methods were somehow grouped. There are a few survey API's in SurveyMonkey and was wondering if I can somehow group the last 4 methods so I could call them using something like

sm.survey.get.details(id)
sm.survey.get.response.page(id)
sm.survey.get.response.bulk(id)

I couldn't really figure out how to do this

UPDATE (Thanks Tom):

I've restructured the code as per Tom's specifications and it looks like this:

class SurveyMonkey:
    
    def __init__(self, access_token, base_url = "https://api.surveymonkey.com"):
        self.surveys = surveys(self)
        self.survey_responses = survey_responses(self)
        
        self.access_token = access_token
        self.base_url = base_url
        self.headers = {
            "Authorization": f"Bearer {self.access_token}",
            "Content-Type": "application/json"
        }
        self.survey_id = str()
        self.params = dict()
        
    def get_json(self):
        return requests.get(self.url, headers=self.headers, params=self.params).json()
        
class surveys:

    def __init__(self, parent: SurveyMonkey):
        self.parent = parent

    def list_surveys(self):
        self.parent.url = f"{self.parent.base_url}/v3/surveys"
        return self.parent.get_json()
    
    def get_survey(self, survey_id):
        self.survey_id = survey_id
        self.parent.url = f"{self.parent.base_url}/v3/surveys/{self.survey_id}"
        return self.parent.get_json()
    
    def get_survey_details(self, survey_id):
        self.survey_id = survey_id
        self.parent.url = f"{self.parent.base_url}/v3/surveys/{self.survey_id}/details"
        return self.parent.get_json()
    
class survey_responses:
    
    def __init__(self, parent:SurveyMonkey):
        self.parent = parent
        
    def list_responses(self, survey_id, params=dict()):
        self.survey_id = survey_id
        self.parent.params = params
        self.parent.url = f"{self.parent.base_url}/v3/surveys/{self.survey_id}/responses"
        return self.parent.get_json()
    
    def get_response(self, survey_id, response_id, params=dict()):
        self.survey_id = survey_id
        self.response_id = response_id
        self.parent.params = params
        self.parent.url = f"{self.parent.base_url}/v3/surveys/{self.survey_id}/responses/{response_id}"
        return self.parent.get_json()
    
    def get_response_details(self, survey_id, response_id, params=dict()):
        self.survey_id = survey_id
        self.response_id = response_id
        self.parent.params = params
        self.parent.url = f"{self.parent.base_url}/v3/surveys/{self.survey_id}/responses/{response_id}/details"
        return self.parent.get_json()
    
    def get_response_bulk(self, survey_id, params=dict()):
        self.survey_id = survey_id
        self.parent.params = params
        self.parent.url = f"{self.parent.base_url}/v3/surveys/{self.survey_id}/responses/bulk"
        return self.parent.get_json()
like image 200
Andrei Budaes Avatar asked Jun 09 '26 15:06

Andrei Budaes


1 Answers

You can do something like this:

class SurveyMonkey:

    def __init__(self):
        self.survey = Survey(self)


class Survey:

    def __init__(self, parent: SurveyMonkey):
        self.parent = parent
        self.get = Get(self)


class Get:

    def __init__(self, parent: Survey):
        self.parent = parent
        self.response = Response(self)

    def details(self, id):
        print(id)


class Response:

    def __init__(self, parent: Get):
        self.parent = parent

    def page(self, id):
        print(id)

    def bulk(self, id):
        print(id)


sm = SurveyMonkey()
sm.survey.get.response.page(1)

Then you have to be clever about your building your request function calls, traversing the class hierarchy and building the info you need to make the request.

like image 130
Tom McLean Avatar answered Jun 12 '26 06:06

Tom McLean



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!