Skip to content

Rapidata order

RapidataOrder #

RapidataOrder(
    name: str,
    order_id: str,
    openapi_service: OpenAPIService,
)

An instance of a Rapidata order.

Used to interact with a specific order in the Rapidata system, such as starting, pausing, and retrieving results.

Parameters:

Name Type Description Default
name str

The name of the order.

required
order_id str

The ID of the order.

required
openapi_service OpenAPIService

The OpenAPIService instance for API interaction.

required
Source code in src/rapidata/rapidata_client/order/rapidata_order.py
def __init__(
    self,
    name: str,
    order_id: str,
    openapi_service: OpenAPIService,
):
    self.id = order_id
    self.name = name
    self.__created_at: datetime | None = None
    self._openapi_service = openapi_service
    self.__workflow_id: str = ""
    self.__campaign_id: str = ""
    self.__pipeline_id: str = ""
    self.order_details_page = (
        f"https://app.{self._openapi_service.environment}/order/detail/{self.id}"
    )
    logger.debug("RapidataOrder initialized")

created_at property #

created_at: datetime

Returns the creation date of the order.

run #

run(
    after: RapidataOrder | str | None = None,
) -> RapidataOrder

Runs the order to start collecting responses. Args: after: The order to set as the preceding order. So order will only start collecting responses after the preceding order is completed. Can be a RapidataOrder instance, a string order ID, or None. If None, the order will start collecting responses immediately. Returns: The order itself.

Source code in src/rapidata/rapidata_client/order/rapidata_order.py
def run(self, after: RapidataOrder | str | None = None) -> RapidataOrder:
    """Runs the order to start collecting responses.
    Args:
        after: The order to set as the preceding order. So order will only start collecting responses after the preceding order is completed.
            Can be a RapidataOrder instance, a string order ID, or None.
            If None, the order will start collecting responses immediately.
    Returns:
        The order itself.
    """
    with tracer.start_as_current_span("RapidataOrder.run"):
        if after:
            logger.info(
                "Setting preceding order for order '%s' to '%s'", self, after
            )
            from rapidata.api_client.models.update_order_endpoint_input import (
                UpdateOrderEndpointInput,
            )

            self._openapi_service.order.order_api.order_order_id_patch(
                self.id,
                UpdateOrderEndpointInput(
                    precedingOrderId=(
                        after.id if isinstance(after, RapidataOrder) else after
                    )
                ),
            )

        logger.info("Starting order '%s'", self)
        from rapidata.api_client.models.submit_order_endpoint_input import (
            SubmitOrderEndpointInput,
        )

        self._openapi_service.order.order_api.order_order_id_submit_post(
            self.id, SubmitOrderEndpointInput(ignoreFailedDatapoints=True)
        )
        logger.debug("Order '%s' has been started.", self)
        managed_print(
            f"Order '{self.name}' is now viewable under: {self.order_details_page}"
        )
        return self

pause #

pause() -> None

Pauses the order.

Source code in src/rapidata/rapidata_client/order/rapidata_order.py
def pause(self) -> None:
    """Pauses the order."""
    with tracer.start_as_current_span("RapidataOrder.pause"):
        logger.info("Pausing order '%s'", self)
        self._openapi_service.order.order_api.order_order_id_pause_post(self.id)
        logger.debug("Order '%s' has been paused.", self)
        managed_print(f"Order '{self}' has been paused.")

unpause #

unpause() -> None

Unpauses/resumes the order.

Source code in src/rapidata/rapidata_client/order/rapidata_order.py
def unpause(self) -> None:
    """Unpauses/resumes the order."""
    with tracer.start_as_current_span("RapidataOrder.unpause"):
        logger.info("Unpausing order '%s'", self)
        self._openapi_service.order.order_api.order_order_id_resume_post(self.id)
        logger.debug("Order '%s' has been unpaused.", self)
        managed_print(f"Order '{self}' has been unpaused.")

delete #

delete() -> None

Deletes the order.

Source code in src/rapidata/rapidata_client/order/rapidata_order.py
def delete(self) -> None:
    """Deletes the order."""
    with tracer.start_as_current_span("RapidataOrder.delete"):
        logger.info("Deleting order '%s'", self)
        self._openapi_service.order.order_api.order_order_id_delete(self.id)
        logger.debug("Order '%s' has been deleted.", self)
        managed_print(f"Order '{self}' has been deleted.")

get_status #

get_status() -> str

Gets the status of the order.

States

Created: The order has been created but not started yet.

Preview: The order has been set up and ready but not collecting responses yet.

Submitted: The order has been submitted and is being reviewed.

ManualReview: The order is in manual review - something went wrong with the automatic approval.

Processing: The order is actively being processed.

Paused: The order has been paused.

Completed: The order has been completed.

Failed: The order has failed.

StaleResults: The order completed but its result file is no longer valid; calling get_results regenerates it automatically.

Source code in src/rapidata/rapidata_client/order/rapidata_order.py
def get_status(self) -> str:
    """
    Gets the status of the order.

    States:
        Created: The order has been created but not started yet.\n
        Preview: The order has been set up and ready but not collecting responses yet.\n
        Submitted: The order has been submitted and is being reviewed.\n
        ManualReview: The order is in manual review - something went wrong with the automatic approval.\n
        Processing: The order is actively being processed.\n
        Paused: The order has been paused.\n
        Completed: The order has been completed.\n
        Failed: The order has failed.\n
        StaleResults: The order completed but its result file is no longer valid; calling get_results regenerates it automatically.
    """
    with tracer.start_as_current_span("RapidataOrder.get_status"):
        return self._openapi_service.order.order_api.order_order_id_get(
            self.id
        ).state

display_progress_bar #

display_progress_bar(refresh_rate: int = 5) -> None

Displays a progress bar for the order processing using tqdm.

Parameters:

Name Type Description Default
refresh_rate int

How often to refresh the progress bar, in seconds.

5
Source code in src/rapidata/rapidata_client/order/rapidata_order.py
def display_progress_bar(self, refresh_rate: int = 5) -> None:
    """
    Displays a progress bar for the order processing using tqdm.

    Args:
        refresh_rate: How often to refresh the progress bar, in seconds.
    """
    from rapidata.api_client.models.order_state import OrderState

    if refresh_rate < 1:
        raise ValueError("refresh_rate must be at least 1")

    if self.get_status() == OrderState.CREATED:
        raise Exception("Order has not been started yet. Please start it first.")

    # Wait for submission review
    while self.get_status() == OrderState.SUBMITTED:
        managed_print(
            f"Order '{self}' is submitted and being reviewed. Standby...", end="\r"
        )
        sleep(1)

    if self.get_status() == OrderState.MANUALREVIEW:
        raise Exception(
            f"Order '{self}' is in manual review. It might take some time to start. "
            f"To speed up the process, contact support (info@rapidata.ai).\n"
            f"Once started, run this method again to display the progress bar."
        )

    # Terminal states that should break the progress-bar loop
    # regardless of completion_percentage. Without this check a
    # Failed or Paused order would pin the caller's thread forever.
    terminal_states = {
        OrderState.COMPLETED,
        OrderState.PAUSED,
        OrderState.FAILED,
        OrderState.MANUALREVIEW,
    }

    with tqdm(
        total=100,
        desc="Processing order",
        unit="%",
        bar_format="{desc}: {percentage:3.0f}%|{bar}| completed [{elapsed}<{remaining}, {rate_fmt}]",
        disable=rapidata_config.logging.silent_mode,
    ) as pbar:
        last_percentage = 0
        while True:
            current_percentage = (
                self.__get_workflow_progress().completion_percentage
            )

            if current_percentage > last_percentage:
                pbar.update(current_percentage - last_percentage)
                last_percentage = current_percentage

            if current_percentage >= 100:
                break

            current_state = self.get_status()
            if current_state in terminal_states:
                logger.info(
                    "Progress bar exiting early: order is in state %s",
                    current_state,
                )
                break

            sleep(refresh_rate)

get_results #

get_results(
    preliminary_results: bool = False,
) -> RapidataResults

Gets the results of the order. If the order is still processing, this method will block until the order is completed and then return the results. If the order's results have gone stale, regeneration is triggered automatically and this method blocks until the fresh results are ready.

Parameters:

Name Type Description Default
preliminary_results bool

If True, returns the preliminary results of the order. Defaults to False. Note that preliminary results are not final and may not contain all the datapoints & responses. Only the ones that are already available.

False
Info

Currently the SDK does not support streaming. The preliminary results are simply a snapshot of the results at the time of the request.

Source code in src/rapidata/rapidata_client/order/rapidata_order.py
def get_results(self, preliminary_results: bool = False) -> RapidataResults:
    """
    Gets the results of the order.
    If the order is still processing, this method will block until the order is completed and then return the results.
    If the order's results have gone stale, regeneration is triggered automatically and this method blocks until the fresh results are ready.

    Args:
        preliminary_results: If True, returns the preliminary results of the order. Defaults to False.
            Note that preliminary results are not final and may not contain all the datapoints & responses. Only the ones that are already available.

    Info:
        Currently the SDK does not support streaming. The preliminary results are simply a snapshot of the results at the time of the request.
    """
    with tracer.start_as_current_span("RapidataOrder.get_results"):
        from rapidata.api_client.models.order_state import OrderState
        from rapidata.api_client.exceptions import ApiException
        from rapidata.rapidata_client.results.rapidata_results import (
            RapidataResults,
        )

        logger.info("Getting results for order '%s'...", self)

        if preliminary_results and self.get_status() not in [OrderState.COMPLETED]:
            return self._get_preliminary_results()

        if preliminary_results and self.get_status() == OrderState.COMPLETED:
            managed_print("Order is already completed. Returning final results.")

        # Stale results have no downloadable file until the pipeline is re-run;
        # trigger that automatically before waiting for the re-completion.
        if self.get_status() == OrderState.STALERESULTS:
            self._regenerate_results()

        self._wait_for_state(
            target_states=[
                OrderState.COMPLETED,
                OrderState.PAUSED,
                OrderState.MANUALREVIEW,
                OrderState.FAILED,
            ],
            status_message="Order '%s' is in state %s, waiting for completion...",
        )

        try:
            results = self._openapi_service.order.order_api.order_order_id_download_results_get(
                order_id=self.id
            )
            return RapidataResults(json.loads(results))
        except (ApiException, json.JSONDecodeError) as e:
            raise Exception(f"Failed to get order results: {str(e)}") from e

view #

view() -> None

Opens the order details page in the browser.

Source code in src/rapidata/rapidata_client/order/rapidata_order.py
def view(self) -> None:
    """Opens the order details page in the browser."""
    logger.info("Opening order details page in browser...")
    if not webbrowser.open(self.order_details_page):
        encoded_url = urllib.parse.quote(
            self.order_details_page, safe="%/:=&?~#+!$,;'@()*[]"
        )
        managed_print(
            Fore.RED
            + f"Please open this URL in your browser: '{encoded_url}'"
            + Fore.RESET
        )

preview #

preview() -> None

Opens a preview of the order in the browser.

Source code in src/rapidata/rapidata_client/order/rapidata_order.py
def preview(self) -> None:
    """Opens a preview of the order in the browser."""
    from rapidata.api_client.models.order_state import OrderState
    from rapidata.api_client.models.preview_order_endpoint_input import (
        PreviewOrderEndpointInput,
    )

    logger.info("Opening order preview in browser...")

    if self.get_status() == OrderState.CREATED:
        logger.info("Order is still in state created. Setting it to preview.")
        self._openapi_service.order.order_api.order_order_id_preview_post(
            self.id, PreviewOrderEndpointInput(ignoreFailedDatapoints=True)
        )
        logger.info("Order is now in preview state.")

    campaign_id = self.__get_campaign_id()
    auth_url = f"https://app.{self._openapi_service.environment}/order/detail/{self.id}/preview?campaignId={campaign_id}"

    if not webbrowser.open(auth_url):
        encoded_url = urllib.parse.quote(auth_url, safe="%/:=&?~#+!$,;'@()*[]")
        managed_print(
            Fore.RED
            + f"Please open this URL in your browser: '{encoded_url}'"
            + Fore.RESET
        )