From a480cd7f2ce4b1734aca21112653e5af690f311d Mon Sep 17 00:00:00 2001 From: Bobbins228 Date: Thu, 3 Oct 2024 17:06:00 +0100 Subject: [PATCH] docs: enhance currently existing documentation create new documentation for ray clusters and ui widgets Signed-off-by: Bobbins228 --- docs/authentication.md | 4 +- docs/cluster-configuration.md | 33 ++++++++++++++- docs/images/ui-buttons.png | Bin 0 -> 22385 bytes docs/images/ui-view-clusters.png | Bin 0 -> 28767 bytes docs/ray-cluster-interaction.md | 67 +++++++++++++++++++++++++++++++ docs/ui-widgets.md | 29 +++++++++++++ 6 files changed, 130 insertions(+), 3 deletions(-) create mode 100644 docs/images/ui-buttons.png create mode 100644 docs/images/ui-view-clusters.png create mode 100644 docs/ray-cluster-interaction.md create mode 100644 docs/ui-widgets.md diff --git a/docs/authentication.md b/docs/authentication.md index bb27f1716..14eee4a82 100644 --- a/docs/authentication.md +++ b/docs/authentication.md @@ -4,7 +4,7 @@ Authenticating with your cluster allows you to perform actions such as creating ## Method 1 Token Authentication This is how a typical user would authenticate to their cluster using `TokenAuthentication`. -``` +``` python from codeflare_sdk import TokenAuthentication auth = TokenAuthentication( @@ -26,7 +26,7 @@ If the user has not specifically authenticated through the SDK by other means su ## Method 3 Specifying a Kubernetes Config File A user can specify a config file via a different authentication class `KubeConfigFileAuthentication` for authenticating with the SDK.
This is what loading a custom config file would typically look like. -``` +``` python from codeflare_sdk import KubeConfigFileAuthentication auth = KubeConfigFileAuthentication( diff --git a/docs/cluster-configuration.md b/docs/cluster-configuration.md index 97068b490..317921b0c 100644 --- a/docs/cluster-configuration.md +++ b/docs/cluster-configuration.md @@ -31,9 +31,40 @@ The `labels={"exampleLabel": "example"}` parameter can be used to apply addition After creating their `cluster`, a user can call `cluster.up()` and `cluster.down()` to respectively create or remove the Ray Cluster. +## Parameters of the `ClusterConfiguration` +Below is a table explaining each of the `ClusterConfiguration` parameters and their default values. +| Name | Type | Description | Default | +| :--------- | :-------- | :-------- | :-------- | +| `name` | `str` | The name of the Ray Cluster/AppWrapper | Required - No default | +| `namespace` | `Optional[str]` | The namespace of the Ray Cluster/AppWrapper | `None` | +| `head_cpu_requests` | `Union[int, str]` | CPU resource requests for the Head Node | `2` | +| `head_cpu_limits` | `Union[int, str]` | CPU resource limits for the Head Node | `2` | +| `head_memory_requests` | `Union[int, str]` | Memory resource requests for the Head Node | `8` | +| `head_memory_limits` | `Union[int, str]` | Memory limits for the Head Node | `8` | +| `head_extended_resource_requests` | `Dict[str, Union[str, int]]` | Extended resource requests for the Head Node see example above | `{}` | +| `worker_cpu_requests` | `Union[int, str]` | CPU resource requests for the Worker Node | `1` | +| `worker_cpu_limits` | `Union[int, str]` | CPU resource limits for the Worker Node | `1` | +| `num_workers` | `int` | Number of Worker Nodes for the Ray Cluster | `1` | +| `worker_memory_requests` | `Union[int, str]` | Memory resource requests for the Worker Node | `8` | +| `worker_memory_limits` | `Union[int, str]` | Memory resource limits for the Worker Node | `8` | +| `appwrapper` | `bool` | A boolean that wraps the Ray Cluster in an AppWrapper when set to True | `False` | +| `envs` | `Dict[str, str]` | A dictionary of environment variables to set for the Ray Cluster | `{}` | +| `image` | `str` | A paramater for specifying the Ray Image | `""` | +| `image_pull_secrets` | `List[str]` | A Parameter for providing a list of Image Pull Secrets | `[]` | +| `write_to_file` | `bool` | A boolean for writing the Ray Cluster as a Yaml file if set to True | `False` | +| `verify_tls` | `bool` | A boolean indicating whether to verify TLS when connecting to the cluster | `True` | +| `labels` | `Dict[str, str]` | A dictionary of labels to apply to the cluster | `{}` | +| `worker_extended_resource_requests` | `Dict[str, Union[str, int]]` | Extended resource requests for the Worker Node see example above | `{}` | +| `extended_resource_mapping` | `Dict[str, str]` | A dictionary of custom resource mappings to map extended resource requests to RayCluster resource names | `{}` | +| `overwrite_default_resource_mapping` | `bool` | A boolean indicating whether to overwrite the default resource mapping | `False` | +| `local_queue` | `Optional[str]` | A parameter for specifying the Local Queue label for the Ray Cluster | `None` | + + + + ## Deprecating Parameters -The following parameters of the `ClusterConfiguration` are being deprecated in release `v0.22.0`. +The following parameters of the `ClusterConfiguration` are being deprecated. | Deprecated Parameter | Replaced By | | :--------- | :-------- | | `head_cpus` | `head_cpu_requests`, `head_cpu_limits` | diff --git a/docs/images/ui-buttons.png b/docs/images/ui-buttons.png new file mode 100644 index 0000000000000000000000000000000000000000..a274929203e5cbad91aa2a3dc21a08363f9a9b73 GIT binary patch literal 22385 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 literal 0 HcmV?d00001 diff --git a/docs/ray-cluster-interaction.md b/docs/ray-cluster-interaction.md new file mode 100644 index 000000000..6e17580bd --- /dev/null +++ b/docs/ray-cluster-interaction.md @@ -0,0 +1,67 @@ +# Ray Cluster Interaction + +The CodeFlare SDK offers multiple ways to interact with Ray Clusters including the below methods. + +## get_cluster() +The `get_cluster()` function is used to initialise a `Cluster` object from a pre-existing Ray Cluster/AppWrapper.
+Below is an example of it's usage: +``` python +from codeflare_sdk import get_cluster +cluster = get_cluster(cluster_name="raytest", namespace="example", is_appwrapper=False, write_to_file=False) +-> output: Yaml resources loaded for raytest +cluster.status() +-> output: + ๐Ÿš€ CodeFlare Cluster Status ๐Ÿš€ + โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ + โ”‚ Name โ”‚ + โ”‚ raytest Active โœ… โ”‚ + โ”‚ โ”‚ + โ”‚ URI: ray://raytest-head-svc.example.svc:10001 โ”‚ + โ”‚ โ”‚ + โ”‚ Dashboard๐Ÿ”— โ”‚ + โ”‚ โ”‚ + โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ +(, True) +cluster.down() +cluster.up() # This function will create an exact copy of the retrieved Ray Cluster only if the Ray Cluster has been previously deleted. +``` + +These are the parameters the `get_cluster()` function accepts: +* `cluster_name: str # Required` -> The name of the Ray Cluster. +* `namespace: str # Default: "default"` -> The namespace of the Ray Cluster. +* `is_appwrapper: bool # Default: False` -> When set to `True` the function will attempt to retrieve an AppWrapper instead of a Ray Cluster. +* `write_to_file: bool # Default: False` -> When set to `True` the Ray Cluster/AppWrapper will be written to a file similar to how it is done in `ClusterConfiguration`. + +## list_all_queued() +The `list_all_queued()` function returns (and prints by default) a list of all currently queued-up Ray Clusters in a given namespace. +It accepts the following parameters: +* `namespace: str # Required` -> The namespace you want to retrieve the list from. +* `print_to_console: bool # Default: True` -> Allows the user to print the list to their console. +* `appwrapper: bool # Default: False` -> When set to `True` allows the user to list queued AppWrappers. + + + +## list_all_clusters() +The `list_all_clusters()` function will return a list of detailed descriptions of Ray Clusters to the console by default. It accepts the following parameters: +* `namespace: str # Required` -> The namespace you want to retrieve the list from. +* `print_to_console: bool # Default: True` -> A boolean that allows the user to print the list to their console. + +> [!NOTE] +> The following methods require a `Cluster` object to be initialised see [Cluster Configuration](./cluster-configuration.md) + +## cluster.up() +The `cluster.up()` function creates a Ray Cluster in the given namespace. + +## cluster.down() +The `cluster.down()` function deletes the Ray Cluster in the given namespace. + +## cluster.status() +The `cluster.status()` function prints out the status of the Ray Cluster's state with a link to the Ray Dashboard. + +## cluster.details() +The `cluster.details()` function prints out a detailed description of the Ray Cluster's status, worker resources and a link to the Ray Dashboard. + +## cluster.wait_ready() +The `cluster.wait_ready()` function waits for the requested cluster to be ready, up to an optional timeout and checks every 5 seconds. It accepts the following parameters: +* `timeout: Optional[int] # Default: None` -> Allows the user to define a timeout for the `wait_ready()` function. +* `dashboard_check: bool # Default: True` -> If enabled the `wait_ready()` function will wait until the Ray Dashboard is ready too. diff --git a/docs/ui-widgets.md b/docs/ui-widgets.md new file mode 100644 index 000000000..7136a484d --- /dev/null +++ b/docs/ui-widgets.md @@ -0,0 +1,29 @@ +# Jupyter UI Widgets +Below are some examples of the Jupyter UI Widgets that are included in the CodeFlare SDK.
+> [!NOTE] +> To use the widgets functionality you must be using the CodeFlare SDK in a Jupyter Notebook environment. + +## Cluster Up/Down Buttons +The Cluster Up/Down buttons appear after successfully initialising your [ClusterConfiguration](cluster-configuration.md#ray-cluster-configuration). +There are two buttons and a checkbox `Cluster Up`, `Cluster Down` and `Wait for Cluster?` which mimic the [cluster.up()](ray-cluster-interaction.md#clusterup), [cluster.down()](ray-cluster-interaction.md#clusterdown) and [cluster.wait_ready()](ray-cluster-interaction.md#clusterwait_ready) functionality. + +After initialising their `ClusterConfiguration` a user can select the `Wait for Cluster?` checkbox then click the `Cluster Up` button to create their Ray Cluster and wait until it is ready. The cluster can be deleted by clicking the `Cluster Down` button.
+ +An image of the up/down ui buttons + +## View Clusters UI Table +The View Clusters UI Table allows a user to see a list of Ray Clusters with information on their configuration including number of workers, CPU requests and limits along with the clusters status. + +An image of the view clusters ui table + +Above is a list of two Ray Clusters `raytest` and `raytest2` each of those headings is clickable and will update the table to view the selected Cluster's information. +There are three buttons under the table `Cluster Down`, `View Jobs` and `Open Ray Dashboard`.
+* The `Cluster Down` button will delete the selected Cluster. +* The `View Jobs` button will try to open the Ray Dashboard's Jobs view in a Web Browser. The link will also be printed to the console. +* The `Open Ray Dashboard` button will try to open the Ray Dashboard view in a Web Browser. The link will also be printed to the console. + +The UI Table can be viewed by calling the following function. +``` python +from codeflare_sdk import view_clusters +view_clusters() # Accepts namespace parameter but will try to gather the namespace from the current context +```