pypath icon indicating copy to clipboard operation
pypath copied to clipboard

Base Class for Authorization required APIs

Open MelihDarcanxyz opened this issue 1 year ago • 2 comments

Summary

Here I have a suggestion to make. After thinking a while about Disgenet API, I've come to a conclusion. Using classes for authorization required APIs is the best practive since it is the perfect balance between data security and ease of use.

Details

If we store the api key in the storage, it's not a good practice for data security. And if we don't, we have to prompt to user for e-mail and password every time we want to make a query. Of course they can be stored in a variable but classes are more elegant way of doing it. Prompting one time for each session is enough in this approach.

How

This base class is an Abstract Class and has a decorator (wrapper if you prefer) to use queries without the hassle of checking authorization status every time in every query. It also checks if the necessary and unique attributes of each child class is implemented.

Code

from abc import ABC, abstractmethod

class BaseAuthorizedApi(ABC):

    _name = NotImplemented
    _api_url = NotImplemented
    _authorized = False
    _api_key = None

    @abstractmethod
    def authorize(self) -> bool:
        pass

    def __if_authorized(f):
        def wrapper(self, *args, **kwargs):
            if self.authorize():
                return f(self, *args, **kwargs)
            else:
                print('Failure in authorization, check your credentials.')
        return wrapper

    def __init_subclass__(cls, **kwargs):
        for attr in dir(cls):
            try:
                if (getattr(cls, attr) == NotImplemented):
                    raise NotImplementedError(f'\'{attr}\' attribute is not defined in subclass.')
            except AttributeError:
                pass

MelihDarcanxyz avatar Aug 10 '22 21:08 MelihDarcanxyz

Hi Melih,

Thanks for coming up with this idea. If I understand correctly, we could do something like this in the new downloader module?

deeenes avatar Aug 11 '22 20:08 deeenes

If I got it right, yes, of course. That way there will be no unnecessary login prompts and this base class will prove useful for child classes. I made a correction to the wrapper by the way. You might want to look at it again.

My initial goal was to create a base class for the inputs module. This way, if a contributor wants to write an api for a database, one will know how to do it with consistence with the code base and ease. They just have to use this as a parent class and the parent class will guide them.

MelihDarcanxyz avatar Aug 15 '22 09:08 MelihDarcanxyz