I am writing a front-end tool, which main function's signature looks like:
class MyApp:
def my_function(option_name, object_list, **kwargs) -> Graph:
Users use my function to access the server. my_function posts a json (that I build from the objects and extra data in the kwargs) to the route indicated by 'option_name', and returns an object I build from the response.
Dynamic Info: option_name is one of 10 rest-routes today, but from time to time, the server team adds options. The data in the kwargs may be relevant for some option_names but not for others.
On my invocation, I access the server and get a json that describes the current available options:
[
{
"option_name": str,
"description": str,
"extra-data": [
{
"data-id": str,
"description": str
},
...
]
},
...
]
While this data enables me to do all needed verifications before accessing the server, it still does not help me build a clearer interface for my users.
My issue: My interface to the user is "MyApp.my_function" with its general help string. But my users are very inexperienced programmers, so the distinct signature and a specific help string are very important. I'd like to offer them specific entries for my dynamic list of functions:
class MyApp:
def __my_function(option_name, object_list, **kwargs) -> Graph:
def option_name_1(object_list) -> Graph:
""" help 1 """
return self.__my_function("option_name_1", object_list)
def option_name_2(object_list, extra1=None) -> Graph:
""" help 2 """
return self.__my_function("option_name_2", object_list, extra1=None)
def option_name_3(object_list, extra2=None, extra3=None) -> Graph:
""" help 3 """
return self.__my_function("option_name_3", object_list, extra2=None, extra3=None)
Note that each function has a clear signature and help string.
I managed to add specific functions with a wrapper, give the wrapper the relevant help string via __doc__
(as described in the question section of: How do I programmatically set the docstring) and register them with setattr
, but I still have no control over their argument list.
I know I can write my functions as strings and then exec
them, but this solution seems ugly and non-pythonic.
Any other ideas?