Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

document flytekit remote module #564

Merged
merged 4 commits into from
Jul 26, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/source/_templates/custom.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@

.. rubric:: {{ _('Methods') }}
{% for item in methods %}

{% if item != '__init__' %}
.. automethod:: {{ item }}
{% endif %}

{%- endfor %}
{% endif %}
{% endblock %}
Expand Down
2 changes: 2 additions & 0 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@
# build the templated autosummary files
autosummary_generate = True

autodoc_typehints = "description"

# autosectionlabel throws warnings if section names are duplicated.
# The following tells autosectionlabel to not throw a warning for
# duplicated section names that are in different documents.
Expand Down
110 changes: 75 additions & 35 deletions docs/source/design/control_plane.rst
Original file line number Diff line number Diff line change
@@ -1,55 +1,95 @@
.. _design-control-plane:

############################
Control Plane Objects
############################
For those who require programmatic access to the control plane, certain APIs are available through "control plane classes".
###################################################
FlyteRemote: A Programmatic Control Plane Interface
###################################################

.. warning::
For those who require programmatic access to the control plane, :mod:`~flytekit.remote` module enables you to perform
certain operations in a python runtime environment.

The syntax of this section, while it will continue to work, is subject to change.
Since this section naturally deals with the control plane, this discussion is only relevant for those who have a Flyte
backend set up, and have access to it (a local sandbox will suffice as well of course). These objects do not rely on the
underlying code they represent being locally available.

Since this section naturally deals with the control plane, this discussion is only relevant for those who have a Flyte backend set up, and have access to it (a local backend will suffice as well of course). These objects do not rely on the underlying code they represent being locally available.
***************************
Create a FlyteRemote Object
***************************

*******
Setup
*******
Similar to the CLIs, this section requires proper configuration. Please follow the setup guide there.
The :class:`~flytekit.remote.FlyteRemote` class is the entrypoint for programmatically performing operations in a python
runtime. There are two ways of creating a remote object.

Unlike the CLI case however, you may need to explicitly target the configuration file like so ::
**Initialize directly**

from flytekit.configuration.common import CONFIGURATION_SINGLETON
CONFIGURATION_SINGLETON.reset_config("/Users/full/path/to/config")
.. code-block:: python

from flytekit.remote import FlyteRemote

remote = FlyteRemote(default_project="project", default_domain="domain", flyte_admin_url="<url>", insecure=True)

**Initialize from flyte config**

.. TODO: link documentation to flyte config and environment variables

This will initialize a :class:`~flytekit.remote.FlyteRemote` object from your flyte config file or environment variable
overrides

.. code-block:: python

remote = FlyteRemote.from_config()

*****************************
Fetching Flyte Admin Entities
*****************************

.. code-block:: python

flyte_task = remote.fetch_task(name="my_task", version="v1")
flyte_workflow = remote.fetch_workflow(name="my_workflow", version="v1")
flyte_launch_plan = remote.fetch_launch_plan(name="my_launch_plan", version="v1")

******************
Executing Entities
******************

*******
Classes
*******
This is not an exhaustive list of the objects available, but should provide the reader with the wherewithal to further ascertain for herself additional functionality.
You can execute all of these flyte entities, which returns a :class:`~flytekit.remote.FlyteWorkflowExecution` object.
For more information on flyte entities, see the See the :ref:`remote flyte entities <remote-flyte-execution-objects>`
reference.

Task
======
To fetch a Task ::
.. code-block:: python

from flytekit.common.tasks.task import SdkTask
SdkTask.fetch('flytetester', 'staging', 'recipes.core_basic.task.square', '49b6c6bdbb86e974ffd9875cab1f721ada8066a7')
flyte_entity = ... # one of FlyteTask, FlyteWorkflow, or FlyteLaunchPlan
execution = remote.execute(flyte_entity, inputs={...})

********************************
Waiting for Execution Completion
********************************

Workflow
========
To inspect a Workflow ::
.. code-block:: python

from flytekit.common.workflow import SdkWorkflow
wf = SdkWorkflow.fetch('flytetester', 'staging', 'recipes.core_basic.basic_workflow.my_wf', '49b6c6bdbb86e974ffd9875cab1f721ada8066a7')
completed_execution = remote.wait(execution)
cosmicBboy marked this conversation as resolved.
Show resolved Hide resolved

WorkflowExecution
=================
This class represents one run of a workflow. The ``execution_name`` used here is just the tail end of the URL you see in your browser when looking at a workflow run.
You can also pass in ``wait=True`` to the :method:`~flytekit.remote.FlyteRemote.execute` method to synchronously wait
for the execution to complete before returning the execution object:

.. code-block:: python

from flytekit.common.workflow_execution import SdkWorkflowExecution
execution = remote.execute(flyte_entity, inputs={...}, wait=True)

********************
Syncing Remote State
********************

Use the :method:`~flytekit.remote.FlyteRemote.sync` method to sync the entity object's state with the remote state

.. code-block:: python

synced_execution = remote.sync(execution)


e = SdkWorkflowExecution.fetch('project_name', 'development', 'execution_name')
e.sync()
****************************
Inspecting Execution Objects
****************************

As a workflow is made up of nodes (each of which can contain a task, a subworkflow, or a launch plan), a workflow execution is made up of node executions (each of which can contain a task execution, a subworkflow execution, or a launch plan execution).
At any time you can inspect the inputs, outputs, completion status, error status, and other aspects of a workflow
execution object. See the :ref:`remote execution objects <remote-flyte-execution-objects>` reference for a list
of all the available attributes.
39 changes: 39 additions & 0 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,45 @@ This section of the documentation provides more detailed descriptions of the hig
API reference for specific usage details of python functions, classes, and decorators that you import to specify tasks,
build workflows, and extend ``flytekit``.

Installation
============

.. code-block::

pip install flytekit

For developer environment setup instructions, see the :ref:`contributor guide <contributing>`.


Quickstart
==========

.. code-block:: python

from flytekit import task, workflow

@task
def sum(x: int, y: int) -> int:
return x + y

@task
def square(z: int) -> int:
return z * z

@workflow
def my_workflow(x: int, y: int) -> int:
return sum(x=square(z=x), y=square(z=y))

print(f"my_workflow output: {my_workflow(x=1, y=2)}")


Expected output:

.. code-block::

my_workflow output: 5


.. toctree::
:maxdepth: 1
:hidden:
Expand Down
56 changes: 42 additions & 14 deletions flytekit/remote/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@

.. code-block:: python

# create a remote object from environment variables
remote = FlyteRemote.from_environment()
# create a remote object from flyte config and environment variables
remote = FlyteRemote.from_config()

# fetch a workflow from the flyte backend
flyte_workflow = remote.fetch_workflow(name="my_workflow", version="v1")
Expand All @@ -22,31 +22,59 @@
# inspect the execution's outputs
print(workflow_execution.outputs)

.. _remote-entrypoint:

Entrypoint
==========

.. autosummary::
:template: custom.rst
:toctree: generated/
:nosignatures:

~remote.FlyteRemote

.. _remote-flyte-entities:

Entities
========

.. autosummary::
:template: custom.rst
:toctree: generated/
:nosignatures:

~tasks.task.FlyteTask
~workflow.FlyteWorkflow
~launch_plan.FlyteLaunchPlan

.. _remote-flyte-entity-components:

Entity Components
=================

.. autosummary::
:template: custom.rst
:toctree: generated/
:nosignatures:

~nodes.FlyteNode
~component_nodes.FlyteTaskNode
~component_nodes.FlyteWorkflowNode

FlyteRemote
.. _remote-flyte-execution-objects:

Flyte Entities
==============
Execution Objects
=================

.. autosummary::
:template: custom.rst
:toctree: generated/
:nosignatures:

FlyteTask
FlyteWorkflow
FlyteLaunchPlan
FlyteNode
FlyteTaskNode
FlyteWorkflowNode
FlyteWorkflowExecution
FlyteTaskExecution
FlyteNodeExecution
~workflow_execution.FlyteWorkflowExecution
~tasks.executions.FlyteTaskExecution
~nodes.FlyteNodeExecution

"""

Expand Down
4 changes: 4 additions & 0 deletions flytekit/remote/component_nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@


class FlyteTaskNode(_workflow_model.TaskNode):
"""A class encapsulating a task that a Flyte node needs to execute."""

def __init__(self, flyte_task: "flytekit.remote.tasks.task.FlyteTask"):
self._flyte_task = flyte_task
super(FlyteTaskNode, self).__init__(None)
Expand Down Expand Up @@ -56,6 +58,8 @@ def promote_from_model(


class FlyteWorkflowNode(_workflow_model.WorkflowNode):
"""A class encapsulating a workflow that a Flyte node needs to execute."""

def __init__(
self,
flyte_workflow: "flytekit.remote.workflow.FlyteWorkflow" = None,
Expand Down
2 changes: 2 additions & 0 deletions flytekit/remote/launch_plan.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@


class FlyteLaunchPlan(_launch_plan_models.LaunchPlanSpec):
"""A class encapsulating a remote Flyte launch plan."""

def __init__(self, *args, **kwargs):
super(FlyteLaunchPlan, self).__init__(*args, **kwargs)
# Set all the attributes we expect this class to have
Expand Down
4 changes: 4 additions & 0 deletions flytekit/remote/nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@


class FlyteNode(_hash_mixin.HashOnReferenceMixin, _workflow_model.Node):
"""A class encapsulating a remote Flyte node."""

def __init__(
self,
id,
Expand Down Expand Up @@ -150,6 +152,8 @@ def __repr__(self) -> str:


class FlyteNodeExecution(_node_execution_models.NodeExecution, _artifact_mixin.ExecutionArtifact):
"""A class encapsulating a node execution being run on a Flyte remote backend."""

def __init__(self, *args, **kwargs):
super(FlyteNodeExecution, self).__init__(*args, **kwargs)
self._task_executions = None
Expand Down
Loading