Source code for apikeyper.utils.decorators

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
decorators.py
-------------
Author: tayja
Date: 8/3/2023

This module provides decorators for ensuring API keys are available for specific services.
It offers both function-level and class-level decorators:

1. `apikey_required(service_names)`:
    A decorator for functions. When a function decorated with this is called, it checks
    if the required API keys are available. If a key is not found in the database,
    it prompts the user for input and saves the provided key.

    Args:
        service_names (Union[str, List[str]]):
            A list of service names for which API keys are needed.
            If a single string is provided, it's converted to a list.

2. `apikey_required_class(service_names)`:
    A decorator for classes. When an instance of a class decorated with this is created,
    it checks if the required API keys are available for the given services.
    If a key is not found in the database, it prompts the user for input and saves the provided key.
    It then sets the API key as a class attribute.

    Args:
        service_names (Union[str, List[str]]):
            A list of service names for which API keys are needed.
            If a single string is provided, it's converted to a list.

Usage example::

    @apikey_required(["service1", "service2"])
    def my_function():
        pass

    @apikey_required_class(["service1", "service2"])
    class MyClass:
        pass

Note:
    This module uses the APIKeyPER database manager for retrieving and storing API keys.Ensure that the APIKeyPER
    manager is initialized and connected to the correct database before use.

"""


[docs]def apikey_required(service_names): """ A decorator to ensure API keys are available for given services. If a key is not available in the database, it prompts the user for input. """ if not isinstance(service_names, list): service_names = [service_names] def decorator(func): def wrapper(*args, **kwargs): api_manager = APIKeyPER("default_apikeys.db") api_keys = {} for service_name in service_names: api_key = api_manager.get_key(service_name) if not api_key: print( f"No API key found for {service_name}. Please provide the API key:" ) user_api_key = input() # Get user input for the API key api_manager.add_key(service_name, user_api_key) api_keys[service_name] = user_api_key else: api_keys[service_name] = api_key[0] kwargs["api_keys"] = api_keys return func(*args, **kwargs) return wrapper return decorator
[docs]def apikey_required_class(service_names): """ A class decorator to ensure API keys are available for given services. If a key is not available in the database, it prompts the user for input. """ if not isinstance(service_names, list): service_names = [service_names] def decorator(cls): original_init = cls.__init__ def new_init(self, *args, **kwargs): api_manager = APIKeyPER("default_apikeys.db") for service_name in service_names: api_key = api_manager.get_key(service_name) if not api_key: print( f"No API key found for {service_name}. Please provide the API key:" ) user_api_key = input() # Get user input for the API key api_manager.add_key(service_name, user_api_key) setattr(cls, service_name.upper() + "_API_KEY", user_api_key) else: setattr(cls, service_name.upper() + "_API_KEY", api_key[0]) original_init(self, *args, **kwargs) cls.__init__ = new_init return cls return decorator