Skip to content

FutureOutputs

chemcloud.models

TaskStatus

Tasks status for a submitted compute job.

FutureOutputBase

Base class for FutureOutputs

Attributes:

Name Type Description
task_id str

The task_id for primary task submitted to ChemCloud. May correspond to a single task or group of tasks.

client Any

The _RequestsClient to use for http requests to ChemCloud.

result Optional[QCIOOutputsOrList]

Primary return value resulting from computation.

Caution

A FutureOutput should never be instantiated directly. CCClient.compute(...) will return one when you submit a computation.

status property

status: str

Check status of compute task.

Returns:

Type Description
str

Status of computation.

Note

Sets self.result if task is complete.

get

get(timeout: Optional[float] = None, interval: float = 1.0) -> Optional[QCIOOutputsOrList]

Block until a calculation is complete and return the result.

Parameters:

Name Type Description Default
timeout Optional[float]

The number of seconds to wait for a computation before raising a TimeOutError.

None
interval float

The amount of time to wait between calls to ChemCloud to check a computation's status.

1.0

Returns:

Type Description
Optional[QCIOOutputsOrList]

Resultant values from a computation.

Raises:

Type Description
TimeoutError

Raised if timeout interval exceeded.

Source code in chemcloud/models.py
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
def get(
    self,
    timeout: Optional[float] = None,  # in seconds
    interval: float = 1.0,
) -> Optional[QCIOOutputsOrList]:
    """Block until a calculation is complete and return the result.

    Parameters:
        timeout: The number of seconds to wait for a computation before raising a
            TimeOutError.
        interval: The amount of time to wait between calls to ChemCloud to
            check a computation's status.

    Returns:
        Resultant values from a computation.

    Exceptions:
        TimeoutError: Raised if timeout interval exceeded.
    """
    if self.result:
        return self.result

    start_time = time()

    # self._state check prevents 401 errors from ChemCloud when the job completed
    # but the server failed to return a result (e.g., due to .program_output not)
    # being set correctly by qcio/BigChem.
    # TODO: Make a clearer contract between Server and Client re: states. This got
    # a bit messy as I switched mimicking celery states to the more simplified setup
    # I have now. This can be simplified further.
    while not self.result and self._state not in {"COMPLETE", "FAILURE"}:
        # Calling self.status returns status and sets self.result if task complete
        self.status
        if timeout:
            if (time() - start_time) > timeout:
                raise TimeoutError(
                    f"Your timeout limit of {timeout} seconds was exceeded"
                )
        sleep(interval)

    return self.result

FutureOutput

Single computation result

FutureOutputGroup

Group computation result

validate_id classmethod

validate_id(val)

Prepend id with GROUP_ID_PREFIX.

NOTE

This makes instantiating FutureOutputGroups from saved ids easier because they are differentiated from FutureOutput ids.

Source code in chemcloud/models.py
130
131
132
133
134
135
136
137
138
139
140
141
@field_validator("task_id")
@classmethod
def validate_id(cls, val):
    """Prepend id with GROUP_ID_PREFIX.

    NOTE:
        This makes instantiating FutureOutputGroups from saved ids easier because
        they are differentiated from FutureOutput ids.
    """
    if not val.startswith(GROUP_ID_PREFIX):
        val = GROUP_ID_PREFIX + val
    return val

to_file

to_file(future_results: Union[FutureOutputBase, List[FutureOutputBase]], path: Union[str, Path], *, append: bool = False) -> None

Write FutureOutputs to disk for later retrieval

Parameters:

Name Type Description Default
future_results Union[FutureOutputBase, List[FutureOutputBase]]

List of or single FutureOutput or FutureOutputGroup

required
path Union[str, Path]

File path to results file

required
append bool

Append results to an existing file if True, else create new file

False
Source code in chemcloud/models.py
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
def to_file(
    future_results: Union[FutureOutputBase, List[FutureOutputBase]],
    path: Union[str, Path],
    *,
    append: bool = False,
) -> None:
    """Write FutureOutputs to disk for later retrieval

    Params:
        future_results: List of or single FutureOutput or FutureOutputGroup
        path: File path to results file
        append: Append results to an existing file if True, else create new file
    """
    if not isinstance(future_results, list):
        future_results = [future_results]

    with open(path, f"{'a' if append else 'w'}") as f:
        f.writelines([f"{fr.task_id}\n" for fr in future_results])

from_file

from_file(path: Union[str, Path], client: Any) -> List[Union[FutureOutput, FutureOutputGroup]]

Instantiate FutureOutputs or FutureOutputGroups from file of result ids

Parameters:

Name Type Description Default
path Union[str, Path]

Path to file containing the ids

required
client Any

Instantiated CCClient object

required
Source code in chemcloud/models.py
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
def from_file(
    path: Union[str, Path],
    client: Any,
) -> List[Union[FutureOutput, FutureOutputGroup]]:
    """Instantiate FutureOutputs or FutureOutputGroups from file of result ids

    Params:
        path: Path to file containing the ids
        client: Instantiated CCClient object
    """
    frs: List[Union[FutureOutput, FutureOutputGroup]] = []
    with open(path) as f:
        for id in f.readlines():
            id = id.strip()
            model: Union[Type[FutureOutput], Type[FutureOutputGroup]]
            if id.startswith(GROUP_ID_PREFIX):
                model = FutureOutputGroup
            else:
                model = FutureOutput
            frs.append(model(task_id=id, client=client._client))

    assert len(frs) > 0, "No ids found in file!"
    return frs