-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
69430de
commit 61f502a
Showing
12 changed files
with
360 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# Router | ||
|
||
A `Router` object represents a router that is created on Turing API. It does not (and should not) ever be created | ||
manually by using its constructor directly. Instead, you should only be manipulating with `Router` instances that | ||
get returned as a result of using the various `Router` class and instance methods that interact with Turing API. | ||
|
||
A `Router` object has attributes such as `id`, `name`, `project_id`, `environment_name`, `monitoring_url`, `status` | ||
and `endpoint`. It also has a `config` attribute, which is a `RouterConfig` containing the current configuration for | ||
the router. | ||
|
||
When trying to replicate configuration from an existing router, always retrieve the underlying `RouterConfig` from | ||
the `Router` instance by accessing its `config` attribute. |
13 changes: 13 additions & 0 deletions
13
sdk/docs/how-to/use-turing-sdk-classes/02-router-version.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# RouterVersion | ||
|
||
A `RouterVersion` represents a single version (and configuration) of a Turing Router. Just as `Router` objects, they | ||
should almost never be created manually by using their constructor. | ||
|
||
Besides assessing attributes of a `RouterVersion` object directly, which will allow you to access attributes such as | ||
`id`, `version`, `created_at`, `updated_at`, `environment_name`, `status`, `name`, `monitoring_url`, `log_config`, | ||
you may also consider retrieving the entire router configuration from a specific `RouterVersion` object as a | ||
`RouterConfig` for further manipulation: | ||
|
||
```python | ||
my_config = router_version.get_config() | ||
``` |
46 changes: 46 additions & 0 deletions
46
sdk/docs/how-to/use-turing-sdk-classes/03-router-config.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
# RouterConfig | ||
|
||
`RouterConfig` objects are what you would probably interact most frequently with when using Turing SDK. They | ||
essentially carry a router's configuration and define the ways in which a router should be run. All of the | ||
methods that interact with Turing API that involve the updating or creating of routers involve the | ||
use of `RouterConfig` objects as arguments. | ||
|
||
As you would have seen before, a `RouterConfig` object is built using multiple parts: | ||
|
||
```python | ||
@dataclass | ||
class RouterConfig: | ||
""" | ||
Class to create a new RouterConfig. Can be built up from its individual components or initialised instantly | ||
from an appropriate API response | ||
:param environment_name: name of the environment | ||
:param name: name of the router | ||
:param routes: list of routes used by the router | ||
:param rules: list of rules used by the router | ||
:param default_route_id: default route id to be used | ||
:param experiment_engine: experiment engine config file | ||
:param resource_request: resources to be provisioned for the router | ||
:param timeout: request timeout which when exceeded, the request to the router will be terminated | ||
:param log_config: logging config settings to be used with the router | ||
:param enricher: enricher config settings to be used with the router | ||
:param ensembler: ensembler config settings to be used with the router | ||
""" | ||
environment_name: str | ||
name: str | ||
routes: Union[List[Route], List[Dict[str, str]]] = None | ||
rules: Union[List[TrafficRule], List[Dict]] = None | ||
default_route_id: str = None | ||
experiment_engine: Union[ExperimentConfig, Dict] = None | ||
resource_request: Union[ResourceRequest, Dict[str, Union[str, int]]] = None | ||
timeout: str = None | ||
log_config: Union[LogConfig, Dict[str, Union[str, bool, int]]] = None | ||
enricher: Union[Enricher, Dict] = None | ||
ensembler: Union[RouterEnsemblerConfig, Dict] = None | ||
``` | ||
|
||
When constructing a `RouterConfig` object from scratch, it is **highly recommended** that you construct each | ||
individual component using the Turing SDK classes provided instead of using `dict` objects which do not perform any | ||
schema validation. | ||
|
||
In the following pages of this subsection, we will go through the usage of these individual components separately. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# Route | ||
|
||
Creating a route with Turing SDK is just as simple as doing it on the UI; one only needs to specify the `id`, | ||
`endpoint`, and `timeout` of the route: | ||
|
||
```python | ||
@dataclass | ||
class Route: | ||
""" | ||
Class to create a new Route object | ||
:param id: route's name | ||
:param endpoint: endpoint of the route. Must be a valid URL | ||
:param timeout: timeout indicating the duration past which the request execution will end | ||
""" | ||
id: str | ||
endpoint: str | ||
timeout: str | ||
``` |
17 changes: 17 additions & 0 deletions
17
sdk/docs/how-to/use-turing-sdk-classes/05-experiment-config.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# ExperimentConfig | ||
|
||
The `ExperimentConfig` class is a simple container to carry configuration related to an experiment to be used by a | ||
Turing Router. Note that as Turing does not create experiments automatically, you would need to create your | ||
experiments separately prior to specifying their configuration here. | ||
|
||
Also, notice that `ExperimentConfig` does not contain any fixed schema as it simply carries configuration for | ||
generic experiment engines, which are used as plug-ins for Turing. When building an `ExperimentConfig` from scratch, | ||
you would need to consider the underlying schema for the `config` attribute as well as the appropriate `type` that | ||
corresponds to your selected experiment engine: | ||
|
||
```python | ||
@dataclass | ||
class ExperimentConfig: | ||
type: str = "nop" | ||
config: Dict = None | ||
``` |
19 changes: 19 additions & 0 deletions
19
sdk/docs/how-to/use-turing-sdk-classes/06-resource-request.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# ResourceRequest | ||
|
||
A `ResourceRequest` class carries information related to the resources that should be allocated to a particular | ||
component, e.g. router, ensembler, enricher, etc., and is defined by 4 attributes, `min_replica`, `max_replica`, | ||
`cpu_request`, `memory_request`: | ||
|
||
```python | ||
@dataclass | ||
class ResourceRequest: | ||
min_allowed_replica: ClassVar[int] = 0 | ||
max_allowed_replica: ClassVar[int] = 20 | ||
min_replica: int | ||
max_replica: int | ||
cpu_request: str | ||
memory_request: str | ||
``` | ||
|
||
Note that the units for CPU and memory requests are measured in cpu units and bytes respectively. You may wish to | ||
read more about how these are measured [here](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
# LogConfig | ||
|
||
Logging for Turing Routers is done through BigQuery or Kafka, and its configuration is managed by the `LogConfig` | ||
class. Two helper classes (child classes of `LogConfig`) have been created to assist you in constructing these objects: | ||
|
||
```python | ||
@dataclass | ||
class BigQueryLogConfig(LogConfig): | ||
""" | ||
Class to create a new log config with a BigQuery config | ||
:param table: name of the BigQuery table; if the table does not exist, it will be created automatically | ||
:param service_account_secret: service account which has both JobUser and DataEditor privileges and write access | ||
:param batch_load: optional parameter to indicate if batch loading is used | ||
""" | ||
def __init__(self, | ||
table: str, | ||
service_account_secret: str, | ||
batch_load: bool = None): | ||
self.table = table | ||
self.service_account_secret = service_account_secret | ||
self.batch_load = batch_load | ||
|
||
super().__init__(result_logger_type=ResultLoggerType.BIGQUERY) | ||
``` | ||
|
||
```python | ||
@dataclass | ||
class KafkaLogConfig(LogConfig): | ||
def __init__(self, | ||
brokers: str, | ||
topic: str, | ||
serialization_format: KafkaConfigSerializationFormat): | ||
""" | ||
Method to create a new log config with a Kafka config | ||
:param brokers: comma-separated list of one or more Kafka brokers | ||
:param topic: valid Kafka topic name on the server; data will be written to this topic | ||
:param serialization_format: message serialization format to be used | ||
""" | ||
self.brokers = brokers | ||
self.topic = topic | ||
self.serialization_format = serialization_format | ||
|
||
super().__init__(result_logger_type=ResultLoggerType.KAFKA) | ||
``` | ||
|
||
If you are using a `KafkaLogConfig`, you would additionally have to define a `serialization_format`, which is of a | ||
`KafkaConfigSerializationFormat`: | ||
|
||
```python | ||
class KafkaConfigSerializationFormat(Enum): | ||
JSON = "json" | ||
PROTOBUF = "protobuf" | ||
``` | ||
|
||
If you do not intend to use any logging, simply create a regular `LogConfig` object with `result_loggger_type` set | ||
as `ResultLoggerType.NOP`, without defining the other arguments: | ||
|
||
```python | ||
log_config = LogConfig(result_logger_type=ResultLoggerType.NOP) | ||
``` | ||
|
||
While `ResultLoggerType` may take on the `enum` value of `ResultLoggerType.CONSOLE`, its behaviour is | ||
currently undefined and you will almost certainly experience errors while using it. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
# Enricher | ||
|
||
An `Enricher` object holds configuration needed to define an enricher: | ||
|
||
```python | ||
@dataclass | ||
class Enricher: | ||
""" | ||
Class to create a new Enricher | ||
:param image: registry and name of the image | ||
:param resource_request: ResourceRequest instance containing configs related to the resources required | ||
:param endpoint: endpoint URL of the enricher | ||
:param timeout: request timeout which when exceeded, the request to the enricher will be terminated | ||
:param port: port number exposed by the container | ||
:param env: environment variables required by the container | ||
:param id: id of the enricher | ||
:param service_account: optional service account for the Docker deployment | ||
""" | ||
image: str | ||
resource_request: ResourceRequest | ||
endpoint: str | ||
timeout: str | ||
port: int | ||
env: List['EnvVar'] | ||
id: int = None | ||
service_account: str = None | ||
``` | ||
|
||
## EnvVar | ||
|
||
To define environment variables for the `env` attribute in an `Enricher`, you would need to define them using the | ||
`EnvVar` object: | ||
|
||
```python | ||
@dataclass | ||
class EnvVar: | ||
name: str | ||
value: str | ||
``` |
74 changes: 74 additions & 0 deletions
74
sdk/docs/how-to/use-turing-sdk-classes/09-router-ensembler-config.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
# RouterEnsemblerConfig | ||
|
||
Ensembling for Turing Routers is done through Standard, Docker or Pyfunc ensemblers, and its configuration is | ||
managed by the `RouterEnsemblerConfig` class. Three helper classes (child classes of `RouterEnsemblerConfig`) have been | ||
created to assist you in constructing these objects: | ||
|
||
```python | ||
@dataclass | ||
class StandardRouterEnsemblerConfig(RouterEnsemblerConfig): | ||
def __init__(self, | ||
experiment_mappings: List[Dict[str, str]]): | ||
""" | ||
Method to create a new standard ensembler | ||
:param experiment_mappings: configured mappings between routes and treatments | ||
""" | ||
self.experiment_mappings = experiment_mappings | ||
super().__init__(type="standard") | ||
``` | ||
|
||
```python | ||
@dataclass | ||
class DockerRouterEnsemblerConfig(RouterEnsemblerConfig): | ||
def __init__(self, | ||
image: str, | ||
resource_request: ResourceRequest, | ||
endpoint: str, | ||
timeout: str, | ||
port: int, | ||
env: List['EnvVar'], | ||
service_account: str = None): | ||
""" | ||
Method to create a new Docker ensembler | ||
:param image: registry and name of the image | ||
:param resource_request: ResourceRequest instance containing configs related to the resources required | ||
:param endpoint: endpoint URL of the ensembler | ||
:param timeout: request timeout which when exceeded, the request to the ensembler will be terminated | ||
:param port: port number exposed by the container | ||
:param env: environment variables required by the container | ||
:param service_account: optional service account for the Docker deployment | ||
""" | ||
self.image = image | ||
self.resource_request = resource_request | ||
self.endpoint = endpoint | ||
self.timeout = timeout | ||
self.port = port | ||
self.env = env | ||
self.service_account = service_account | ||
super().__init__(type="docker") | ||
``` | ||
|
||
```python | ||
@dataclass | ||
class PyfuncRouterEnsemblerConfig(RouterEnsemblerConfig): | ||
def __init__(self, | ||
project_id: int, | ||
ensembler_id: int, | ||
timeout: str, | ||
resource_request: ResourceRequest): | ||
""" | ||
Method to create a new Pyfunc ensembler | ||
:param project_id: project id of the current project | ||
:param ensembler_id: ensembler_id of the ensembler | ||
:param resource_request: ResourceRequest instance containing configs related to the resources required | ||
:param timeout: request timeout which when exceeded, the request to the ensembler will be terminated | ||
""" | ||
self.project_id = project_id | ||
self.ensembler_id = ensembler_id | ||
self.resource_request = resource_request | ||
self.timeout = timeout | ||
super().__init__(type="pyfunc") | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
# TrafficRule | ||
|
||
Each traffic rule is defined by at least one `TrafficRuleCondition` and one route. Routes are essentially the `id`s | ||
of `Route` objects that you intend to specify for the entire `TrafficRule`. | ||
|
||
```python | ||
@dataclass | ||
class TrafficRule: | ||
""" | ||
Class to create a new TrafficRule based on a list of conditions and routes | ||
:param conditions: list of TrafficRuleConditions that need to ALL be satisfied before routing to the given routes | ||
:param routes: list of routes to send the request to should all the given conditions be met | ||
""" | ||
conditions: Union[List[TrafficRuleCondition], List[Dict[str, List[str]]]] | ||
routes: List[str] | ||
``` | ||
|
||
## Traffic Rule Condition | ||
|
||
When defining a traffic rule, one would need to decide between using a `HeaderTrafficRuleCondition` or a | ||
`PayloadTrafficRuleCondition`. These subclasses can be used to build a `TrafficRuleCondition` without having to | ||
manually set attributes such as `field_source` or `operator`: | ||
|
||
```python | ||
@dataclass | ||
class HeaderTrafficRuleCondition(TrafficRuleCondition): | ||
def __init__(self, | ||
field: str, | ||
values: List[str]): | ||
""" | ||
Method to create a new TrafficRuleCondition that is defined on a request header | ||
:param field: name of the field specified | ||
:param values: values that are supposed to match those found in the field | ||
""" | ||
super().__init__(field_source=FieldSource.HEADER, field=field, operator="in", values=values) | ||
|
||
|
||
@dataclass | ||
class PayloadTrafficRuleCondition(TrafficRuleCondition): | ||
def __init__(self, | ||
field: str, | ||
values: List[str]): | ||
""" | ||
Method to create a new TrafficRuleCondition that is defined on a request payload | ||
:param field: name of the field specified | ||
:param values: values that are supposed to match those found in the field | ||
""" | ||
super().__init__(field_source=FieldSource.PAYLOAD, field=field, operator="in", values=values) | ||
``` | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters