Metadata-Version: 2.1
Name: gabriel-server
Version: 2.0.2
Summary: Server for Wearable Cognitive Assistance Applications
Home-page: http://gabriel.cs.cmu.edu
Author: Roger Iyengar
Author-email: ri@rogeriyengar.com
License: Apache
Description: # Gabriel Server Library
        
        ## Installation
        
        Requires Python 3.5 or newer.
        
        Run `pip install gabriel-server`
        
        ## Usage
        
        Data is processed by Cognitive Engines. Each cognitive engine is implemented in
        a separate class that inherits `cognitive_engine.Engine`. The `handle` method is
        called each time there is a new frame for the engine to process. `handle` gets
        passed an
        [`InputFrame`](https://github.com/cmusatyalab/gabriel/blob/2840808c3d90e4980969b2744877e739723c84bb/protocol/gabriel.proto#L20).
        It must return a
        [`ResultWrapper`](https://github.com/cmusatyalab/gabriel/blob/2840808c3d90e4980969b2744877e739723c84bb/protocol/gabriel.proto#L33).
        The `handle` method should create a `ResultWrapper` using the
        `cognitive_engine.create_result_wrapper` function. The `handle` method can add
        results to this `ResultWrapper`, or just return the `ResultWrapper` instance it
        gets from `create_result_wrapper` without adding results (if the client does not
        expect results back). The client will get a token back as soon as `handle`
        returns a `ResultWrapper` (even if the `ResultWrapper` instance just came from
        `create_result_wrapper` and nothing else wass added to it). Therefore, returning
        from `handle` before the engine is ready for the next frame will cause the
        engine to get saturated with requests faster than they can be processed.
        
        ### Single Engine Workflows
        
        The simplest possible setup involves a single cognitive engine. In this case,
        the Gabriel Server and the cognitive engine are run in the same Python program.
        Start the engine and server as follows:
        
        ```python
        local_engine.run(engine_factory=lambda: MyEngine(), source_name='my_source',
                         input_queue_maxsize=60, port=9099, num_tokens=2)
        ```
        
        `engine_factory` should be a function that runs the constructor for the
        cognitive engine. A separate process gets created with Python's
        `multiprocessing` module, and `engine_factory` gets executed in this process.
        Having `engine_factory` return a reference to an object that was created before
        `local_engine.run` was called is not recommended.
        
        ### Multiple Engine Workflows
        
        When a workflow requires more than one cognitive engine, the Gabriel server must
        be run as a standalone Python program. Each cognitive engine is run as an
        additional separate Python program. The cognitive engines can be run on the same
        computer that the Gabriel server is running on, or a different computer. Under
        the hood, the server communicates with the cognitive engines using
        [ZeroMQ](https://zeromq.org/).
        
        The Gabriel server is run using `network_engine.server_runner` as follows:
        
        ```python
        server_runner.run(websocket_port=9099, zmq_address='tcp://*:5555', num_tokens=2,
                          input_queue_maxsize=60)
        ```
        
        Cognitive engines are run using `network_engine.engine_runner` as follows:
        
        ```python
        engine_runner.run(engine=MyEngine(), source_name='my_source',
                          server_address='tcp://localhost:5555',
        		  all_responses_required=True)
        ```
        
        Note that `engine` should be a reference to an existing engine, not a function
        that runs the constructor for the engine. Unlike `local_engine`,
        `network_engine.engine_runner` does not run the engine in a separate process.
        
        When `all_responses_required` is False, the client will not receive a result
        from this engine, if a different engine processing the same frame already
        returned a result for this frame. When `all_responses_required` is True,
        the server will send every result this engine returns. Typically, you should set
        `all_responses_required` to True when an engine returns results to the clients,
        and False when an engine stores results but does not include anything useful for
        the client in the `ResultWrapper` instance that it returns.
        
        The server should be started before the engine runner.
        
        #### Timeouts
        
        When setting timeout values, consider the following from
        [ZeroMQ's guide](http://zguide.zeromq.org/py:chapter4#Shrugging-It-Off):
        > If we use a TCP connection that stays silent for a long while, it will, in
        > some networks, just die. Sending something (technically, a "keep-alive" more
        > than a heartbeat), will keep the network alive.
        
        `server_runner.run` takes an optional `timeout` argument. The default value of
        five seconds should be sufficient unless one of your cognitive engines might
        take more than five seconds to process a frame. This `timeout` value
        should be set to the longest amount of time that any of your cognitive engines
        could take to process a frame. The engine runner will not send or reply to
        messages while the cognitive engine is in the middle of processing a frame.
        
        `engine_runner.run` takes optional `timeout` and `request_retries` parameters.
        `request_retries` specifies the number of attempts that this runner will make to
        re-establish a lost connection with the Gabriel server. The number of retry
        attempts do not get replenished at any point during the engine runner's
        execution. The default `timeout` and `request_retries` values should be
        sufficient for most configurations.
        
        ## Publishing Changes to PyPi
        
        Update the version number in setup.py. Then follow
        [these instructions](https://packaging.python.org/tutorials/packaging-projects/#generating-distribution-archives).
        
Platform: UNKNOWN
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: OS Independent
Requires-Python: >=3.5
Description-Content-Type: text/markdown
