Package: automata-ws
AutomataTable of ContentsIntroductionGetting StartedPrerequisitesInstallation and SetupStates, Events, State Changes, Data Events, and PayloadsAdvancedLicenseIntroductionAutomata is a lightweight framework that allows users to define a state machine based websocket server. Each machine has a collection of states, for example, a traffic light state machine has Green, Yellow, and Red states. Each state can have any number of events, these events can be defined by the developer to do whatever they want. They can return data back to the client, transition to a new state, process data, or even do nothing; that is all up the the desired implementation. Overall, the goal of Automata is to provide a unified methodology and doctrine for defining and improving the clarity of websocket communication.Getting StartedThis is a simple example of how you to set up your Automata instance and run your application.Prerequisitespython version >= 3.7Installation and SetupInstall withpip install automata-wsInitialize your Automata (we use app.py)fromautomataimportAutomatamy_machine=Automata(name="myMachine")Create your states and any events (in any directory you want)fromautomataimportState,EventStatus,transition,transmitred_light=State('red_light')@red_light.event('change_to_green')asyncdefhandler(automata,data):#do something here...run_some_func()awaittransition(automata,'green',EventStatus.OK)#will change the state of our machine and will report this to the clientgreen_state=State(name="green",targets=["yellow"])@green_light.event('change_to_yellow')asyncdefhandler(automata,data):awaittransmit(automata,EventStatus.OK,some_data)#will send back data without changing state#and so on and so on...Register states in your machine (back in the file you defined the machine)my_machine.register_state(red_light)#the first state that is registered will be the initial state for new sessionsmy_machine.register_state(green_light)Run the machinemy_machine.run('localhost',8000)States, Events, State Changes, Data Events, and Payloads1. StatesEvery state must be unique: there cannot exist two states with the same nameA state may have a list of target states: all of the states in which a transition from the referenced state is possibleTrying to transition to a state that is not in the target list for the referenced state will raise an exceptionAn undefined target list means that a transition to any state is allowedgreen_state=State(name="green",targets=["yellow"]#the target list with all the states that the green_state can transition to)The initial state is the one that is registered first in theAutomatainstance2. EventsEvents defined for a specific state must be uniqueAll events are identified by their name and defined by their handlerEach handler will recieve anAutomatainstance and adatainstance (either as adictor astr)@green_state.event('change_to_yellow')#this annotation will create an event for the corresponding state (green_state in this case)asyncdefhandler(automata:Automata,data):run_some_code()do_whatever_you_want()awaittransition(automata,'yellow',EventStatus.OK)@green_state.event('ping')defhandler(automata:Automata,data):#the handler doesn't necessarily have to be asyncprint('pong')3. State ChangesEach state transition has to be relayed to the client: they will receive data about their new state and all events they can callEach state transition has to be accompanied with a status code: these are similar to the 100, 200, 300, 400, 500 status codes defined in HTTP and are found in theEventStatusenumA state transition may have data associated with it if needed (data is optional)A state transition is achieved through thetransitionfunctionawaittransition(automata,'logged_in',EventStatus.OK,some_data)#a state transition with some data4. Data EventsIt is possible to send data back to the client without changing state: this is achieved through thetransmitfunctionEach data event must be accompanied with a status code (as mentioned above)awaittransmit(automata,EventStatus.OK,some_data)#a data event with no state transition5. PayloadsAll client to server payloads must follow the format below{"event":"event_name","data":data}A state change will be relayed to the client in the following format (occurs whentransitionis called){"state":"new_state","events":["event1","event2",//Any number of possible events associated with the new state],"status":200,"data":"some_data"//optional: can be None/Null}Any generic data event will be returned back in the following format (occurs whentransmitis called){"status":200,"data":"some_data"//optional}Advanced1. Custom HTTP Endpoint(s)As of now all websocket connections are served on/It is possible to implement a custom endpoint using theautomata.endpoint('/endpoint')annotationThis is useful if a health check (or something generic) is needed@my_machine.endpoint('/health')asyncdefsome_handler(request_headers):return'OK'Note: onlygetrequests can be handledLicenseApache License 2.0