Creating an extension package#
This guide explains how to create an OrangeQS Juice extension that can be installed inside the OrangeQS Juice framework.
Setting up a Python package#
An OrangeQS Juice extension is a standard Python package. It can subclass OrangeQS Juice classes and define entrypoints to automatically inject its extra functionality.
Start by setting up an empty Python package structure following the Python Packaging User Guide.
Ensure that your package is pip installable in your local environment, e.g. using pip install -e . from the root folder of your package.
For the following sections we assume you have set up a package with the following structure:
juice_extension_example/
├── pyproject.toml
└── src/
└── juice_extension_example/
└── __init__.py
Managing dependencies#
Extensions will be installed in different contexts in an OrangeQS Juice installation. To minimize dependencies and thereby dependency conflicts and environment size, it is required to specify optional dependencies for each context separately.
We distinguish three different sets of dependencies for an extension:
The default dependencies. This is a minimal set of dependencies that is required to make a minimal part of the package importable. This minimal part shoud only include configuration, types and shared interfaces, and thus only dependencies that are required to define these. The dependencies should include the
orangeqs-juice-corepackage, and for example a data validation library likepydantic.The
clientdependencies: This is a set of dependencies required to run the client side of the extension. For example, if your extension starts a HTTP server in a service, the client-side only requires HTTP client packages to talk to the remote server. This dependency set is intended to be used in user containers, but can also be used in other services that communicate as clients to the the HTTP service.The
serverdependencies: This is a set of dependencies required to run the server side of an extension. Continuing the HTTP example, this contains packages that are required to run a HTTP server. This dependency set is then only required in the service where the HTTP server is running.
For some extensions one of the dependency sets might be empty. In that case it’s still good practice to define the empty set. This allows for a recognizable installation procedure for all extensions. It’s also possible that your extension requires an extra set of dependencies that does not fit one of the sets above. As an extension is just a Python package, this is allowed.
Let’s continue the HTTP server example by showing what your pyproject.toml could look like for such an extension.
# pyproject.toml
[project]
name = "juice_extension_example"
version = "0.0.1"
dependencies = [
"orangeqs-juice-core" # Always required
"pydantic", # For data validation
]
[project.optional-dependencies]
# Dependencies required to send HTTP requests
client = [
# No dependencies, we will use the built-in HTTP client library
]
# Dependencies required to run a HTTP server
server = [
"tornado" # Web framework for running a HTTP server
]
Your extension is now ready to be installed in an OrangeQS Juice development environment.