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/util.py
DELETED
@@ -1,406 +0,0 @@
|
|
1
|
-
import random
|
2
|
-
from typing import (
|
3
|
-
Any,
|
4
|
-
Callable,
|
5
|
-
Dict,
|
6
|
-
Generic,
|
7
|
-
List,
|
8
|
-
Optional,
|
9
|
-
Tuple,
|
10
|
-
TypeVar,
|
11
|
-
Union,
|
12
|
-
get_type_hints,
|
13
|
-
)
|
14
|
-
|
15
|
-
from ...public import PanelMetricsHelper
|
16
|
-
from .validators import UNDEFINED_TYPE, TypeValidator, Validator
|
17
|
-
|
18
|
-
# Func = TypeVar("Func")
|
19
|
-
T = TypeVar("T")
|
20
|
-
V = TypeVar("V")
|
21
|
-
Func = Callable[[T], V]
|
22
|
-
|
23
|
-
|
24
|
-
def generate_name(length: int = 12) -> str:
|
25
|
-
"""Generate a random name.
|
26
|
-
|
27
|
-
This implementation roughly based the following snippet in core:
|
28
|
-
https://github.com/wandb/core/blob/master/lib/js/cg/src/utils/string.ts#L39-L44.
|
29
|
-
"""
|
30
|
-
|
31
|
-
# Borrowed from numpy: https://github.com/numpy/numpy/blob/v1.23.0/numpy/core/numeric.py#L2069-L2123
|
32
|
-
def base_repr(number: int, base: int, padding: int = 0) -> str:
|
33
|
-
digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
34
|
-
if base > len(digits):
|
35
|
-
raise ValueError("Bases greater than 36 not handled in base_repr.")
|
36
|
-
elif base < 2:
|
37
|
-
raise ValueError("Bases less than 2 not handled in base_repr.")
|
38
|
-
|
39
|
-
num = abs(number)
|
40
|
-
res = []
|
41
|
-
while num:
|
42
|
-
res.append(digits[num % base])
|
43
|
-
num //= base
|
44
|
-
if padding:
|
45
|
-
res.append("0" * padding)
|
46
|
-
if number < 0:
|
47
|
-
res.append("-")
|
48
|
-
return "".join(reversed(res or "0"))
|
49
|
-
|
50
|
-
rand = random.random()
|
51
|
-
rand = int(float(str(rand)[2:]))
|
52
|
-
rand36 = base_repr(rand, 36)
|
53
|
-
return rand36.lower()[:length]
|
54
|
-
|
55
|
-
|
56
|
-
def coalesce(*arg: Any) -> Any:
|
57
|
-
"""Return the first non-none value in the list of arguments.
|
58
|
-
|
59
|
-
Similar to ?? in C#.
|
60
|
-
"""
|
61
|
-
return next((a for a in arg if a is not None), None)
|
62
|
-
|
63
|
-
|
64
|
-
def nested_get(json: dict, keys: str) -> Any:
|
65
|
-
"""Get the element at the terminal node of a nested JSON dict based on `path`.
|
66
|
-
|
67
|
-
The first item of the path can be an object.
|
68
|
-
"""
|
69
|
-
keys = keys.split(".")
|
70
|
-
if len(keys) == 1:
|
71
|
-
return vars(json)[keys[0]]
|
72
|
-
else:
|
73
|
-
rv = json
|
74
|
-
for key in keys:
|
75
|
-
if isinstance(rv, Base):
|
76
|
-
if not hasattr(rv, key):
|
77
|
-
setattr(rv, key, {})
|
78
|
-
rv = getattr(rv, key)
|
79
|
-
else:
|
80
|
-
if key not in rv:
|
81
|
-
rv[key] = None
|
82
|
-
rv = rv[key]
|
83
|
-
return rv
|
84
|
-
|
85
|
-
|
86
|
-
def nested_set(json: dict, keys: str, value: Any) -> None:
|
87
|
-
"""Set the element at the terminal node of a nested JSON dict based on `path`.
|
88
|
-
|
89
|
-
The first item of the path can be an object.
|
90
|
-
|
91
|
-
If nodes do not exist, they are created along the way.
|
92
|
-
"""
|
93
|
-
keys = keys.split(".")
|
94
|
-
if len(keys) == 1:
|
95
|
-
vars(json)[keys[0]] = value
|
96
|
-
else:
|
97
|
-
for key in keys[:-1]:
|
98
|
-
if isinstance(json, Base):
|
99
|
-
if not hasattr(json, key):
|
100
|
-
setattr(json, key, {})
|
101
|
-
json = getattr(json, key)
|
102
|
-
else:
|
103
|
-
json = json.setdefault(key, {})
|
104
|
-
json[keys[-1]] = value
|
105
|
-
|
106
|
-
|
107
|
-
class Property(Generic[T]):
|
108
|
-
"""Property descriptor with a default getter and setter."""
|
109
|
-
|
110
|
-
def __init__(
|
111
|
-
self, fget: Optional[Func] = None, fset: Optional[Func] = None
|
112
|
-
) -> None:
|
113
|
-
self.fget = fget or self.default_fget
|
114
|
-
self.fset = fset or self.default_fset
|
115
|
-
self.name = ""
|
116
|
-
|
117
|
-
def __set_name__(self, owner: Any, name: str) -> None:
|
118
|
-
self.name = name
|
119
|
-
|
120
|
-
def __get__(self, obj: Any, objtype: Optional[Any] = None) -> T:
|
121
|
-
if obj is None:
|
122
|
-
return self
|
123
|
-
if self.fget is None:
|
124
|
-
raise AttributeError(f"unreadable attribute {self.name}")
|
125
|
-
return self.fget(obj)
|
126
|
-
|
127
|
-
def __set__(self, obj: Any, value: Any) -> None:
|
128
|
-
if self.fset is None:
|
129
|
-
raise AttributeError(f"can't set attribute {self.name}")
|
130
|
-
self.fset(obj, value)
|
131
|
-
|
132
|
-
def getter(self, fget: Func) -> Func:
|
133
|
-
prop = type(self)(fget, self.fset)
|
134
|
-
prop.name = self.name
|
135
|
-
return prop
|
136
|
-
|
137
|
-
def setter(self, fset: Func) -> Func:
|
138
|
-
prop = type(self)(self.fget, fset)
|
139
|
-
prop.name = self.name
|
140
|
-
return prop
|
141
|
-
|
142
|
-
def default_fget(self, obj: Any) -> Any:
|
143
|
-
return obj.__dict__[self.name]
|
144
|
-
|
145
|
-
def default_fset(self, obj: Any, value: Any) -> None:
|
146
|
-
obj.__dict__[self.name] = value
|
147
|
-
|
148
|
-
|
149
|
-
class Validated(Property):
|
150
|
-
def __init__(
|
151
|
-
self, *args: Func, validators: Optional[List[Validator]] = None, **kwargs: Func
|
152
|
-
) -> None:
|
153
|
-
super().__init__(*args, **kwargs)
|
154
|
-
if validators is None:
|
155
|
-
validators = []
|
156
|
-
self.validators = validators
|
157
|
-
|
158
|
-
def __set__(self, instance: Any, value: Any) -> None:
|
159
|
-
if not isinstance(value, type(self)):
|
160
|
-
for validator in self.validators:
|
161
|
-
validator(self, value)
|
162
|
-
super().__set__(instance, value)
|
163
|
-
|
164
|
-
|
165
|
-
class Typed(Validated):
|
166
|
-
def __set_name__(self, owner: Any, name: str) -> None:
|
167
|
-
super().__set_name__(owner, name)
|
168
|
-
self.type = get_type_hints(owner).get(name, UNDEFINED_TYPE)
|
169
|
-
|
170
|
-
if self.type is not UNDEFINED_TYPE:
|
171
|
-
self.validators = [TypeValidator(attr_type=self.type)] + self.validators
|
172
|
-
|
173
|
-
|
174
|
-
class JSONLinked(Property):
|
175
|
-
"""Property that is linked to one or more JSON keys."""
|
176
|
-
|
177
|
-
def __init__(
|
178
|
-
self,
|
179
|
-
*args: Func,
|
180
|
-
json_path: Optional[Union[str, List[str]]] = None,
|
181
|
-
**kwargs: Func,
|
182
|
-
) -> None:
|
183
|
-
super().__init__(*args, **kwargs)
|
184
|
-
self.path_or_name = json_path
|
185
|
-
|
186
|
-
def __set_name__(self, owner: Any, name: str) -> None:
|
187
|
-
if self.path_or_name is None:
|
188
|
-
self.path_or_name = name
|
189
|
-
super().__set_name__(owner, name)
|
190
|
-
|
191
|
-
def getter(self, fget: Func) -> Func:
|
192
|
-
prop = type(self)(fget, self.fset, json_path=self.path_or_name)
|
193
|
-
prop.name = self.name
|
194
|
-
return prop
|
195
|
-
|
196
|
-
def setter(self, fset: Func) -> Func:
|
197
|
-
prop = type(self)(self.fget, fset, json_path=self.path_or_name)
|
198
|
-
prop.name = self.name
|
199
|
-
return prop
|
200
|
-
|
201
|
-
def default_fget(self, obj: Any) -> Union[Any, List[Any]]:
|
202
|
-
if isinstance(self.path_or_name, str):
|
203
|
-
return nested_get(obj, self.path_or_name)
|
204
|
-
elif isinstance(self.path_or_name, list):
|
205
|
-
return [nested_get(obj, p) for p in self.path_or_name]
|
206
|
-
else:
|
207
|
-
raise TypeError(f"Unexpected type for path {type(self.path_or_name)!r}")
|
208
|
-
|
209
|
-
def default_fset(self, obj: Any, value: Any) -> None:
|
210
|
-
if isinstance(self.path_or_name, str):
|
211
|
-
nested_set(obj, self.path_or_name, value)
|
212
|
-
elif isinstance(self.path_or_name, list):
|
213
|
-
for p, v in zip(self.path_or_name, value):
|
214
|
-
nested_set(obj, p, v)
|
215
|
-
else:
|
216
|
-
raise TypeError(f"Unexpected type for path {type(self.path_or_name)!r}")
|
217
|
-
|
218
|
-
|
219
|
-
class Attr(Typed, JSONLinked):
|
220
|
-
def getter(self, fget: Func) -> Func:
|
221
|
-
prop = type(self)(
|
222
|
-
fget, self.fset, json_path=self.path_or_name, validators=self.validators
|
223
|
-
)
|
224
|
-
prop.name = self.name
|
225
|
-
return prop
|
226
|
-
|
227
|
-
def setter(self, fset: Func) -> Func:
|
228
|
-
prop = type(self)(
|
229
|
-
self.fget, fset, json_path=self.path_or_name, validators=self.validators
|
230
|
-
)
|
231
|
-
prop.name = self.name
|
232
|
-
return prop
|
233
|
-
|
234
|
-
|
235
|
-
class SubclassOnlyABC:
|
236
|
-
def __new__(cls, *args: Any, **kwargs: Any) -> T:
|
237
|
-
if SubclassOnlyABC in cls.__bases__:
|
238
|
-
raise TypeError(f"Abstract class {cls.__name__} cannot be instantiated")
|
239
|
-
|
240
|
-
return super().__new__(cls)
|
241
|
-
|
242
|
-
|
243
|
-
class ShortReprMixin:
|
244
|
-
def __repr__(self) -> str:
|
245
|
-
clas = self.__class__.__name__
|
246
|
-
props = {
|
247
|
-
k: getattr(self, k)
|
248
|
-
for k, v in self.__class__.__dict__.items()
|
249
|
-
if isinstance(v, Attr)
|
250
|
-
}
|
251
|
-
settings = [
|
252
|
-
f"{k}={v!r}" for k, v in props.items() if not self._is_interesting(v)
|
253
|
-
]
|
254
|
-
return "{}({})".format(clas, ", ".join(settings))
|
255
|
-
|
256
|
-
@staticmethod
|
257
|
-
def _is_interesting(x: Any) -> bool:
|
258
|
-
if isinstance(x, (list, tuple)):
|
259
|
-
return all(v is None for v in x)
|
260
|
-
return x is None or x == {}
|
261
|
-
|
262
|
-
|
263
|
-
class Base(SubclassOnlyABC, ShortReprMixin):
|
264
|
-
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
265
|
-
super().__init__(*args, **kwargs)
|
266
|
-
self._spec = {}
|
267
|
-
|
268
|
-
@property
|
269
|
-
def spec(self) -> Dict[str, Any]:
|
270
|
-
return self._spec
|
271
|
-
|
272
|
-
@classmethod
|
273
|
-
def from_json(cls, spec: Dict[str, Any]) -> T:
|
274
|
-
obj = cls()
|
275
|
-
obj._spec = spec
|
276
|
-
return obj
|
277
|
-
|
278
|
-
def _get_path(self, var: str) -> str:
|
279
|
-
return vars(type(self))[var].path_or_name
|
280
|
-
|
281
|
-
|
282
|
-
class Panel(Base, SubclassOnlyABC):
|
283
|
-
layout: dict = Attr(json_path="spec.layout")
|
284
|
-
|
285
|
-
def __init__(
|
286
|
-
self, layout: Optional[Dict[str, int]] = None, *args: Any, **kwargs: Any
|
287
|
-
) -> None:
|
288
|
-
super().__init__(*args, **kwargs)
|
289
|
-
self._spec["viewType"] = self.view_type
|
290
|
-
self._spec["__id__"] = generate_name()
|
291
|
-
self.layout = coalesce(layout, self._default_panel_layout())
|
292
|
-
self.panel_metrics_helper = PanelMetricsHelper()
|
293
|
-
|
294
|
-
@property
|
295
|
-
def view_type(self) -> str:
|
296
|
-
return "UNKNOWN PANEL"
|
297
|
-
|
298
|
-
@property
|
299
|
-
def config(self) -> Dict[str, Any]:
|
300
|
-
return self._spec["config"]
|
301
|
-
|
302
|
-
@staticmethod
|
303
|
-
def _default_panel_layout() -> Dict[str, int]:
|
304
|
-
return {"x": 0, "y": 0, "w": 8, "h": 6}
|
305
|
-
|
306
|
-
@layout.setter
|
307
|
-
def layout(self, d: Dict[str, int]) -> None:
|
308
|
-
d["x"] = coalesce(d.get("x"), self._default_panel_layout()["x"])
|
309
|
-
d["y"] = coalesce(d.get("y"), self._default_panel_layout()["y"])
|
310
|
-
d["w"] = coalesce(d.get("w"), self._default_panel_layout()["w"])
|
311
|
-
d["h"] = coalesce(d.get("h"), self._default_panel_layout()["h"])
|
312
|
-
|
313
|
-
# json_path = self._get_path("layout")
|
314
|
-
# can't use _get_path because it's not on the obj... if only we had dataclass...
|
315
|
-
json_path = "spec.layout"
|
316
|
-
nested_set(self, json_path, d)
|
317
|
-
|
318
|
-
|
319
|
-
class Block(Base, SubclassOnlyABC):
|
320
|
-
pass
|
321
|
-
|
322
|
-
|
323
|
-
def fix_collisions(panels: List[Panel]) -> List[Panel]:
|
324
|
-
x_max = 24
|
325
|
-
|
326
|
-
for i, p1 in enumerate(panels):
|
327
|
-
for p2 in panels[i:]:
|
328
|
-
if collides(p1, p2):
|
329
|
-
# try to move right
|
330
|
-
x, y = shift(p1, p2)
|
331
|
-
if p2.layout["x"] + p2.layout["w"] + x <= x_max:
|
332
|
-
p2.layout["x"] += x
|
333
|
-
|
334
|
-
# if you hit right right bound, move down
|
335
|
-
else:
|
336
|
-
p2.layout["y"] += y
|
337
|
-
|
338
|
-
# then check if you can move left again to cleanup layout
|
339
|
-
p2.layout["x"] = 0
|
340
|
-
return panels
|
341
|
-
|
342
|
-
|
343
|
-
def collides(p1: Panel, p2: Panel) -> bool:
|
344
|
-
l1, l2 = p1.layout, p2.layout
|
345
|
-
|
346
|
-
if (
|
347
|
-
(p1.spec["__id__"] == p2.spec["__id__"])
|
348
|
-
or (l1["x"] + l1["w"] <= l2["x"])
|
349
|
-
or (l1["x"] >= l2["w"] + l2["x"])
|
350
|
-
or (l1["y"] + l1["h"] <= l2["y"])
|
351
|
-
or (l1["y"] >= l2["y"] + l2["h"])
|
352
|
-
):
|
353
|
-
return False
|
354
|
-
|
355
|
-
return True
|
356
|
-
|
357
|
-
|
358
|
-
def shift(p1: Panel, p2: Panel) -> Tuple[Panel, Panel]:
|
359
|
-
l1, l2 = p1.layout, p2.layout
|
360
|
-
|
361
|
-
x = l1["x"] + l1["w"] - l2["x"]
|
362
|
-
y = l1["y"] + l1["h"] - l2["y"]
|
363
|
-
|
364
|
-
return x, y
|
365
|
-
|
366
|
-
|
367
|
-
class InlineLaTeX(Base):
|
368
|
-
latex: str = Attr()
|
369
|
-
|
370
|
-
def __init__(self, latex="", *args, **kwargs):
|
371
|
-
super().__init__(*args, **kwargs)
|
372
|
-
self.latex = latex
|
373
|
-
|
374
|
-
@property
|
375
|
-
def spec(self) -> dict:
|
376
|
-
return {"type": "latex", "children": [{"text": ""}], "content": self.latex}
|
377
|
-
|
378
|
-
|
379
|
-
class InlineCode(Base):
|
380
|
-
code: str = Attr()
|
381
|
-
|
382
|
-
def __init__(self, code="", *args, **kwargs):
|
383
|
-
super().__init__(*args, **kwargs)
|
384
|
-
self.code = code
|
385
|
-
|
386
|
-
@property
|
387
|
-
def spec(self) -> dict:
|
388
|
-
return {"text": self.code, "inlineCode": True}
|
389
|
-
|
390
|
-
|
391
|
-
class Link(Base):
|
392
|
-
text: str = Attr()
|
393
|
-
url: str = Attr()
|
394
|
-
|
395
|
-
def __init__(self, text, url, *args, **kwargs):
|
396
|
-
super().__init__(*args, **kwargs)
|
397
|
-
self.text = text
|
398
|
-
self.url = url
|
399
|
-
|
400
|
-
@property
|
401
|
-
def spec(self) -> dict:
|
402
|
-
return {"type": "link", "url": self.url, "children": [{"text": self.text}]}
|
403
|
-
|
404
|
-
|
405
|
-
def weave_inputs(spec):
|
406
|
-
return spec["config"]["panelConfig"]["exp"]["fromOp"]["inputs"]
|
@@ -1,131 +0,0 @@
|
|
1
|
-
from abc import ABC, abstractmethod
|
2
|
-
from typing import TypeVar, Union
|
3
|
-
|
4
|
-
LINEPLOT_STYLES = ["line", "stacked-area", "pct-area", None]
|
5
|
-
BARPLOT_STYLES = ["bar", "boxplot", "violin", None]
|
6
|
-
FONT_SIZES = ["small", "medium", "large", "auto", None]
|
7
|
-
LEGEND_POSITIONS = ["north", "south", "east", "west", None]
|
8
|
-
LEGEND_ORIENTATIONS = ["horizontal", "vertical", None]
|
9
|
-
AGGFUNCS = ["mean", "min", "max", "median", "sum", "samples", None]
|
10
|
-
RANGEFUNCS = ["minmax", "stddev", "stderr", "none", "samples", None]
|
11
|
-
MARKS = ["solid", "dashed", "dotted", "dotdash", "dotdotdash", None]
|
12
|
-
TIMESTEPS = ["seconds", "minutes", "hours", "days", None]
|
13
|
-
SMOOTHING_TYPES = ["exponential", "gaussian", "average", "none", None]
|
14
|
-
CODE_COMPARE_DIFF = ["split", "unified", None]
|
15
|
-
|
16
|
-
|
17
|
-
UNDEFINED_TYPE = TypeVar("UNDEFINED_TYPE")
|
18
|
-
|
19
|
-
|
20
|
-
class Validator(ABC):
|
21
|
-
def __init__(self, how=None):
|
22
|
-
self.how = how
|
23
|
-
|
24
|
-
@abstractmethod
|
25
|
-
def call(self, attr_name, value):
|
26
|
-
pass
|
27
|
-
|
28
|
-
def __call__(self, attr, value):
|
29
|
-
attr_name = attr.name
|
30
|
-
if value is None and self.how in {"keys", "values"}:
|
31
|
-
return
|
32
|
-
if self.how == "keys":
|
33
|
-
attr_name += " keys"
|
34
|
-
for v in value:
|
35
|
-
self.call(attr_name, v)
|
36
|
-
elif self.how == "values":
|
37
|
-
attr_name += " values"
|
38
|
-
for v in value.values():
|
39
|
-
self.call(attr_name, v)
|
40
|
-
elif self.how is None:
|
41
|
-
attr_name += " object"
|
42
|
-
self.call(attr_name, value)
|
43
|
-
else:
|
44
|
-
raise ValueError(
|
45
|
-
'Validator setting `how` must be one of ("keys", "values", None)'
|
46
|
-
)
|
47
|
-
|
48
|
-
|
49
|
-
class TypeValidator(Validator):
|
50
|
-
def __init__(self, attr_type, *args, **kwargs):
|
51
|
-
super().__init__(*args, **kwargs)
|
52
|
-
self.attr_type = attr_type
|
53
|
-
try:
|
54
|
-
origin = attr_type.__origin__
|
55
|
-
subtypes = attr_type.__args__
|
56
|
-
except AttributeError: # normal types
|
57
|
-
self.attr_type = (attr_type,)
|
58
|
-
else:
|
59
|
-
if origin is Union:
|
60
|
-
self.attr_type = subtypes
|
61
|
-
else:
|
62
|
-
raise TypeError(f"{attr_type} is not currently supported.")
|
63
|
-
|
64
|
-
def call(self, attr_name, value):
|
65
|
-
if not isinstance(value, self.attr_type):
|
66
|
-
raise TypeError(
|
67
|
-
f"{attr_name} must be of type {self.attr_type!r} (got {type(value)!r})"
|
68
|
-
)
|
69
|
-
|
70
|
-
|
71
|
-
class OneOf(Validator):
|
72
|
-
def __init__(self, options, *args, **kwargs):
|
73
|
-
super().__init__(*args, **kwargs)
|
74
|
-
self.options = options
|
75
|
-
|
76
|
-
def call(self, attr_name, value):
|
77
|
-
if value not in self.options:
|
78
|
-
raise ValueError(
|
79
|
-
f"{attr_name} must be one of {self.options!r} (got {value!r})"
|
80
|
-
)
|
81
|
-
|
82
|
-
|
83
|
-
class Length(Validator):
|
84
|
-
def __init__(self, k, *args, **kwargs):
|
85
|
-
super().__init__(*args, **kwargs)
|
86
|
-
self.k = k
|
87
|
-
|
88
|
-
def call(self, attr_name, value):
|
89
|
-
if len(value) != self.k:
|
90
|
-
raise ValueError(
|
91
|
-
f"{attr_name} must have exactly {self.k} elements (got {len(value)!r}, elems: {value!r})"
|
92
|
-
)
|
93
|
-
|
94
|
-
|
95
|
-
class Between(Validator):
|
96
|
-
def __init__(self, lb, ub, *args, **kwargs):
|
97
|
-
super().__init__(*args, **kwargs)
|
98
|
-
self.lb = lb
|
99
|
-
self.ub = ub
|
100
|
-
|
101
|
-
def call(self, attr_name, value):
|
102
|
-
if not self.lb <= value <= self.ub:
|
103
|
-
raise ValueError(
|
104
|
-
f"{attr_name} must be between [{self.lb}, {self.ub}] inclusive (got {value})"
|
105
|
-
)
|
106
|
-
|
107
|
-
|
108
|
-
class OrderString(TypeValidator):
|
109
|
-
def __init__(self):
|
110
|
-
super().__init__(attr_type=str)
|
111
|
-
|
112
|
-
def call(self, attr_name, value):
|
113
|
-
super().call(attr_name, value)
|
114
|
-
|
115
|
-
if value[0] not in {"+", "-"}:
|
116
|
-
raise ValueError(
|
117
|
-
f'{attr_name} must be prefixed with "+" or "-" to indicate ascending or descending order'
|
118
|
-
)
|
119
|
-
|
120
|
-
|
121
|
-
class LayoutDict(Validator):
|
122
|
-
def call(self, attr_name, value):
|
123
|
-
if set(value.keys()) != {"x", "y", "w", "h"}:
|
124
|
-
raise ValueError(
|
125
|
-
f"{attr_name} must be a dict containing exactly the keys `x`, y`, `w`, `h`"
|
126
|
-
)
|
127
|
-
for k, v in value.items():
|
128
|
-
if not isinstance(v, int):
|
129
|
-
raise ValueError(
|
130
|
-
f"{attr_name} key `{k}` must be of type {int} (got {type(v)!r})"
|
131
|
-
)
|
wandb/apis/reports/v2/blocks.py
DELETED
@@ -1,25 +0,0 @@
|
|
1
|
-
# flake8: noqa
|
2
|
-
from .interface import (
|
3
|
-
H1,
|
4
|
-
H2,
|
5
|
-
H3,
|
6
|
-
BlockQuote,
|
7
|
-
CalloutBlock,
|
8
|
-
CheckedList,
|
9
|
-
CheckedListItem,
|
10
|
-
CodeBlock,
|
11
|
-
Gallery,
|
12
|
-
HorizontalRule,
|
13
|
-
Image,
|
14
|
-
LatexBlock,
|
15
|
-
MarkdownBlock,
|
16
|
-
OrderedList,
|
17
|
-
OrderedListItem,
|
18
|
-
P,
|
19
|
-
PanelGrid,
|
20
|
-
TableOfContents,
|
21
|
-
UnorderedList,
|
22
|
-
UnorderedListItem,
|
23
|
-
Video,
|
24
|
-
WeaveBlock,
|
25
|
-
)
|