import inspect import types from openai import OpenAI from .env import Environment class ApiKeyMissingError(Exception): pass class Explainable: API_KEY = None PROMPT = """ Explain the following Python class code. Use these rules: - Ignore the Explainable class – it's just an internal utility to add the `.explain()` method. It is not relevant to the explanation as it just adds the `.explain()` method to the class. Don't even mention it in the explanation. Only mention other inherited classes if they are relevant. - Focus on the class that is being explained. - Focus only on what the class and its methods do, practically. - Do not explain basic Python concepts like `self`, indentation, or decorators. - Do not guess the purpose or intent of the class — just describe what the code does. - Do not make suggestions for improvement or style. - Keep the explanation clear, minimal, and to-the-point. - Your audience is a competent Python developer. - Use simple language and avoid jargon. - Be concise and avoid unnecessary detail. - Provide the explanation in a single paragraph or more if needed. """ @classmethod def use_env(cls, path: str = ".env"): env = Environment(env_file_name=path) Explainable.API_KEY = env.get("OPENAPI_KEY") @classmethod def explain(cls) -> str: if cls.API_KEY is None: raise ApiKeyMissingError("API key is missing. Please set it using `Explainable.use_env()` or by directly assigning `Explainable.API_KEY`.") try: code = inspect.getsource(cls) client = OpenAI(api_key=cls.API_KEY) response = client.chat.completions.create( model="gpt-4", messages=[ {"role": "system", "content": cls.PROMPT}, {"role": "user", "content": code} ] ) return response.choices[0].message.content.strip() except Exception as e: return f"" def __init_subclass__(cls, **kwargs): for name, obj in vars(cls).items(): if isinstance(obj, types.FunctionType): setattr(cls, name, Explainable.wrap_with_explain(obj)) super().__init_subclass__(**kwargs) @staticmethod def wrap_with_explain(func): def _with_explain(*args, **kwargs): return func(*args, **kwargs) _with_explain.__name__ = func.__name__ _with_explain.__doc__ = func.__doc__ def explain_func(): if Explainable.API_KEY is None: raise ApiKeyMissingError("API key is missing. Please set it using `Explainable.use_env()` or by directly assigning `Explainable.API_KEY`.") try: code = inspect.getsource(func) client = OpenAI(api_key=Explainable.API_KEY) response = client.chat.completions.create( model="gpt-4", messages=[ {"role": "system", "content": Explainable.PROMPT}, {"role": "user", "content": code} ] ) return response.choices[0].message.content.strip() except Exception as e: return f"" _with_explain.explain = explain_func return _with_explain