Example #1
0
    def list(
        cls, public: bool = False, client: Optional[Client] = None
    ) -> Iterator["XYZ"]:
        """
        Get all XYZ objects created by this user.

        Parameters
        ----------
        public: bool, default False
            If ``True`` then return public (shared) XYZ objects created by this
            user. If ``False`` then return non-public XYZ objects created through
            the use of workflow map widgets.
        client: Optional[Client], default None
            Allows you to use a specific client instance with non-default
            auth and parameters

        Returns
        -------
        Iterator[XYZ]

        Example
        -------
        >>> from descarteslabs.workflows import XYZ
        >>> for xyz in XYZ.list(): # doctest: +SKIP
        ...     print(xyz.id) # doctest: +SKIP
        24d0e79c5c1e1f10a0b1177ef3974d7edefd5988291cf2c6
        """
        if client is None:
            client = get_global_grpc_client()

        iter = client.api["ListXYZ"](
            xyz_pb2.ListXYZRequest(public=public), timeout=client.STREAM_TIMEOUT
        )
        return map(lambda xyz: cls._from_proto(xyz, client=client), iter)
Example #2
0
def _tile_log_stream(
    xyz_id: str,
    session_id: str,
    start_datetime: datetime.datetime = None,
    level: int = None,
    client: Optional[Client] = None,
) -> Iterator[xyz_pb2.XYZLogRecord]:
    if client is None:
        client = get_global_grpc_client()

    if start_datetime is None:
        start_timestamp = 0
    else:
        start_timestamp = pb_datetime_to_milliseconds(start_datetime)

    if level is None:
        level = logging.DEBUG
    else:
        level = py_log_level_to_proto_log_level(level)

    msg = xyz_pb2.GetXYZSessionLogsRequest(
        session_id=session_id,
        xyz_id=xyz_id,
        start_timestamp=start_timestamp,
        level=level,
    )

    return client.api["GetXYZSessionLogs"](msg, timeout=client.STREAM_TIMEOUT)
Example #3
0
    def delete_id(id, client=None):
        """
        Delete the `XYZ` that has the provided ID. Only the user
        that created the `XYZ` can delete it.

        **Warning:** this cannot be undone!

        Parameters
        ----------
        id: str
            The ID of the `XYZ` that we wish to delete.
        client: `.workflows.client.Client`, optional
            Allows you to use a specific client instance with non-default
            auth and parameters.

        Example
        -------
        >>> from descarteslabs.workflows import XYZ
        >>> xyz_id = '24d0e79c5c1e1f10a0b1177ef3974d7edefd5988291cf2c6'
        >>> xyz = XYZ.get(xyz_id) # doctest: +SKIP
        >>> xyz # doctest: +SKIP
        <descarteslabs.workflows.models.xyz.XYZ object at 0x...>
        >>> XYZ.delete_id(xyz_id) # doctest: +SKIP
        >>> XYZ.get(xyz_id) # doctest: +SKIP
        ...
        NotFound: 404 XYZ '24d0e79c5c1e1f10a0b1177ef3974d7edefd5988291cf2c6' does not exist.
        """
        if client is None:
            client = get_global_grpc_client()

        client.api["DeleteXYZ"](
            xyz_pb2.DeleteXYZRequest(xyz_id=id),
            timeout=client.DEFAULT_TIMEOUT,
        )
Example #4
0
    def delete_id(id, client=None):
        """
        Delete the `Workflow` that has the provided ID, and every `VersionedGraft` it contains.

        **Warning:** this cannot be undone!

        Parameters
        ----------
        id: str
            The ID of the `Workflow` that we wish to delete.
        client: `.workflows.client.Client`, optional
            Allows you to use a specific client instance with non-default
            auth and parameters.

        Example
        -------
        >>> import descarteslabs.workflows as wf
        >>> workflow = wf.Workflow.get("[email protected]:cool_thing_wf") # doctest: +SKIP
        >>> wf.Workflow.delete_id(workflow.id) # doctest: +SKIP
        """
        if client is None:
            client = get_global_grpc_client()

        client.api["DeleteWorkflow"](
            workflow_pb2.DeleteWorkflowRequest(id=id),
            timeout=client.DEFAULT_TIMEOUT,
        )
Example #5
0
    def get(cls, xyz_id: str, client: Optional[Client] = None) -> "XYZ":
        """
        Get an existing XYZ by id.

        Parameters
        ----------
        id: str
            The unique id of a `XZY` object
        client: Optional[Client], default None
            Allows you to use a specific client instance with non-default
            auth and parameters

        Returns
        -------
        XYZ

        Example
        -------
        >>> from descarteslabs.workflows import XYZ
        >>> xyz = XYZ.get('24d0e79c5c1e1f10a0b1177ef3974d7edefd5988291cf2c6') # doctest: +SKIP
        >>> xyz # doctest: +SKIP
        <descarteslabs.workflows.models.xyz.XYZ object at 0x...>
        """
        if client is None:
            client = get_global_grpc_client()

        message = client.api["GetXYZ"](
            xyz_pb2.GetXYZRequest(xyz_id=xyz_id), timeout=client.DEFAULT_TIMEOUT
        )
        return cls._from_proto(message, client=client)
    def _from_proto(cls,
                    message: MT,
                    client: Optional[Client] = None) -> "PublishedGraft":
        """
        Low-level constructor for a `PublishedGraft` object from a Protobuf message.

        Do not use this method directly; use `__init__` or `get` instead.

        Parameters
        ----------
        proto_message
            Protobuf message for the `PublishedGraft`
        client
            Allows you to use a specific client instance with non-default
            auth and parameters

        Returns
        -------
        PublishedGraft
        """

        obj = cls.__new__(cls)  # bypass __init__

        if client is None:
            client = get_global_grpc_client()

        obj._client = client
        obj._message = message
        obj._object = None
        obj._params = None

        return obj
Example #7
0
    def get(cls, workflow_id, version, client=None):
        """
        Get a specific `VersionedGraft` of a `Workflow`.

        Parameters
        ----------
        workflow_id: str
            The ID of the `Workflow`.
        version: str
            The version of the `Workflow` that you wish to fetch.
        client: `.workflows.client.Client`, optional
            Allows you to use a specific client instance with non-default
            auth and parameters.

        Returns
        -------
        VersionedGraft
        """
        if client is None:
            client = get_global_grpc_client()

        req = workflow_pb2.GetVersionRequest(id=workflow_id, version=version)

        versioned_graft_message = client.api["GetVersion"](
            req, timeout=client.DEFAULT_TIMEOUT)

        return cls._from_proto(versioned_graft_message)
Example #8
0
def wmts_url(tile_matrix_sets=None, dimensions=None, client=None) -> str:
    """
    Get the WMTS endpoint which gives access to all workflows accessible to this user.

    Parameters
    ----------
    tile_matrix_sets: str or list, optional
        Desired tile matrix sets. Defaults to EPSG:3857.
    dimensions: bool, optional
        If True, then provide dimensions definitions to WMTS. If
        False, then generate a layer for each possible dimensions
        attribute combination. If not specified, the WMTS service itself
        will determine how to handle dimensions (currently it does
        not provide dimensions definitions).
    client: `.workflows.client.Client`, optional
        Allows you to use a specific client instance with non-default
        auth and parameters.

    Returns
    -------
    wmts_url: str
        The URL for the WMTS service endpoint corresponding to this channel.

    Example
    -------
    >>> import descarteslabs.workflows as wf
    >>> wf.wmts_url() # doctest: +SKIP
    'https://workflows.prod.descarteslabs.com/master/wmts/workflow/1.0.0/WMTSCapabilities.xml'
    """
    if client is None:
        client = get_global_grpc_client()

    response = client.api["GetWmtsUrlTemplate"](
        workflow_pb2.Empty(), timeout=client.DEFAULT_TIMEOUT
    )

    url_params = {}

    if tile_matrix_sets:
        url_params["tile_matrix_sets"] = tile_matrix_sets
    if dimensions is not None:
        url_params["dimensions"] = "true" if dimensions else "false"

    wmts_url = response.wmts_url_template
    if url_params:
        wmts_url = f"{wmts_url}?{urlencode(url_params, doseq=True)}"

    return wmts_url
Example #9
0
    def search(cls, email="", name="", tags=None, client=None):
        """
        Iterator over Workflows you have access to.

        All search options are logically ANDed together.

        Parameters
        ----------
        email: str, optional
            Restrict to Workflows belonging to this email address (exact match).
        name: str, optional
            Restrict to Workflow names that start with this string (prefix search).
            (The name follows the colon in a Workflow ID: ``[email protected]:this_is_the_name``.)
        tags: List[str], optional
            Restrict to Workflows that have _any_ of these tags.
        client: `.workflows.client.Client`, optional
            Allows you to use a specific client instance with non-default
            auth and parameters.

        Yields
        -----
        workflow: Workflow
            Workflow matching the search criteria

        Example
        -------
        >>> import descarteslabs.workflows as wf
        >>> for workflow in wf.Workflow.search():  # doctest: +SKIP
        ...     print(workflow.id)  # doctest: +SKIP
        [email protected]:my_workflow
        [email protected]:my_workflow
        [email protected]:my_other_workflow
        """
        if client is None:
            client = get_global_grpc_client()

        stream = client.api["SearchWorkflows"](
            workflow_pb2.SearchWorkflowsRequest(
                email=email, name_prefix=name, tags=tags
            ),
            timeout=client.DEFAULT_TIMEOUT,
        )

        for message in stream:
            yield cls._from_proto(message, client)
Example #10
0
    def delete_id(id, client=None):
        """
        Delete the `Workflow` that has the provided ID, and every `VersionedGraft` it contains.

        **Warning:** this cannot be undone!

        Parameters
        ----------
        id: str
            The ID of the `Workflow` that we wish to delete.
        client: `.workflows.client.Client`, optional
            Allows you to use a specific client instance with non-default
            auth and parameters.
        """
        if client is None:
            client = get_global_grpc_client()

        client.api["DeleteWorkflow"](
            workflow_pb2.DeleteWorkflowRequest(id=id),
            timeout=client.DEFAULT_TIMEOUT,
        )
Example #11
0
    def _from_proto(cls, proto_message, client=None):
        """
        Low-level constructor for a `Workflow` object from a protobuf message.

        Do not use this method directly; use `Workflow.__init__`
        or `Workflow.get` instead.

        Parameters
        ----------
        proto_message: workflow_pb2.Workflow message
            Protobuf message for the Workflow
        client: `.workflows.client.Client`, optional
            Allows you to use a specific client instance with non-default
            auth and parameters.
        """
        obj = cls.__new__(cls)  # bypass __init__

        if client is None:
            client = get_global_grpc_client()

        obj._message = proto_message
        obj._client = client
        return obj
Example #12
0
    def get(cls, id, client=None):
        """
        Get an existing `Workflow` by ID.

        Parameters
        ----------
        id: string
            The ID of the `Workflow` (like ``[email protected]:workflow_id``)
        client: `.workflows.client.Client`, optional
            Allows you to use a specific client instance with non-default
            auth and parameters.

        Returns
        -------
        Workflow

        Example
        -------
        >>> from descarteslabs.workflows import Workflow
        >>> workflow = Workflow.get('[email protected]:cool_addition_model') # doctest: +SKIP
        >>> workflow # doctest: +SKIP
        Workflow: "Bob's Super Cool Addition Model"
            - id: [email protected]:cool_addition_model
            - public: True
            - labels: {'project': 'arithmetic'}
            - tags: ['test', 'cool', 'deep learning', 'AI', 'digital twin']
            - versions: '0.0.1', '0.0.2'
            The result of 1 plus 1
        """
        if client is None:
            client = get_global_grpc_client()

        message = client.api["GetWorkflow"](
            workflow_pb2.GetWorkflowRequest(id=id),
            timeout=client.DEFAULT_TIMEOUT,
        )
        return cls._from_proto(message, client)
Example #13
0
 def __init__(self, xyz_id: str, client: Optional[Client] = None):
     self.xyz_id = xyz_id
     self.callbacks = []
     self._rendezvous = None
     self._thread = None
     self._client = client if client is not None else get_global_grpc_client()
    def __init__(
        self,
        proxy_object: Proxytype,
        viz_options: Optional[Sequence[VizOption]] = None,
        client: Optional[Client] = None,
    ):
        """
        Construct a PublishedGraft object from a proxy object.

        If the proxy object depends on any parameters (``proxy_object.params`` is not empty),
        it's first internally converted to a `.Function` that takes those parameters
        (using `.Function.from_object`).

        Parameters
        ----------
        proxy_object
            The proxy object to publish.
            If it depends on parameters, ``proxy_obj`` is first converted
            to a `.Function` that takes those parameters.
        viz_options: list, default None
            List of `~.models.VizOption` visualization option sets.
        client
            Allows you to use a specific client instance with non-default
            auth and parameters
        """
        if client is None:
            client = get_global_grpc_client()

        proxy_object = proxify(proxy_object)

        if len(proxy_object.params) > 0:
            # turn objects that depend on parameters into Functions;
            # use their current `.params` as the parameter annotations
            params = proxy_object.params
            proxy_object = Function.from_object(proxy_object)

        elif isinstance(proxy_object, Function):
            # generate parameter annotations from the arguments of the Function.
            try:
                # try to get parameter names directly from the graft---this will work
                # even for unnamed positional arguments in the typespec
                names = proxy_object.graft["parameters"]
            except KeyError:
                # but if it's not a function graft (likely a higher-order function returned
                # from another function), use the `__signature__` so positional-only arguments
                # still get reasonable-ish (if inaccurate) names.
                names = list(proxy_object.__signature__.parameters)

            params = tuple(
                parameter(name, type_)
                for name, type_ in zip(names, proxy_object.all_arg_types))

        else:
            params = ()

        typespec = serialize_typespec(type(proxy_object))
        graft = proxy_object.graft
        proto_params = serialize_params(params)

        message = self._message_type(
            serialized_graft=json.dumps(graft),
            channel=client._wf_channel,
            client_version=__version__,
            typespec=typespec,
            parameters=proto_params,
        )

        if viz_options:
            if not isinstance(viz_options, (list, tuple)):
                viz_options = [viz_options]
            message.viz_options.extend([v._message for v in viz_options])

        self._client = client
        self._object = proxy_object
        self._params = params
        self._message = message
Example #15
0
    def __init__(
        self,
        id,
        title="",
        description="",
        labels=None,
        tags=None,
        client=None,
    ):
        """
        Construct a `Workflow` object referencing a new or existing Workflow.

        Parameters
        ----------
        id: str
            ID for the new `Workflow`. This should be of the form ``"email:workflow_name"`` and should be
            globally unique. If this ID is not of the proper format, you will not be able to save the `Workflow`.
            Cannot be changed once set.
        title: str, default ""
            User-friendly title for the `Workflow`.
        description: str, default ""
            Long-form description of this `Workflow`. Markdown is supported.
        labels: dict, optional
            Key-value pair labels to add to the `Workflow`.
        tags: list, optional
            A list of strings of tags to add to the `Workflow`.
        client: `.workflows.client.Client`, optional
            Allows you to use a specific client instance with non-default
            auth and parameters.

        Returns
        -------
        Workflow

        Example
        -------
        >>> from descarteslabs.workflows import Workflow, Int
        >>> workflow = Workflow(
        ...     id="[email protected]:cool_addition_model",
        ...     title="Bob's Super Cool Addition Model",
        ...     description="The result of 1 plus 1",
        ...     labels={"project": "arithmetic"},
        ...     tags=["test", "cool", "deep learning", "AI", "digital twin"]) # doctest: +SKIP
        >>> workflow # doctest: +SKIP
        Workflow: "Bob's Super Cool Addition Model"
            - id: [email protected]:cool_addition_model
            - labels: {'project': 'arithmetic'}
            - tags: ['test', 'cool', 'deep learning', 'AI', 'digital twin']
            - versions: '0.0.1', '0.0.2'
            The result of 1 plus 1
        """
        if client is None:
            client = get_global_grpc_client()

        message = workflow_pb2.Workflow(
            id=id,
            title=title,
            description=textwrap.dedent(description),
            labels=labels,
            tags=tags,
        )

        self._message = message
        self._client = client