2
\$\begingroup\$

I currently have a module with Class / Methods I want to use in other scripts. Recently chess.com released a read-only REST API for beta-testing. The methods in my class build a URL for the API endpoints I am interested in and get the JSON data for me to work with in other scripts.

It is worth noting that I am fairly unused to using classes in the way I am in my code below - or at all really. Here is my working code:

"""TODO: docstring"""
from requests import get


class GetGamesJson:
    """TODO: docstring"""

    def build_url_for_player(self, username):
        """Build a custom URL for the `Palyer Profile` endpoint.

        Args:
            username (`str`): Player's username as string input.

        Returns:
            string: A URL for a player that can be used as a base for
            accessing other enpoints.

        Examples:
            >>> print(build_url_for_player('foo'))
            'https://api.chess.com/pub/player/foo'

        Raises:
            ValueError: If `username` is not found.

        """
        self.username = username
        player = (
            "https://api.chess.com/pub/player/{username}".format(
                username=username
            )
        )
        try:
            if get(player).json()['code'] == 0:
                raise ValueError("User '{username}' not found.".format(
                    username=username
                ))
        except KeyError:
            return player

    def build_url_for_monthly_archives(self, year, month):
        """Build URL for the `Monthly Archives` endpoint.

        This method depends on the base URL returned by the
        build_url_for_player() method.

        Args:
            year (int): Year as integer input.
            months (int): Month as integer input.

        Returns:
            string: URL to Monthly Archives.

        Examples:
            >>> print(build_url_for_monthly_archives(2009, 5))
            'https://api.chess.com/pub/player/foo/games/2009/05'

        """
        self.year = year
        self.month = month
        username = self.username
        url_to_monthly_archive = (
            self.build_url_for_player(username) +
            "/games/{year}/{month:02d}".format(
                username=username, year=year, month=month
            )
        )
        return url_to_monthly_archive

    def get_monthly_archive_json_doc(self):
        """Returns a JSON document from Monthly Archives endpoint."""
        link_to_json_doc = self.build_url_for_monthly_archives(
            self.year, self.month
        )
        get_json_doc = get(link_to_json_doc)
        return get_json_doc.json()

I would like to know what I can do to simplify and improve in the code I have.

\$\endgroup\$
2
\$\begingroup\$

I think you are over-complicating the problem, I would apply the following modifications:

  • rename the class to, say, ChessAPI
  • pass username into the class constructor
  • check for username to exist and define the profile_url instance attribute inside the class constructor
  • instantiate a single Session object and re-use inside the class methods

Modified code:

"""TODO: docstring"""
import requests


class ChessAPI:
    """TODO: docstring"""
    def __init__(self, username):
        self.username = username

        self.session = requests.Session()

        self.profile_url = "https://api.chess.com/pub/player/{username}".format(username=self.username)
        try:
            if self.session.get(self.profile_url).json()['code'] == 0:
                raise ValueError("User '{username}' not found.".format(username=self.username))
        except KeyError:
            pass

    def get_monthly_archives(self, year, month):
        """Returns a JSON document from Monthly Archives endpoint."""
        archive_url = self.profile_url + "/games/{year}/{month:02d}".format(username=self.username, year=year, month=month)
        get_json_doc = self.session.get(archive_url)
        return get_json_doc.json()

Sample usage (works for me):

api = ChessAPI('alex')
archives = api.get_monthly_archives(2017, 1)
print(archives)
\$\endgroup\$
1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.