wandb 0.17.0rc2__py3-none-win_amd64.whl → 0.17.2__py3-none-win_amd64.whl
Sign up to get free protection for your applications and to get access to all the features.
- wandb/__init__.py +4 -2
- wandb/apis/importers/internals/internal.py +0 -1
- wandb/apis/importers/wandb.py +12 -7
- wandb/apis/internal.py +0 -3
- wandb/apis/public/api.py +213 -79
- wandb/apis/public/artifacts.py +335 -100
- wandb/apis/public/files.py +9 -9
- wandb/apis/public/jobs.py +16 -4
- wandb/apis/public/projects.py +26 -28
- wandb/apis/public/query_generator.py +1 -1
- wandb/apis/public/runs.py +163 -65
- wandb/apis/public/sweeps.py +2 -2
- wandb/apis/reports/__init__.py +1 -7
- wandb/apis/reports/v1/__init__.py +5 -27
- wandb/apis/reports/v2/__init__.py +7 -19
- wandb/apis/workspaces/__init__.py +8 -0
- wandb/beta/workflows.py +8 -3
- wandb/bin/wandb-core +0 -0
- wandb/cli/cli.py +151 -59
- wandb/docker/__init__.py +1 -1
- wandb/errors/term.py +10 -2
- wandb/filesync/step_checksum.py +1 -4
- wandb/filesync/step_prepare.py +4 -24
- wandb/filesync/step_upload.py +5 -107
- wandb/filesync/upload_job.py +0 -76
- wandb/integration/gym/__init__.py +35 -15
- wandb/integration/openai/fine_tuning.py +21 -3
- wandb/integration/prodigy/prodigy.py +1 -1
- wandb/jupyter.py +16 -17
- wandb/old/summary.py +5 -0
- wandb/plot/pr_curve.py +2 -1
- wandb/plot/roc_curve.py +2 -1
- wandb/{plots → plot}/utils.py +13 -25
- wandb/proto/v3/wandb_internal_pb2.py +54 -54
- wandb/proto/v3/wandb_settings_pb2.py +2 -2
- wandb/proto/v3/wandb_telemetry_pb2.py +10 -10
- wandb/proto/v4/wandb_internal_pb2.py +54 -54
- wandb/proto/v4/wandb_settings_pb2.py +2 -2
- wandb/proto/v4/wandb_telemetry_pb2.py +10 -10
- wandb/proto/v5/wandb_base_pb2.py +30 -0
- wandb/proto/v5/wandb_internal_pb2.py +355 -0
- wandb/proto/v5/wandb_server_pb2.py +63 -0
- wandb/proto/v5/wandb_settings_pb2.py +45 -0
- wandb/proto/v5/wandb_telemetry_pb2.py +41 -0
- wandb/proto/wandb_base_pb2.py +2 -0
- wandb/proto/wandb_deprecated.py +9 -1
- wandb/proto/wandb_generate_deprecated.py +34 -0
- wandb/proto/{wandb_internal_codegen.py → wandb_generate_proto.py} +1 -35
- wandb/proto/wandb_internal_pb2.py +2 -0
- wandb/proto/wandb_server_pb2.py +2 -0
- wandb/proto/wandb_settings_pb2.py +2 -0
- wandb/proto/wandb_telemetry_pb2.py +2 -0
- wandb/sdk/artifacts/artifact.py +76 -23
- wandb/sdk/artifacts/artifact_manifest.py +1 -1
- wandb/sdk/artifacts/artifact_manifest_entry.py +6 -3
- wandb/sdk/artifacts/artifact_manifests/artifact_manifest_v1.py +1 -1
- wandb/sdk/artifacts/artifact_saver.py +1 -10
- wandb/sdk/artifacts/storage_handlers/local_file_handler.py +6 -2
- wandb/sdk/artifacts/storage_handlers/multi_handler.py +1 -1
- wandb/sdk/artifacts/storage_handlers/tracking_handler.py +6 -4
- wandb/sdk/artifacts/storage_policies/wandb_storage_policy.py +2 -42
- wandb/sdk/artifacts/storage_policy.py +1 -12
- wandb/sdk/data_types/_dtypes.py +5 -2
- wandb/sdk/data_types/html.py +1 -1
- wandb/sdk/data_types/image.py +1 -1
- wandb/sdk/data_types/object_3d.py +1 -1
- wandb/sdk/data_types/video.py +4 -2
- wandb/sdk/interface/interface.py +13 -0
- wandb/sdk/interface/interface_shared.py +1 -1
- wandb/sdk/internal/file_pusher.py +2 -5
- wandb/sdk/internal/file_stream.py +6 -19
- wandb/sdk/internal/internal_api.py +160 -138
- wandb/sdk/internal/job_builder.py +207 -135
- wandb/sdk/internal/progress.py +0 -28
- wandb/sdk/internal/sender.py +105 -42
- wandb/sdk/internal/settings_static.py +8 -1
- wandb/sdk/internal/system/assets/gpu.py +2 -0
- wandb/sdk/internal/system/assets/trainium.py +3 -3
- wandb/sdk/internal/system/system_info.py +4 -2
- wandb/sdk/internal/update.py +1 -1
- wandb/sdk/launch/__init__.py +9 -1
- wandb/sdk/launch/_launch.py +4 -24
- wandb/sdk/launch/_launch_add.py +1 -3
- wandb/sdk/launch/_project_spec.py +184 -224
- wandb/sdk/launch/agent/agent.py +58 -18
- wandb/sdk/launch/agent/config.py +0 -3
- wandb/sdk/launch/builder/abstract.py +67 -0
- wandb/sdk/launch/builder/build.py +165 -576
- wandb/sdk/launch/builder/context_manager.py +235 -0
- wandb/sdk/launch/builder/docker_builder.py +7 -23
- wandb/sdk/launch/builder/kaniko_builder.py +10 -23
- wandb/sdk/launch/builder/templates/dockerfile.py +92 -0
- wandb/sdk/launch/create_job.py +51 -45
- wandb/sdk/launch/environment/aws_environment.py +26 -1
- wandb/sdk/launch/inputs/files.py +148 -0
- wandb/sdk/launch/inputs/internal.py +224 -0
- wandb/sdk/launch/inputs/manage.py +95 -0
- wandb/sdk/launch/runner/abstract.py +2 -2
- wandb/sdk/launch/runner/kubernetes_monitor.py +45 -12
- wandb/sdk/launch/runner/kubernetes_runner.py +6 -8
- wandb/sdk/launch/runner/local_container.py +2 -3
- wandb/sdk/launch/runner/local_process.py +8 -29
- wandb/sdk/launch/runner/sagemaker_runner.py +20 -14
- wandb/sdk/launch/runner/vertex_runner.py +8 -7
- wandb/sdk/launch/sweeps/scheduler.py +2 -0
- wandb/sdk/launch/sweeps/utils.py +2 -2
- wandb/sdk/launch/utils.py +16 -138
- wandb/sdk/lib/_settings_toposort_generated.py +2 -5
- wandb/sdk/lib/apikey.py +4 -2
- wandb/sdk/lib/config_util.py +3 -3
- wandb/sdk/lib/proto_util.py +22 -1
- wandb/sdk/lib/redirect.py +1 -1
- wandb/sdk/service/service.py +2 -1
- wandb/sdk/service/streams.py +5 -5
- wandb/sdk/wandb_init.py +25 -59
- wandb/sdk/wandb_login.py +28 -25
- wandb/sdk/wandb_run.py +135 -70
- wandb/sdk/wandb_settings.py +33 -64
- wandb/sdk/wandb_watch.py +1 -1
- wandb/sklearn/plot/classifier.py +4 -6
- wandb/sync/sync.py +2 -2
- wandb/testing/relay.py +32 -17
- wandb/util.py +39 -37
- wandb/wandb_agent.py +3 -3
- wandb/wandb_controller.py +3 -2
- {wandb-0.17.0rc2.dist-info → wandb-0.17.2.dist-info}/METADATA +7 -9
- {wandb-0.17.0rc2.dist-info → wandb-0.17.2.dist-info}/RECORD +130 -152
- wandb/apis/reports/v1/_blocks.py +0 -1406
- wandb/apis/reports/v1/_helpers.py +0 -70
- wandb/apis/reports/v1/_panels.py +0 -1282
- wandb/apis/reports/v1/_templates.py +0 -478
- wandb/apis/reports/v1/blocks.py +0 -27
- wandb/apis/reports/v1/helpers.py +0 -2
- wandb/apis/reports/v1/mutations.py +0 -66
- wandb/apis/reports/v1/panels.py +0 -17
- wandb/apis/reports/v1/report.py +0 -268
- wandb/apis/reports/v1/runset.py +0 -144
- wandb/apis/reports/v1/templates.py +0 -7
- wandb/apis/reports/v1/util.py +0 -406
- wandb/apis/reports/v1/validators.py +0 -131
- wandb/apis/reports/v2/blocks.py +0 -25
- wandb/apis/reports/v2/expr_parsing.py +0 -257
- wandb/apis/reports/v2/gql.py +0 -68
- wandb/apis/reports/v2/interface.py +0 -1911
- wandb/apis/reports/v2/internal.py +0 -867
- wandb/apis/reports/v2/metrics.py +0 -6
- wandb/apis/reports/v2/panels.py +0 -15
- wandb/catboost/__init__.py +0 -9
- wandb/fastai/__init__.py +0 -9
- wandb/keras/__init__.py +0 -19
- wandb/lightgbm/__init__.py +0 -9
- wandb/plots/__init__.py +0 -6
- wandb/plots/explain_text.py +0 -36
- wandb/plots/heatmap.py +0 -81
- wandb/plots/named_entity.py +0 -43
- wandb/plots/part_of_speech.py +0 -50
- wandb/plots/plot_definitions.py +0 -768
- wandb/plots/precision_recall.py +0 -121
- wandb/plots/roc.py +0 -103
- wandb/sacred/__init__.py +0 -3
- wandb/xgboost/__init__.py +0 -9
- {wandb-0.17.0rc2.dist-info → wandb-0.17.2.dist-info}/WHEEL +0 -0
- {wandb-0.17.0rc2.dist-info → wandb-0.17.2.dist-info}/entry_points.txt +0 -0
- {wandb-0.17.0rc2.dist-info → wandb-0.17.2.dist-info}/licenses/LICENSE +0 -0
wandb/apis/reports/v1/report.py
DELETED
@@ -1,268 +0,0 @@
|
|
1
|
-
import base64
|
2
|
-
import inspect
|
3
|
-
import json
|
4
|
-
import re
|
5
|
-
import urllib
|
6
|
-
from copy import deepcopy
|
7
|
-
from typing import List as LList
|
8
|
-
|
9
|
-
from .... import __version__ as wandb_ver
|
10
|
-
from .... import termlog, termwarn
|
11
|
-
from ....sdk.lib import ipython
|
12
|
-
from ...public import Api as PublicApi
|
13
|
-
from ...public import RetryingClient
|
14
|
-
from ._blocks import P, PanelGrid, UnknownBlock, WeaveBlock, block_mapping, weave_blocks
|
15
|
-
from .mutations import UPSERT_VIEW, VIEW_REPORT
|
16
|
-
from .runset import Runset
|
17
|
-
from .util import Attr, Base, Block, coalesce, generate_name, nested_get, nested_set
|
18
|
-
from .validators import OneOf, TypeValidator
|
19
|
-
|
20
|
-
|
21
|
-
class Report(Base):
|
22
|
-
project: str = Attr(json_path="viewspec.project.name")
|
23
|
-
entity: str = Attr(json_path="viewspec.project.entityName")
|
24
|
-
title: str = Attr(json_path="viewspec.displayName")
|
25
|
-
description: str = Attr(json_path="viewspec.description")
|
26
|
-
width: str = Attr(
|
27
|
-
json_path="viewspec.spec.width",
|
28
|
-
validators=[OneOf(["readable", "fixed", "fluid"])],
|
29
|
-
)
|
30
|
-
blocks: list = Attr(
|
31
|
-
json_path="viewspec.spec.blocks",
|
32
|
-
validators=[TypeValidator(Block, how="keys")],
|
33
|
-
)
|
34
|
-
|
35
|
-
def __init__(
|
36
|
-
self,
|
37
|
-
project,
|
38
|
-
entity=None,
|
39
|
-
title="Untitled Report",
|
40
|
-
description="",
|
41
|
-
width="readable",
|
42
|
-
blocks=None,
|
43
|
-
_api=None,
|
44
|
-
*args,
|
45
|
-
**kwargs,
|
46
|
-
):
|
47
|
-
super().__init__(*args, **kwargs)
|
48
|
-
self._viewspec = self._default_viewspec()
|
49
|
-
self._orig_viewspec = deepcopy(self._viewspec)
|
50
|
-
self._api = PublicApi() if _api is None else _api
|
51
|
-
|
52
|
-
self.project = project
|
53
|
-
self.entity = coalesce(entity, self._api.default_entity, "")
|
54
|
-
self.title = title
|
55
|
-
self.description = description
|
56
|
-
self.width = width
|
57
|
-
self.blocks = coalesce(blocks, [])
|
58
|
-
|
59
|
-
@classmethod
|
60
|
-
def from_url(cls, url, api=None):
|
61
|
-
if api is None:
|
62
|
-
api = PublicApi()
|
63
|
-
report_id = cls._url_to_report_id(url)
|
64
|
-
r = api.client.execute(VIEW_REPORT, variable_values={"reportId": report_id})
|
65
|
-
viewspec = r["view"]
|
66
|
-
viewspec["spec"] = json.loads(viewspec["spec"])
|
67
|
-
return cls.from_json(viewspec)
|
68
|
-
|
69
|
-
@staticmethod
|
70
|
-
def _url_to_report_id(url):
|
71
|
-
path_msg = "Path must be `entity/project/reports/report_title--report_id`"
|
72
|
-
try:
|
73
|
-
report_path, *_ = url.split("?")
|
74
|
-
report_path = report_path.replace("---", "--")
|
75
|
-
|
76
|
-
if "--" not in report_path:
|
77
|
-
raise ValueError(path_msg)
|
78
|
-
|
79
|
-
*_, report_id = report_path.split("--")
|
80
|
-
if len(report_id) == 0:
|
81
|
-
raise ValueError("Invalid report id")
|
82
|
-
|
83
|
-
report_id = report_id.strip()
|
84
|
-
|
85
|
-
"""
|
86
|
-
Server does not generate IDs with correct padding, so decode with default validate=False.
|
87
|
-
Then re-encode it with correct padding.
|
88
|
-
https://stackoverflow.com/questions/2941995/python-ignore-incorrect-padding-error-when-base64-decoding
|
89
|
-
|
90
|
-
Corresponding core app logic that strips the padding in url
|
91
|
-
https://github.com/wandb/core/blob/b563437c1f3237ec35b1fb388ac14abbab7b4279/frontends/app/src/util/url/shared.ts#L33-L78
|
92
|
-
"""
|
93
|
-
report_id = base64.b64encode(base64.b64decode(report_id + "==")).decode(
|
94
|
-
"utf-8"
|
95
|
-
)
|
96
|
-
|
97
|
-
except ValueError as e:
|
98
|
-
raise ValueError(path_msg) from e
|
99
|
-
else:
|
100
|
-
return report_id
|
101
|
-
|
102
|
-
@blocks.getter
|
103
|
-
def blocks(self):
|
104
|
-
json_path = self._get_path("blocks")
|
105
|
-
block_specs = nested_get(self, json_path)
|
106
|
-
blocks = []
|
107
|
-
for bspec in block_specs:
|
108
|
-
cls = block_mapping.get(bspec["type"], UnknownBlock)
|
109
|
-
if cls is UnknownBlock:
|
110
|
-
termwarn(
|
111
|
-
inspect.cleandoc(
|
112
|
-
f"""
|
113
|
-
UNKNOWN BLOCK DETECTED
|
114
|
-
This can happen if we have added new blocks, but you are using an older version of the SDK.
|
115
|
-
If your report is loading normally, you can safely ignore this message (but we recommend not touching UnknownBlock)
|
116
|
-
If you think this is an error, please file a bug report including your SDK version ({wandb_ver}) and this spec ({bspec})
|
117
|
-
"""
|
118
|
-
)
|
119
|
-
)
|
120
|
-
if cls is WeaveBlock:
|
121
|
-
for cls in weave_blocks:
|
122
|
-
try:
|
123
|
-
cls.from_json(bspec)
|
124
|
-
except Exception:
|
125
|
-
pass
|
126
|
-
else:
|
127
|
-
break
|
128
|
-
blocks.append(cls.from_json(bspec))
|
129
|
-
return blocks[1:-1] # accounts for hidden p blocks
|
130
|
-
|
131
|
-
@blocks.setter
|
132
|
-
def blocks(self, new_blocks):
|
133
|
-
json_path = self._get_path("blocks")
|
134
|
-
new_block_specs = (
|
135
|
-
[P("").spec] + [b.spec for b in new_blocks] + [P("").spec]
|
136
|
-
) # hidden p blocks
|
137
|
-
nested_set(self, json_path, new_block_specs)
|
138
|
-
|
139
|
-
@staticmethod
|
140
|
-
def _default_viewspec():
|
141
|
-
return {
|
142
|
-
"id": None,
|
143
|
-
"name": None,
|
144
|
-
"spec": {
|
145
|
-
"version": 5,
|
146
|
-
"panelSettings": {},
|
147
|
-
"blocks": [],
|
148
|
-
"width": "readable",
|
149
|
-
"authors": [],
|
150
|
-
"discussionThreads": [],
|
151
|
-
"ref": {},
|
152
|
-
},
|
153
|
-
}
|
154
|
-
|
155
|
-
@classmethod
|
156
|
-
def from_json(cls, viewspec):
|
157
|
-
obj = cls(project=viewspec["project"]["name"])
|
158
|
-
obj._viewspec = viewspec
|
159
|
-
obj._orig_viewspec = deepcopy(obj._viewspec)
|
160
|
-
return obj
|
161
|
-
|
162
|
-
@property
|
163
|
-
def viewspec(self):
|
164
|
-
return self._viewspec
|
165
|
-
|
166
|
-
@property
|
167
|
-
def modified(self) -> bool:
|
168
|
-
return self._viewspec != self._orig_viewspec
|
169
|
-
|
170
|
-
@property
|
171
|
-
def spec(self) -> dict:
|
172
|
-
return self._viewspec["spec"]
|
173
|
-
|
174
|
-
@property
|
175
|
-
def client(self) -> "RetryingClient":
|
176
|
-
return self._api.client
|
177
|
-
|
178
|
-
@property
|
179
|
-
def id(self) -> str:
|
180
|
-
return self._viewspec["id"]
|
181
|
-
|
182
|
-
@property
|
183
|
-
def name(self) -> str:
|
184
|
-
return self._viewspec["name"]
|
185
|
-
|
186
|
-
@property
|
187
|
-
def panel_grids(self) -> "LList[PanelGrid]":
|
188
|
-
return [b for b in self.blocks if isinstance(b, PanelGrid)]
|
189
|
-
|
190
|
-
@property
|
191
|
-
def runsets(self) -> "LList[Runset]":
|
192
|
-
return [rs for pg in self.panel_grids for rs in pg.runsets]
|
193
|
-
|
194
|
-
@property
|
195
|
-
def url(self) -> str:
|
196
|
-
title = re.sub(r"\W", "-", self.title)
|
197
|
-
title = re.sub(r"-+", "-", title)
|
198
|
-
title = urllib.parse.quote(title)
|
199
|
-
id = self.id.replace("=", "")
|
200
|
-
app_url = self._api.client.app_url
|
201
|
-
if not app_url.endswith("/"):
|
202
|
-
app_url = app_url + "/"
|
203
|
-
return f"{app_url}{self.entity}/{self.project}/reports/{title}--{id}"
|
204
|
-
|
205
|
-
def save(self, draft: bool = False, clone: bool = False) -> "Report":
|
206
|
-
if not self.modified:
|
207
|
-
termwarn("Report has not been modified")
|
208
|
-
|
209
|
-
# create project if not exists
|
210
|
-
projects = self._api.projects(self.entity)
|
211
|
-
is_new_project = True
|
212
|
-
for p in projects:
|
213
|
-
if p.name == self.project:
|
214
|
-
is_new_project = False
|
215
|
-
break
|
216
|
-
|
217
|
-
if is_new_project:
|
218
|
-
self._api.create_project(self.project, self.entity)
|
219
|
-
|
220
|
-
# All panel grids must have at least one runset
|
221
|
-
for pg in self.panel_grids:
|
222
|
-
if not pg.runsets:
|
223
|
-
pg.runsets = PanelGrid._default_runsets()
|
224
|
-
|
225
|
-
# Check runsets with `None` for project and replace with the report's project.
|
226
|
-
# We have to do this here because RunSets don't know about their report until they're added to it.
|
227
|
-
for rs in self.runsets:
|
228
|
-
rs.entity = coalesce(rs.entity, self._api.default_entity)
|
229
|
-
rs.project = coalesce(rs.project, self.project)
|
230
|
-
|
231
|
-
r = self._api.client.execute(
|
232
|
-
UPSERT_VIEW,
|
233
|
-
variable_values={
|
234
|
-
"id": None if clone or not self.id else self.id,
|
235
|
-
"name": generate_name() if clone or not self.name else self.name,
|
236
|
-
"entityName": self.entity,
|
237
|
-
"projectName": self.project,
|
238
|
-
"description": self.description,
|
239
|
-
"displayName": self.title,
|
240
|
-
"type": "runs/draft" if draft else "runs",
|
241
|
-
"spec": json.dumps(self.spec),
|
242
|
-
},
|
243
|
-
)
|
244
|
-
|
245
|
-
viewspec = r["upsertView"]["view"]
|
246
|
-
viewspec["spec"] = json.loads(viewspec["spec"])
|
247
|
-
if clone:
|
248
|
-
return Report.from_json(viewspec)
|
249
|
-
else:
|
250
|
-
self._viewspec["id"] = viewspec["id"]
|
251
|
-
self._viewspec["name"] = viewspec["name"]
|
252
|
-
return self
|
253
|
-
|
254
|
-
def to_html(self, height: int = 1024, hidden: bool = False) -> str:
|
255
|
-
"""Generate HTML containing an iframe displaying this report."""
|
256
|
-
try:
|
257
|
-
url = self.url + "?jupyter=true"
|
258
|
-
style = f"border:none;width:100%;height:{height}px;"
|
259
|
-
prefix = ""
|
260
|
-
if hidden:
|
261
|
-
style += "display:none;"
|
262
|
-
prefix = ipython.toggle_button("report")
|
263
|
-
return prefix + f"<iframe src={url!r} style={style!r}></iframe>"
|
264
|
-
except AttributeError:
|
265
|
-
termlog("HTML repr will be available after you save the report!")
|
266
|
-
|
267
|
-
def _repr_html_(self) -> str:
|
268
|
-
return self.to_html()
|
wandb/apis/reports/v1/runset.py
DELETED
@@ -1,144 +0,0 @@
|
|
1
|
-
from typing import Any, Dict, Optional, TypeVar
|
2
|
-
|
3
|
-
from ...public import Api as PublicApi
|
4
|
-
from ...public import PythonMongoishQueryGenerator, QueryGenerator, Runs
|
5
|
-
from .util import Attr, Base, coalesce, generate_name, nested_get, nested_set
|
6
|
-
|
7
|
-
T = TypeVar("T")
|
8
|
-
|
9
|
-
|
10
|
-
class Runset(Base):
|
11
|
-
entity: Optional[str] = Attr(json_path="spec.project.entityName")
|
12
|
-
project: Optional[str] = Attr(json_path="spec.project.name")
|
13
|
-
name: str = Attr(json_path="spec.name")
|
14
|
-
query: str = Attr(json_path="spec.search.query")
|
15
|
-
filters: dict = Attr(json_path="spec.filters")
|
16
|
-
groupby: list = Attr(json_path="spec.grouping")
|
17
|
-
order: list = Attr(json_path="spec.sort")
|
18
|
-
|
19
|
-
def __init__(
|
20
|
-
self,
|
21
|
-
entity=None,
|
22
|
-
project=None,
|
23
|
-
name="Run set",
|
24
|
-
query="",
|
25
|
-
filters=None,
|
26
|
-
groupby=None,
|
27
|
-
order=None,
|
28
|
-
*args,
|
29
|
-
**kwargs,
|
30
|
-
):
|
31
|
-
super().__init__(*args, **kwargs)
|
32
|
-
self._spec = self._default_runset_spec()
|
33
|
-
self.query_generator = QueryGenerator()
|
34
|
-
self.pm_query_generator = PythonMongoishQueryGenerator(self)
|
35
|
-
|
36
|
-
self.entity = coalesce(entity, PublicApi().default_entity, "")
|
37
|
-
self.project = project # If the project is None, it will be updated to the report's project on save. See: Report.save
|
38
|
-
self.name = name
|
39
|
-
self.query = query
|
40
|
-
self.filters = coalesce(filters, self._default_filters())
|
41
|
-
self.groupby = coalesce(groupby, self._default_groupby())
|
42
|
-
self.order = coalesce(order, self._default_order())
|
43
|
-
|
44
|
-
@classmethod
|
45
|
-
def from_json(cls, spec: Dict[str, Any]) -> T:
|
46
|
-
"""This has a custom implementation because sometimes runsets are missing the project field."""
|
47
|
-
obj = cls()
|
48
|
-
obj._spec = spec
|
49
|
-
|
50
|
-
project = spec.get("project")
|
51
|
-
if project:
|
52
|
-
obj.entity = project.get(
|
53
|
-
"entityName", coalesce(PublicApi().default_entity, "")
|
54
|
-
)
|
55
|
-
obj.project = project.get("name")
|
56
|
-
else:
|
57
|
-
obj.entity = coalesce(PublicApi().default_entity, "")
|
58
|
-
obj.project = None
|
59
|
-
|
60
|
-
return obj
|
61
|
-
|
62
|
-
@filters.getter
|
63
|
-
def filters(self):
|
64
|
-
json_path = self._get_path("filters")
|
65
|
-
filter_specs = nested_get(self, json_path)
|
66
|
-
return self.query_generator.filter_to_mongo(filter_specs)
|
67
|
-
|
68
|
-
@filters.setter
|
69
|
-
def filters(self, new_filters):
|
70
|
-
json_path = self._get_path("filters")
|
71
|
-
new_filter_specs = self.query_generator.mongo_to_filter(new_filters)
|
72
|
-
nested_set(self, json_path, new_filter_specs)
|
73
|
-
|
74
|
-
def set_filters_with_python_expr(self, expr):
|
75
|
-
self.filters = self.pm_query_generator.python_to_mongo(expr)
|
76
|
-
return self
|
77
|
-
|
78
|
-
@groupby.getter
|
79
|
-
def groupby(self):
|
80
|
-
json_path = self._get_path("groupby")
|
81
|
-
groupby_specs = nested_get(self, json_path)
|
82
|
-
cols = [self.query_generator.key_to_server_path(k) for k in groupby_specs]
|
83
|
-
return [self.pm_query_generator.back_to_front(c) for c in cols]
|
84
|
-
|
85
|
-
@groupby.setter
|
86
|
-
def groupby(self, new_groupby):
|
87
|
-
json_path = self._get_path("groupby")
|
88
|
-
cols = [self.pm_query_generator.front_to_back(g) for g in new_groupby]
|
89
|
-
new_groupby_specs = [self.query_generator.server_path_to_key(c) for c in cols]
|
90
|
-
nested_set(self, json_path, new_groupby_specs)
|
91
|
-
|
92
|
-
@order.getter
|
93
|
-
def order(self):
|
94
|
-
json_path = self._get_path("order")
|
95
|
-
order_specs = nested_get(self, json_path)
|
96
|
-
cols = self.query_generator.keys_to_order(order_specs)
|
97
|
-
return [c[0] + self.pm_query_generator.back_to_front(c[1:]) for c in cols]
|
98
|
-
|
99
|
-
@order.setter
|
100
|
-
def order(self, new_orders):
|
101
|
-
json_path = self._get_path("order")
|
102
|
-
cols = [o[0] + self.pm_query_generator.front_to_back(o[1:]) for o in new_orders]
|
103
|
-
new_order_specs = self.query_generator.order_to_keys(cols)
|
104
|
-
nested_set(self, json_path, new_order_specs)
|
105
|
-
|
106
|
-
@property
|
107
|
-
def _runs_config(self) -> dict:
|
108
|
-
return {k: v for run in self.runs for k, v in run.config.items()}
|
109
|
-
|
110
|
-
@property
|
111
|
-
def runs(self) -> Runs:
|
112
|
-
return PublicApi().runs(
|
113
|
-
path=f"{self.entity}/{self.project}", filters=self.filters
|
114
|
-
)
|
115
|
-
|
116
|
-
@staticmethod
|
117
|
-
def _default_filters():
|
118
|
-
return {"$or": [{"$and": []}]}
|
119
|
-
|
120
|
-
@staticmethod
|
121
|
-
def _default_groupby():
|
122
|
-
return []
|
123
|
-
|
124
|
-
@staticmethod
|
125
|
-
def _default_order():
|
126
|
-
return ["-CreatedTimestamp"]
|
127
|
-
|
128
|
-
@staticmethod
|
129
|
-
def _default_runset_spec():
|
130
|
-
return {
|
131
|
-
"id": generate_name(),
|
132
|
-
"runFeed": {
|
133
|
-
"version": 2,
|
134
|
-
"columnVisible": {"run:name": False},
|
135
|
-
"columnPinned": {},
|
136
|
-
"columnWidths": {},
|
137
|
-
"columnOrder": [],
|
138
|
-
"pageSize": 10,
|
139
|
-
"onlyShowSelected": False,
|
140
|
-
},
|
141
|
-
"enabled": True,
|
142
|
-
"selections": {"root": 1, "bounds": [], "tree": []},
|
143
|
-
"expandedRowAddresses": [],
|
144
|
-
}
|