Handling hardcoded URL's in a python package

Viewed 200

I am working on a python package which speaks with an API (using HTTP protocol). In my package I have a python configuration file that contains the API URL (hardcoded) and other settings. The API URL is saved in a global variable so I could import it and use it in my package modules. For example:

API_URL = "https://api-url.com"

The configuration file is part of the package, that means once that a user installs the package he also gets the configuration file including the hardcoded URL. The problem is that in some point in the future the API's URL could change, and all the factuality's of the package will break, and the users will have to update (i.g. pip install etc.) the package. What is the right way to handle hardcoded URLs in a package?

2 Answers

The common pattern here is to not hardcode the URL base, but instead provide a API class that will get instantiate with the corresponding URL. This class can also get additional config/a config file:

class MyAPI:
    def __init__(self, config_file: str = DEFAULT_CONFIG, **overrides):
        self.config = build_config(config_file, overrides)
        self.url = self.config.url

    @property
    def value(self):
        return requests.get(urljoin(self.url, "./value"))

The user would then use it like this:

api = MyAPI()

print(api.value)

or

api = MyAPI(url="NEW_URL")

print(api.value)

This is as example similar to what praw and wikipedia use.

This is an especially good idea if there are different URL that can be used with the same/a very similar Interface. (Often at least the live product + a test sandbox)

You can design your API so that URIs don't change. This might be achieved using versioning, e.g. serving your API at https://api-url.com/v1 instead of https://api-url.com. In this case users won't have to update or change anything because any changes to the API won't affect them since the changes will exist only in the newer version of you API served at https://api-url.com/v2.

Another option is to force library clients to pass the URL they want to use. This will solve the issue with hardcoding but won't solve the root cause. API usually change because something has changed in the understanding of the domain, which in turn means there are likely more changes than URLs alone (which will break your library anyway).

In case you think you simply might want to change domain name and don't anticipate any other changes that might affect clients you can use redirect from old URL to the new one.

Related