Services#

OrangeQS Juice services are fully customizable Python programs running within the OrangeQS Juice framework. By default, OrangeQS Juice ships with the IPythonService type which runs an IPython kernel, with a customizable module to run on startup. You can extend this functionality by implementing a class based on the Service class, of which IPython service is an example.

By implementing a Python program as an OrangeQS Juice service you benefit from all the built-in functionality of OrangeQS Juice, like centralized logging, monitoring, service discovery, etc.

Example: HTTP server#

This example shows how to build an OrangeQS Juice service that runs a HTTP server.

Any OrangeQS Juice service needs to implement the base class Service, which has a constructor and the Service.start method. Let’s start by defining an HTTPService class that can be used as an OrangeQS Juice service.

from orangeqs.juice.service import Service

class HTTPService(Service):
    """An OrangeQS Juice service that runs a HTTP server"""

    def __init__(self, service_name: str):
        super().__init__(service_name)
        # TODO: Initialize HTTP server

    def start(self):
        # TODO: Start HTTP server

For this example we will use a HTTP server based on the Tornado framework. We define the request handler for our HTTP application:

import tornado

class HTTPServiceHandler(tornado.web.RequestHandler):
    def initialize(self, service_name):
        self.service_name = service_name

    def get(self):
        self.write(f"Hello from {self.service_name}")

Let’s now add the HTTP application to our custom HTTPService class.

import asyncio

from orangeqs.juice.service import Service

class HTTPService(Service):
    """An OrangeQS Juice service that runs a HTTP server"""

    def __init__(self, service_name: str):
        super().__init__(service_name)
        # Initialize the HTTP application
        self.app = tornado.web.Application([
            (r"/", HTTPServiceHandler)
        ])

    async def serve():
        """Serve HTTP request asynchronously forever."""
        self.app.listen(8000)
        await asyncio.Event().wait()

    def start(self):
        """
        Start serving HTTP requests using the `self.serve()` coroutine.

        This function never returns and runs forever.
        """
        asyncio.run(self.serve())

The final step is to configure an OrangeQS Juice service to use this class. For this you need to point your service to the HTTPService you have just created. You can do this by adding the following section to your OrangeQS Juice orchestrator configuration.

[orchestration.services.http_service]
# Entrypoint follows the format `path.to.your.module:ClassName`
entrypoint = "juice_extension_example:HTTPService"

As a next step when creating a service, you would likely want to learn how to use Juice’s communication framework