This readme provides a condensed tutorial. A much more complete reference can be found on Read The Docs.
Setup your account
Register an account on Moobius. You have to enter an email and password to use this SDK. Third-party logins are not supported.
Install Python and Moobius
Make sure you are at least at Python 3.10 with python --version. If not, install it from Python.org. Also make sure pip is isntalled.
Install with pip install moobius --upgrade
Note: It may be "python3" and "pip3" instead of "python" and "pip" if you are not aliasing "python" to python3.
Create a simple service
cd into a folder of your choice.
Type in moobius or moobius gui. Enter your email and password (these are the only fields you absolutely need to get a correct configuration). If you are getting a command not found error, you can alternatively use python -m moobius.
Test Moobius
Start the service with python service.py within your folder. Go back to your browser and you should see a new channel in the list of channels. The service is currently running on this channel.
Experiment!
Congratulations! Now you have your first Moobius Service. It functions by overriding the base Moobius class. The code is driven by async callbacks which can in turn send commands up to the service to i.e. send particular messages to particular users.
Several demos that showcase simple features are a good starting point.
Again, a more detailed version of this is available in the read-the-docs.
-
Tutorials: In
projects/demothere areDemoServiceTutorial.mdandDemoAgentTutorial.mdwalkthroughs. -
Service: The Service handles most of the interaction with the platform SDK. This includes sending and responding to messages, controlling the look and feel, and uploading assets. Callbacks have the format
on_xyzand actuators have the formatsend_xyz. JSON is automatically converted to and from dataclasses withintypes.py. A CCS is our term for your custom service that overrides the base Moobius class. -
Databases: Moobius provides a client-side database engine with the
MoobiusStorageclass. The structure is determined by a configuration file (usually./config/db.json) or can be hard-coded in your CCS app. Each element has anamethat created a dynamic attribute on the MoobiusStorage instance. Each element also contains animplementationwhich determines the database engine; currently "json" and "redis" are supported. -
Logging: Logging uses Loguru, a colorful, comprehensive logging system. Simply replace
printwithlogging.info(),logging.warning(), orlogging.error()for a thread-safe logging that also saves to the disk. It has plenty of other features as well. -
Wand: The
MoobiusWandclass launches and manages one or more services. The services can either run on the Wand's process (recommended for simple tasks) or on a seperate process withbackground=True. Using a background service requires moving initialization of unpicklable objects toself.before_channel_init()orself.on_start()instead ofself.__init__(). Usewand.spell()orawait wand.aspell()to have the wand interact with the service by calling theself.on_spell()callback. -
Usermode: Usermode is an advanced feature with niche use-cases. This is a service running with
service_modeset to False. Instead of a service, it acts as a user who can interact with a service much like a user would. It responds to messages recieved down from the serivce (instead of up from a user) and sends messages up instead of down. Instead of sending buttons, wigits, and other menus and recieving clicks and other interaction, it recieves changes to these components and sends clicks. Only use usermode if you need to automate a pre-existing account. If all you need to do is create AI characters and have them talk, it is much easier to do so using theservice.create_characterfunction.
As mentioned before, databases allow persistant storage and support redis. Each custom attribute of a MoobiusStorage instance is a CachedDict which in turn implements __getitem__, __setitem__, and __delitem__. This means that it can be used as a dict and will automatically save whenever it is modified. However, the value itself may be in turn a mutable data structure. In which case CachedDict will not be aware of this change and a call to cached_dict.save(key) is needed to serialize and save the value to the database.
Custom database engines can be implemented by following these steps:
- Inherit the
DatabaseInterfaceclass and specifying the engine. - Choose a name.
- Add the name to the
get_enginefunction in storage.py. - Use the name in the database config file.
In addition to name and implementation, each database field defined in the configuration has load and clear booleans. Usually load is True and clear is False. (Experimental) load can be False to not load everything at once for optimization. If clear is True, the database will be cleared from the disk on init and load does not matter.
The code is divided into the core logic, the database, and the network. All the Python code is in the src/moobius folder. Again, an exhaustive list is on read-the-docs.
core/: The core logic of the SDK including Services and databases.sdk.py: Defines theMoobiusclass which is the main class that aggregates all functions a CCS needs to interact with the Moobius platform. It is the base class of a Service.storage.py: DefinesMoobiusStoragewhich acts as a container of disk-stored "dictionaries" (CachedDictinstances). This feature can be used independently of the Moobius class.wand.py: DefinesMoobiusWandwhich handles all the multiprocessing magic. This can be used independently of the Moobius class.
database/: The infrastructure ofMoobiusStorage.database_interface.py: DefinesDatabaseInterface, an abstract base class used by each of the below implementations.null_database.py: DefinesNullDatabasewhich is likedev/null.json_database.py: DefinesJSONDatabasewhich uses json files and stores plaintext.redis_database.py: DefinesRedisDatabasewhich requires a running Redis server to function.magical_storage.py: Defines several classes.CachedDictis used like a dictionary but has a database under the hood.MagicalStorageis built onCachedDictand supports customized on-the-flyCachedDictcontainers.
network/: Network communication with the Platform.http_api_wrapper.py: DefinesHTTPAPIWrapperwhich mirrors the Platform's low-level HTTP API. Used byMoobiusinstances. Handels HTTPS auth among other tasks.ws_client.py: DefinesWSClientwhich mirrors the Platform's low-level Socket API. Used byMoobiusinstances. Handles most communication for a running service.
types.py: Defines many dataclassesButton,Canvas,View,Message,MessageBody,ButtonClick, etc. Each class encodes a very simple data-structure and is easily converted to/from a dict.json_utils.py: Extends JSON read/write functionality.quickstart.py: This is called whenmoobiusis typed into the terminal and sets up a basic service.