Skip to content

Commit 15e91b1

Browse files
gkcivisCopilotjacksonlee-civis
authored
[CIVIS-11467] civis-python: add support to civis.utils.run_template for passing remote_host_id and credential_id arguments (#526)
* Co-pilot implementation. * Add unittests for the run_template changes. * Updating CHANGELOG. * Add a _warn_or_raise_for_JSONValue function and update logging in unit tests accordingly. Handle case where JSONValue and return_as conflict. * Apply suggestions from copilot code review - remove unneeded .format() and cleanup whitespace Co-authored-by: Jackson Lee <86482098+jacksonlee-civis@users.noreply.github.com> * Add deprecated note in CHANGELOG. Co-authored-by: Jackson Lee <86482098+jacksonlee-civis@users.noreply.github.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Jackson Lee <86482098+jacksonlee-civis@users.noreply.github.com>
1 parent d829708 commit 15e91b1

File tree

3 files changed

+234
-20
lines changed

3 files changed

+234
-20
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,13 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
99
### Added
1010

1111
### Changed
12+
- Updated `civis.utils.run_template` to accept kwargs. (#526)
1213
- Updated retries for Civis API calls under `civis.APIClient`
1314
to wait at least the `Retry-After` duration from the response header,
1415
instead of potentially less than that. (#525)
1516

1617
### Deprecated
18+
- Deprecated the JSONValue parameter of `civis.utils.run_template`. (#526)
1719

1820
### Removed
1921

src/civis/utils/_jobs.py

Lines changed: 85 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,58 @@
22
import operator
33
import time
44
from datetime import datetime
5+
import warnings
56

67
from civis import APIClient
78
from civis.futures import CivisFuture
9+
from civis._deprecation import DeprecatedKwargDefault
810

911
log = logging.getLogger(__name__)
1012

1113
_FOLLOW_POLL_INTERVAL_SEC = 5
1214
_LOG_REFETCH_CUTOFF_SECONDS = 300
1315
_LOG_REFETCH_COUNT = 100
1416
_LOGS_PER_QUERY = 250
17+
_RETURN_AS_OPTIONS = frozenset(("files", "JSONValue", "future"))
18+
19+
20+
def _warn_or_raise_for_JSONValue(JSONValue, return_as):
21+
"""Warn about use of deprecated JSONValue parameter in run_template.
22+
When it's time to remove JSONValue at civis-python v3.0.0,
23+
remove this helper and all usage of JSONValue.
24+
"""
25+
if not isinstance(JSONValue, DeprecatedKwargDefault):
26+
warn_msg = (
27+
"As of civis-python v2.8.0, civis.utils.run_template can return three "
28+
"types of values, so 'JSONValue' is deprecated "
29+
"and will be removed in civis-python v3.0.0 "
30+
"(no release timeline yet). "
31+
"While the arg 'JSONValue' still works for now, you're strongly encouraged "
32+
"to update your code to use the new keyword argument 'return_as' instead "
33+
"and stop settting 'JSONValue'. "
34+
)
35+
if JSONValue:
36+
warn_msg += (
37+
"To return the JSONValue output of the custom script run, "
38+
'set return_as="JSONValue".'
39+
)
40+
conflict_msg = (
41+
"Update your code so that the 'JSONValue' argument is no longer set, "
42+
"and set 'return_as' to one of {'files', 'JSONValue', 'future'}. "
43+
"Note that the default return_as value is 'files' as of "
44+
"civis-python v2.8.0, but will be 'future' in civis-python v3.0.0."
45+
)
46+
if (JSONValue and return_as != "JSONValue") or (
47+
not JSONValue and return_as == "JSONValue"
48+
):
49+
raise ValueError(
50+
"Conflicting argument values: "
51+
f"JSONValue={bool(JSONValue)} but return_as={return_as!r}. "
52+
+ conflict_msg
53+
)
54+
else:
55+
warnings.warn(warn_msg.strip(), FutureWarning, stacklevel=3)
56+
return return_as
1557

1658

1759
def run_job(job_id, client=None, polling_interval=None):
@@ -45,7 +87,14 @@ def run_job(job_id, client=None, polling_interval=None):
4587
)
4688

4789

48-
def run_template(id, arguments, JSONValue=False, client=None):
90+
def run_template(
91+
id,
92+
arguments,
93+
JSONValue=DeprecatedKwargDefault(),
94+
client=None,
95+
return_as="files",
96+
**kwargs,
97+
):
4998
"""Run a template and return the results.
5099
51100
Parameters
@@ -58,37 +107,65 @@ def run_template(id, arguments, JSONValue=False, client=None):
58107
If True, will return the JSON output of the template.
59108
If False, will return the file ids associated with the
60109
output results.
110+
111+
.. deprecated:: 2.8.0
112+
``JSONValue`` will be removed at civis-python v3.0.0.
113+
Please use ``return_as`` instead.
114+
return_as: str, optional
115+
Determines the return type. Options:
116+
- "files": returns file ids associated with output results (default for <v3.0.0)
117+
- "JSONValue": returns the JSON output of the template
118+
- "future": returns the CivisFuture object for the run
119+
At civis-python v3.0.0, the default will change to "future".
61120
client: :class:`civis.APIClient`, optional
62121
If not provided, an :class:`civis.APIClient` object will be
63122
created from the :envvar:`CIVIS_API_KEY`.
123+
**kwargs: dict
124+
Additional keyword arguments to be passed to post_custom.
64125
65126
Returns
66127
-------
67-
output: dict
68-
If JSONValue = False, dictionary of file ids with the keys
128+
output: dict or CivisFuture
129+
If return_as = "files", dictionary of file ids with the keys
69130
being their output names.
70-
If JSONValue = True, JSON dict containing the results of the
131+
If return_as = "JSONValue", JSON dict containing the results of the
71132
template run. Expects only a single JSON result. Will return
72133
nothing if either there is no JSON result or there is more
73134
than 1 JSON result.
135+
If return_as = "future", returns the CivisFuture object for the run.
74136
75137
Examples
76138
--------
77139
>>> # Run template to return file_ids
78140
>>> run_template(my_template_id, arguments=my_dict_of_args)
79141
{'output': 1234567}
80142
>>> # Run template to return JSON output
81-
>>> run_template(my_template_id, arguments=my_dict_of_args, JSONValue=True)
143+
>>> run_template(my_template_id, arguments=my_dict_of_args, return_as="JSONValue")
82144
{'result1': 'aaa', 'result2': 123}
145+
>>> # Run template to return CivisFuture
146+
>>> run_template(my_template_id, arguments=my_dict_of_args, return_as="future")
147+
<CivisFuture object>
148+
>>> # Run template with kwargs
149+
>>> run_template(my_template_id, arguments=my_dict_of_args, remote_host_id=1,
150+
credential_id=2)
151+
{'output': 1234567}
83152
"""
153+
if return_as not in _RETURN_AS_OPTIONS:
154+
raise ValueError(f"unsupported return_as option: {return_as}")
155+
# Check if JSONValue conflicts with return_as, warn or raise accordingly
156+
return_as = _warn_or_raise_for_JSONValue(JSONValue, return_as)
84157
if client is None:
85158
client = APIClient()
86-
job = client.scripts.post_custom(id, arguments=arguments)
159+
job = client.scripts.post_custom(id, arguments=arguments, **kwargs)
87160
run = client.scripts.post_custom_runs(job.id)
88161
fut = CivisFuture(client.scripts.get_custom_runs, (job.id, run.id), client=client)
162+
163+
if return_as == "future":
164+
return fut
165+
89166
fut.result()
90167
outputs = client.scripts.list_custom_runs_outputs(job.id, run.id)
91-
if JSONValue:
168+
if return_as == "JSONValue":
92169
json_output = [o.value for o in outputs if o.object_type == "JSONValue"]
93170
if len(json_output) == 0:
94171
log.warning("No JSON output for template {}".format(id))
@@ -102,6 +179,7 @@ def run_template(id, arguments, JSONValue=False, client=None):
102179
# an expected Response object.
103180
return json_output[0].json()
104181
else:
182+
# Expecting return_as == "files"
105183
file_ids = {o.name: o.object_id for o in outputs}
106184
return file_ids
107185

0 commit comments

Comments
 (0)