How to run function if the command is the name of a function?

So I’m wondering how to run a function from another file so if the command is the same as the function name? discord.py implements it exactly how I want to do it. where it can just call the commands. my code looks like this main.py

from ai_main import CommandManager


bot = CommandManager(prefix="!")


@bot.call_fun
def hello():
    print("hello")


bot.run()

ai_main.py

class CommandManager:
    def __init__(self, prefix="!"):
        print("INIT")
        self.prefix = prefix

    def run(self):
        user_input = input("Enter command: ")
        self.check_for_command(user_input)

    def check_for_command(self, user_input):
        if user_input[0] == self.prefix:
            string = ""
            for char in user_input[1:]:
                if char == " ":
                    break
                else:
                    string += char
            if string != "":
                self.call_fun(string)

    def call_fun(self, command):
        # command.run() ??? how to call it?
        return command

Answer

You want to store an instance of the function inside a mapping as part of the CommandManager class. Later, you can use the mapping to find the stored function.

You can also make the run method use a While loop to allow calling multiple commands.

class CommandManager:
    def __init__(self, prefix="!"):
        """
        The CommandManager allows users to register functions for
        calling them in an interactive shell!
    
        Each command can be registered in the CommandManager by wrapping
        it with the add_command decorator. This will store the function in
        the manager by looking at it's __name__ attribute and later allow 
        users to reference the function by that name.

        All commands given to the CommandManager must start with "!", 
        followed by the name of the registered function.
        """

        self.prefix = prefix
        self.commands = {}

    def run(self):
        """
        Run the CommandManager repeatedly by asking for user input.
        """

        while True:
            user_input = input("Enter command: ")
            self.run_command(user_input)

    def run_command(self, user_input):
        """
        Parses input given by the user to determine an appropriate
        command to call. Commands may only be run one at a time and
        must start with "!"
        """

        user_input = user_input.strip()
        if user_input[0] != self.prefix:
            print(f"Invalid command: '{user_input}'. Must start with '!'")
            return

        # Strip out the prifix and use the first word as the command name
        command_name = user_input[1:].strip().split(" ")[0]

        # Check that we have a command registered for that name.
        if command_name not in self.commands:
            print(f"Unknown command: '{user_input}'.")
            return

        self.commands[command_name]()

    def add_command(self, command):
        """
        Register the command to the manager. Uses the __name__ attribute of
        the function to store a reference to the function.
        """

        self.commands[command.__name__] = command
        return command
from ai_main import CommandManager


bot = CommandManager()


@bot.add_command
def hello():
    print("hello")


if __name__ == "__main__":
    bot.run()