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)
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)
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, )
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, )
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
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)
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
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)
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, )
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
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)
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
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