wandb 0.19.9__py3-none-macosx_10_14_x86_64.whl → 0.19.11__py3-none-macosx_10_14_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- wandb/__init__.py +1 -1
- wandb/__init__.pyi +6 -3
- wandb/_pydantic/__init__.py +14 -8
- wandb/_pydantic/base.py +51 -36
- wandb/_pydantic/utils.py +73 -0
- wandb/_pydantic/v1_compat.py +79 -57
- wandb/apis/public/__init__.py +2 -2
- wandb/apis/public/api.py +684 -4
- wandb/apis/public/artifacts.py +377 -677
- wandb/apis/public/automations.py +69 -0
- wandb/apis/public/integrations.py +180 -0
- wandb/apis/public/projects.py +29 -0
- wandb/apis/public/registries/__init__.py +0 -0
- wandb/apis/public/registries/_freezable_list.py +179 -0
- wandb/apis/public/{registries.py → registries/registries_search.py} +22 -129
- wandb/apis/public/registries/registry.py +357 -0
- wandb/apis/public/registries/utils.py +140 -0
- wandb/apis/public/runs.py +58 -56
- wandb/apis/public/utils.py +107 -1
- wandb/automations/__init__.py +73 -0
- wandb/automations/_filters/__init__.py +40 -0
- wandb/automations/_filters/expressions.py +181 -0
- wandb/automations/_filters/operators.py +258 -0
- wandb/automations/_filters/run_metrics.py +332 -0
- wandb/automations/_generated/__init__.py +177 -0
- wandb/automations/_generated/create_automation.py +17 -0
- wandb/automations/_generated/create_generic_webhook_integration.py +43 -0
- wandb/automations/_generated/delete_automation.py +17 -0
- wandb/automations/_generated/enums.py +33 -0
- wandb/automations/_generated/fragments.py +358 -0
- wandb/automations/_generated/generic_webhook_integrations_by_entity.py +22 -0
- wandb/automations/_generated/get_automations.py +24 -0
- wandb/automations/_generated/get_automations_by_entity.py +26 -0
- wandb/automations/_generated/input_types.py +104 -0
- wandb/automations/_generated/integrations_by_entity.py +22 -0
- wandb/automations/_generated/operations.py +647 -0
- wandb/automations/_generated/slack_integrations_by_entity.py +22 -0
- wandb/automations/_generated/update_automation.py +17 -0
- wandb/automations/_utils.py +237 -0
- wandb/automations/_validators.py +165 -0
- wandb/automations/actions.py +220 -0
- wandb/automations/automations.py +87 -0
- wandb/automations/events.py +287 -0
- wandb/automations/integrations.py +45 -0
- wandb/automations/scopes.py +78 -0
- wandb/beta/workflows.py +9 -10
- wandb/bin/gpu_stats +0 -0
- wandb/bin/wandb-core +0 -0
- wandb/cli/cli.py +3 -3
- wandb/env.py +11 -0
- wandb/integration/keras/keras.py +2 -1
- wandb/integration/langchain/wandb_tracer.py +2 -1
- wandb/jupyter.py +137 -118
- wandb/old/settings.py +4 -1
- wandb/old/summary.py +0 -2
- wandb/proto/v3/wandb_internal_pb2.py +297 -292
- 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 +292 -292
- wandb/proto/v4/wandb_settings_pb2.py +2 -2
- wandb/proto/v4/wandb_telemetry_pb2.py +10 -10
- wandb/proto/v5/wandb_internal_pb2.py +292 -292
- wandb/proto/v5/wandb_settings_pb2.py +2 -2
- wandb/proto/v5/wandb_telemetry_pb2.py +10 -10
- wandb/proto/v6/wandb_base_pb2.py +41 -0
- wandb/proto/v6/wandb_internal_pb2.py +393 -0
- wandb/proto/v6/wandb_server_pb2.py +78 -0
- wandb/proto/v6/wandb_settings_pb2.py +58 -0
- wandb/proto/v6/wandb_telemetry_pb2.py +52 -0
- wandb/proto/wandb_base_pb2.py +2 -0
- wandb/proto/wandb_deprecated.py +8 -0
- wandb/proto/wandb_internal_pb2.py +3 -1
- 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/_generated/__init__.py +289 -0
- wandb/sdk/artifacts/_generated/add_aliases.py +21 -0
- wandb/sdk/artifacts/_generated/artifact_collection_membership_files.py +43 -0
- wandb/sdk/artifacts/_generated/artifact_version_files.py +36 -0
- wandb/sdk/artifacts/_generated/create_artifact_collection_tag_assignments.py +36 -0
- wandb/sdk/artifacts/_generated/delete_aliases.py +21 -0
- wandb/sdk/artifacts/_generated/delete_artifact_collection_tag_assignments.py +25 -0
- wandb/sdk/artifacts/_generated/delete_artifact_portfolio.py +35 -0
- wandb/sdk/artifacts/_generated/delete_artifact_sequence.py +35 -0
- wandb/sdk/artifacts/_generated/enums.py +17 -0
- wandb/sdk/artifacts/_generated/fetch_linked_artifacts.py +67 -0
- wandb/sdk/artifacts/_generated/fragments.py +221 -0
- wandb/sdk/artifacts/_generated/input_types.py +28 -0
- wandb/sdk/artifacts/_generated/move_artifact_collection.py +35 -0
- wandb/sdk/artifacts/_generated/operations.py +611 -0
- wandb/sdk/artifacts/_generated/project_artifact_collection.py +101 -0
- wandb/sdk/artifacts/_generated/project_artifact_collections.py +33 -0
- wandb/sdk/artifacts/_generated/project_artifact_type.py +24 -0
- wandb/sdk/artifacts/_generated/project_artifact_types.py +24 -0
- wandb/sdk/artifacts/_generated/project_artifacts.py +42 -0
- wandb/sdk/artifacts/_generated/run_input_artifacts.py +51 -0
- wandb/sdk/artifacts/_generated/run_output_artifacts.py +51 -0
- wandb/sdk/artifacts/_generated/update_artifact.py +26 -0
- wandb/sdk/artifacts/_generated/update_artifact_portfolio.py +35 -0
- wandb/sdk/artifacts/_generated/update_artifact_sequence.py +35 -0
- wandb/sdk/artifacts/_graphql_fragments.py +57 -79
- wandb/sdk/artifacts/_validators.py +120 -1
- wandb/sdk/artifacts/artifact.py +419 -215
- wandb/sdk/artifacts/artifact_file_cache.py +4 -6
- wandb/sdk/artifacts/artifact_manifest_entry.py +13 -3
- wandb/sdk/artifacts/storage_handlers/azure_handler.py +1 -0
- wandb/sdk/artifacts/storage_policies/wandb_storage_policy.py +182 -1
- wandb/sdk/artifacts/storage_policy.py +3 -0
- wandb/sdk/data_types/base_types/media.py +2 -3
- wandb/sdk/data_types/base_types/wb_value.py +34 -11
- wandb/sdk/data_types/html.py +36 -9
- wandb/sdk/data_types/image.py +12 -12
- wandb/sdk/data_types/table.py +5 -0
- wandb/sdk/data_types/trace_tree.py +2 -0
- wandb/sdk/data_types/utils.py +1 -1
- wandb/sdk/data_types/video.py +59 -57
- wandb/sdk/interface/interface.py +4 -3
- wandb/sdk/internal/internal_api.py +21 -31
- wandb/sdk/internal/profiler.py +6 -5
- wandb/sdk/internal/run.py +13 -6
- wandb/sdk/internal/sender.py +5 -2
- wandb/sdk/launch/sweeps/utils.py +8 -0
- wandb/sdk/lib/apikey.py +25 -4
- wandb/sdk/lib/asyncio_compat.py +1 -1
- wandb/sdk/lib/deprecate.py +13 -22
- wandb/sdk/lib/disabled.py +2 -1
- wandb/sdk/lib/printer.py +37 -8
- wandb/sdk/lib/printer_asyncio.py +46 -0
- wandb/sdk/lib/redirect.py +10 -5
- wandb/sdk/projects/_generated/__init__.py +47 -0
- wandb/sdk/projects/_generated/delete_project.py +22 -0
- wandb/sdk/projects/_generated/enums.py +4 -0
- wandb/sdk/projects/_generated/fetch_registry.py +22 -0
- wandb/sdk/projects/_generated/fragments.py +41 -0
- wandb/sdk/projects/_generated/input_types.py +13 -0
- wandb/sdk/projects/_generated/operations.py +88 -0
- wandb/sdk/projects/_generated/rename_project.py +27 -0
- wandb/sdk/projects/_generated/upsert_registry_project.py +27 -0
- wandb/sdk/service/server_sock.py +19 -14
- wandb/sdk/service/service.py +18 -8
- wandb/sdk/service/streams.py +5 -0
- wandb/sdk/verify/verify.py +6 -3
- wandb/sdk/wandb_init.py +217 -70
- wandb/sdk/wandb_login.py +13 -4
- wandb/sdk/wandb_run.py +419 -295
- wandb/sdk/wandb_settings.py +27 -10
- wandb/sdk/wandb_setup.py +61 -0
- wandb/util.py +33 -29
- {wandb-0.19.9.dist-info → wandb-0.19.11.dist-info}/METADATA +5 -5
- {wandb-0.19.9.dist-info → wandb-0.19.11.dist-info}/RECORD +153 -83
- wandb/_globals.py +0 -19
- wandb/sdk/internal/_generated/base.py +0 -226
- wandb/sdk/internal/_generated/typing_compat.py +0 -14
- {wandb-0.19.9.dist-info → wandb-0.19.11.dist-info}/WHEEL +0 -0
- {wandb-0.19.9.dist-info → wandb-0.19.11.dist-info}/entry_points.txt +0 -0
- {wandb-0.19.9.dist-info → wandb-0.19.11.dist-info}/licenses/LICENSE +0 -0
wandb/__init__.py
CHANGED
wandb/__init__.pyi
CHANGED
@@ -106,7 +106,7 @@ if TYPE_CHECKING:
|
|
106
106
|
import wandb
|
107
107
|
from wandb.plot import CustomChart
|
108
108
|
|
109
|
-
__version__: str = "0.19.
|
109
|
+
__version__: str = "0.19.11"
|
110
110
|
|
111
111
|
run: Run | None
|
112
112
|
config: wandb_config.Config
|
@@ -229,6 +229,7 @@ def init(
|
|
229
229
|
"default",
|
230
230
|
"return_previous",
|
231
231
|
"finish_previous",
|
232
|
+
"create_new",
|
232
233
|
]
|
233
234
|
) = None,
|
234
235
|
resume: bool | Literal["allow", "never", "must", "auto"] | None = None,
|
@@ -476,6 +477,7 @@ def login(
|
|
476
477
|
force: Optional[bool] = None,
|
477
478
|
timeout: Optional[int] = None,
|
478
479
|
verify: bool = False,
|
480
|
+
referrer: Optional[str] = None,
|
479
481
|
) -> bool:
|
480
482
|
"""Set up W&B login credentials.
|
481
483
|
|
@@ -495,6 +497,7 @@ def login(
|
|
495
497
|
force: (bool, optional) If true, will force a relogin.
|
496
498
|
timeout: (int, optional) Number of seconds to wait for user input.
|
497
499
|
verify: (bool) Verify the credentials with the W&B server.
|
500
|
+
referrer: (string, optional) The referrer to use in the URL login request.
|
498
501
|
|
499
502
|
Returns:
|
500
503
|
bool: if key is configured
|
@@ -1075,7 +1078,7 @@ def link_model(
|
|
1075
1078
|
registered_model_name: str,
|
1076
1079
|
name: str | None = None,
|
1077
1080
|
aliases: list[str] | None = None,
|
1078
|
-
) -> None:
|
1081
|
+
) -> Artifact | None:
|
1079
1082
|
"""Log a model artifact version and link it to a registered model in the model registry.
|
1080
1083
|
|
1081
1084
|
The linked model version will be visible in the UI for the specified registered model.
|
@@ -1137,7 +1140,7 @@ def link_model(
|
|
1137
1140
|
ValueError: if name has invalid special characters
|
1138
1141
|
|
1139
1142
|
Returns:
|
1140
|
-
None
|
1143
|
+
The linked artifact if linking was successful, otherwise None.
|
1141
1144
|
"""
|
1142
1145
|
...
|
1143
1146
|
|
wandb/_pydantic/__init__.py
CHANGED
@@ -1,17 +1,19 @@
|
|
1
1
|
"""Internal utilities for working with pydantic."""
|
2
2
|
|
3
|
-
from .base import
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
3
|
+
from .base import (
|
4
|
+
CompatBaseModel,
|
5
|
+
GQLBase,
|
6
|
+
GQLId,
|
7
|
+
SerializedToJson,
|
8
|
+
Typename,
|
9
|
+
ensure_json,
|
10
10
|
)
|
11
|
+
from .utils import IS_PYDANTIC_V2, from_json, pydantic_isinstance, to_json
|
12
|
+
from .v1_compat import AliasChoices, computed_field, field_validator, model_validator
|
11
13
|
|
12
14
|
__all__ = [
|
13
15
|
"IS_PYDANTIC_V2",
|
14
|
-
"
|
16
|
+
"CompatBaseModel",
|
15
17
|
"GQLBase",
|
16
18
|
"Typename",
|
17
19
|
"GQLId",
|
@@ -20,4 +22,8 @@ __all__ = [
|
|
20
22
|
"computed_field",
|
21
23
|
"field_validator",
|
22
24
|
"model_validator",
|
25
|
+
"pydantic_isinstance",
|
26
|
+
"to_json",
|
27
|
+
"from_json",
|
28
|
+
"ensure_json",
|
23
29
|
]
|
wandb/_pydantic/base.py
CHANGED
@@ -4,9 +4,10 @@ from __future__ import annotations
|
|
4
4
|
|
5
5
|
from typing import TYPE_CHECKING, Any, Callable, Literal, TypeVar
|
6
6
|
|
7
|
-
from pydantic import BaseModel, ConfigDict, Field, Json
|
7
|
+
from pydantic import BaseModel, ConfigDict, Field, Json, StrictStr
|
8
8
|
from typing_extensions import Annotated, TypedDict, Unpack, override
|
9
9
|
|
10
|
+
from .utils import IS_PYDANTIC_V2, to_json
|
10
11
|
from .v1_compat import PydanticCompatMixin
|
11
12
|
|
12
13
|
if TYPE_CHECKING:
|
@@ -36,17 +37,25 @@ MODEL_DUMP_DEFAULTS = ModelDumpKwargs(
|
|
36
37
|
)
|
37
38
|
|
38
39
|
|
39
|
-
#
|
40
|
+
# v1-compatible base class for pydantic types.
|
41
|
+
class CompatBaseModel(PydanticCompatMixin, BaseModel):
|
42
|
+
__doc__ = None # Prevent subclasses from inheriting the BaseModel docstring
|
43
|
+
|
44
|
+
|
45
|
+
# Base class for all GraphQL-generated types.
|
40
46
|
# Omitted from docstring to avoid inclusion in generated docs.
|
41
|
-
class
|
47
|
+
class GQLBase(CompatBaseModel):
|
42
48
|
model_config = ConfigDict(
|
43
|
-
populate_by_name=True,
|
49
|
+
populate_by_name=True, # Discouraged in pydantic v2.11+, will be deprecated in v3
|
50
|
+
validate_by_name=True, # Introduced in pydantic v2.11
|
51
|
+
validate_by_alias=True, # Introduced in pydantic v2.11
|
52
|
+
serialize_by_alias=True, # Introduced in pydantic v2.11
|
44
53
|
validate_assignment=True,
|
45
54
|
validate_default=True,
|
46
|
-
extra="forbid",
|
47
55
|
use_attribute_docstrings=True,
|
48
56
|
from_attributes=True,
|
49
57
|
revalidate_instances="always",
|
58
|
+
protected_namespaces=(), # Some GraphQL fields may begin with "model_"
|
50
59
|
)
|
51
60
|
|
52
61
|
@override
|
@@ -70,44 +79,50 @@ class Base(PydanticCompatMixin, BaseModel):
|
|
70
79
|
return super().model_dump_json(indent=indent, **kwargs)
|
71
80
|
|
72
81
|
|
73
|
-
# Base class with extra customization for GQL generated types.
|
74
|
-
# Omitted from docstring to avoid inclusion in generated docs.
|
75
|
-
class GQLBase(Base):
|
76
|
-
model_config = ConfigDict(
|
77
|
-
extra="ignore",
|
78
|
-
protected_namespaces=(),
|
79
|
-
)
|
80
|
-
|
81
|
-
|
82
82
|
# ------------------------------------------------------------------------------
|
83
83
|
# Reusable annotations for field types
|
84
84
|
T = TypeVar("T")
|
85
85
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
86
|
+
if IS_PYDANTIC_V2 or TYPE_CHECKING:
|
87
|
+
GQLId = Annotated[
|
88
|
+
StrictStr,
|
89
|
+
Field(repr=False, frozen=True),
|
90
|
+
]
|
91
|
+
else:
|
92
|
+
# FIXME: Find a way to fix this for pydantic v1, which doesn't like when
|
93
|
+
# `Field(...)` used in the field assignment AND `Annotated[...]`.
|
94
|
+
# This is a problem for codegen, which can currently outputs e.g.
|
95
|
+
#
|
96
|
+
# class MyModel(GQLBase):
|
97
|
+
# my_id: GQLId = Field(alias="myID")
|
98
|
+
#
|
99
|
+
GQLId = StrictStr # type: ignore[misc]
|
90
100
|
|
91
101
|
Typename = Annotated[
|
92
102
|
T,
|
93
|
-
Field(repr=False, alias="__typename"
|
103
|
+
Field(repr=False, frozen=True, alias="__typename"),
|
94
104
|
]
|
95
105
|
|
96
106
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
#
|
103
|
-
#
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
107
|
+
def ensure_json(v: Any) -> Any:
|
108
|
+
"""In case the incoming value isn't serialized JSON, reserialize it.
|
109
|
+
|
110
|
+
This lets us use `Json[...]` fields with values that are already deserialized.
|
111
|
+
"""
|
112
|
+
# NOTE: Assumes that the deserialized type is not itself a string.
|
113
|
+
# Revisit this if we need to support deserialized types that are str/bytes.
|
114
|
+
return v if isinstance(v, (str, bytes)) else to_json(v)
|
115
|
+
|
116
|
+
|
117
|
+
if IS_PYDANTIC_V2 or TYPE_CHECKING:
|
118
|
+
from pydantic import BeforeValidator, PlainSerializer
|
119
|
+
|
120
|
+
SerializedToJson = Annotated[
|
121
|
+
Json[T],
|
122
|
+
# Allow lenient instantiation/validation: incoming data may already be deserialized.
|
123
|
+
BeforeValidator(ensure_json),
|
124
|
+
PlainSerializer(to_json),
|
125
|
+
]
|
126
|
+
else:
|
127
|
+
# FIXME: Restore, modify, or replace this later after ensuring pydantic v1 compatibility.
|
128
|
+
SerializedToJson = Json[T] # type: ignore[misc]
|
wandb/_pydantic/utils.py
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
"""Internal utilities for working with Pydantic types and data."""
|
2
|
+
|
3
|
+
from __future__ import annotations
|
4
|
+
|
5
|
+
import json
|
6
|
+
import sys
|
7
|
+
from contextlib import suppress
|
8
|
+
from typing import Any, Type
|
9
|
+
|
10
|
+
import pydantic
|
11
|
+
from pydantic import BaseModel, ValidationError
|
12
|
+
from typing_extensions import TypeAlias
|
13
|
+
|
14
|
+
PYTHON_VERSION = sys.version_info
|
15
|
+
|
16
|
+
pydantic_major, *_ = pydantic.VERSION.split(".")
|
17
|
+
IS_PYDANTIC_V2: bool = int(pydantic_major) >= 2
|
18
|
+
|
19
|
+
|
20
|
+
BaseModelType: TypeAlias = Type[BaseModel]
|
21
|
+
|
22
|
+
|
23
|
+
if IS_PYDANTIC_V2:
|
24
|
+
import pydantic_core # pydantic_core is only installed by pydantic v2
|
25
|
+
|
26
|
+
def from_json(s: str) -> Any:
|
27
|
+
"""Quickly deserialize a JSON string to a Python object."""
|
28
|
+
return pydantic_core.from_json(s)
|
29
|
+
|
30
|
+
def to_json(v: Any) -> str:
|
31
|
+
"""Quickly serialize a (possibly Pydantic) object to a JSON string."""
|
32
|
+
return pydantic_core.to_json(v, by_alias=True, round_trip=True).decode("utf-8")
|
33
|
+
|
34
|
+
def pydantic_isinstance(
|
35
|
+
v: Any, classinfo: BaseModelType | tuple[BaseModelType, ...]
|
36
|
+
) -> bool:
|
37
|
+
"""Return True if the object could be parsed into the given Pydantic type.
|
38
|
+
|
39
|
+
This is like a more lenient version of `isinstance()` for use with Pydantic.
|
40
|
+
In Pydantic v2, should be fast since the underlying implementation is in Rust,
|
41
|
+
and it may be preferable over `try:...except ValidationError:...`.
|
42
|
+
|
43
|
+
See: https://docs.pydantic.dev/latest/api/pydantic_core/#pydantic_core.SchemaValidator.isinstance_python
|
44
|
+
"""
|
45
|
+
if isinstance(classinfo, tuple):
|
46
|
+
return any(
|
47
|
+
cls.__pydantic_validator__.isinstance_python(v) for cls in classinfo
|
48
|
+
)
|
49
|
+
cls = classinfo
|
50
|
+
return cls.__pydantic_validator__.isinstance_python(v)
|
51
|
+
|
52
|
+
else:
|
53
|
+
# Pydantic v1 fallback implementations.
|
54
|
+
# These may be noticeably slower, but their primary goal is to ensure
|
55
|
+
# compatibility with Pydantic v1 so long as we need to support it.
|
56
|
+
|
57
|
+
from pydantic.json import pydantic_encoder # Only valid in pydantic v1
|
58
|
+
|
59
|
+
def from_json(s: str) -> Any:
|
60
|
+
return json.loads(s)
|
61
|
+
|
62
|
+
def to_json(v: Any) -> str:
|
63
|
+
return json.dumps(v, default=pydantic_encoder)
|
64
|
+
|
65
|
+
def pydantic_isinstance(
|
66
|
+
v: Any, classinfo: BaseModelType | tuple[BaseModelType, ...]
|
67
|
+
) -> bool:
|
68
|
+
classes = classinfo if isinstance(classinfo, tuple) else (classinfo,)
|
69
|
+
for cls in classes:
|
70
|
+
with suppress(ValidationError):
|
71
|
+
cls.model_validate(v)
|
72
|
+
return True
|
73
|
+
return False
|
wandb/_pydantic/v1_compat.py
CHANGED
@@ -2,26 +2,29 @@
|
|
2
2
|
|
3
3
|
from __future__ import annotations
|
4
4
|
|
5
|
-
import
|
6
|
-
from
|
7
|
-
from
|
8
|
-
|
9
|
-
|
10
|
-
Callable,
|
11
|
-
ClassVar,
|
12
|
-
Literal,
|
13
|
-
Mapping,
|
14
|
-
TypeVar,
|
15
|
-
overload,
|
16
|
-
)
|
5
|
+
import json
|
6
|
+
from functools import lru_cache
|
7
|
+
from inspect import signature
|
8
|
+
from operator import attrgetter
|
9
|
+
from typing import TYPE_CHECKING, Any, Callable, ClassVar, Literal, overload
|
17
10
|
|
18
11
|
import pydantic
|
19
|
-
|
12
|
+
|
13
|
+
from .utils import IS_PYDANTIC_V2, to_json
|
20
14
|
|
21
15
|
if TYPE_CHECKING:
|
22
16
|
from typing import Protocol
|
23
17
|
|
24
18
|
class V1Model(Protocol):
|
19
|
+
# ------------------------------------------------------------------------------
|
20
|
+
# NOTE: These aren't part of the original v1 BaseModel spec, but were added as
|
21
|
+
# internal helpers and are (re-)declared here to satisfy mypy checks.
|
22
|
+
@classmethod
|
23
|
+
def _dump_json_vals(cls, values: dict, by_alias: bool) -> dict: ...
|
24
|
+
|
25
|
+
# ------------------------------------------------------------------------------
|
26
|
+
# These methods are part of the original v1 BaseModel spec.
|
27
|
+
|
25
28
|
__config__: ClassVar[type]
|
26
29
|
__fields__: ClassVar[dict[str, Any]]
|
27
30
|
__fields_set__: set[str]
|
@@ -34,20 +37,10 @@ if TYPE_CHECKING:
|
|
34
37
|
def parse_obj(cls, *args: Any, **kwargs: Any) -> V1Model: ...
|
35
38
|
@classmethod
|
36
39
|
def parse_raw(cls, *args: Any, **kwargs: Any) -> V1Model: ...
|
37
|
-
def dict(self, *args: Any, **kwargs: Any) -> dict[str, Any]: ...
|
38
|
-
def json(self, *args: Any, **kwargs: Any) -> str: ...
|
39
|
-
def copy(self, *args: Any, **kwargs: Any) -> V1Model: ...
|
40
|
-
|
41
40
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
IS_PYDANTIC_V2: bool = int(pydantic_major_version) >= 2
|
46
|
-
|
47
|
-
|
48
|
-
ModelT = TypeVar("ModelT")
|
49
|
-
RT = TypeVar("RT")
|
50
|
-
P = ParamSpec("P")
|
41
|
+
def dict(self, **kwargs: Any) -> dict[str, Any]: ...
|
42
|
+
def json(self, **kwargs: Any) -> str: ...
|
43
|
+
def copy(self, **kwargs: Any) -> V1Model: ...
|
51
44
|
|
52
45
|
|
53
46
|
# Maps {v2 -> v1} model config keys that were renamed in v2.
|
@@ -66,11 +59,17 @@ _V1_CONFIG_KEYS = {
|
|
66
59
|
}
|
67
60
|
|
68
61
|
|
69
|
-
def
|
70
|
-
"""Return a copy of the v2 ConfigDict with renamed v1 keys."""
|
62
|
+
def convert_v2_config(v2_config: dict[str, Any]) -> dict[str, Any]:
|
63
|
+
"""Internal helper: Return a copy of the v2 ConfigDict with renamed v1 keys."""
|
71
64
|
return {_V1_CONFIG_KEYS.get(k, k): v for k, v in v2_config.items()}
|
72
65
|
|
73
66
|
|
67
|
+
@lru_cache(maxsize=None) # Reduce repeat introspection via `signature()`
|
68
|
+
def allowed_arg_names(func: Callable) -> set[str]:
|
69
|
+
"""Internal helper: Return the names of args accepted by the given function."""
|
70
|
+
return set(signature(func).parameters)
|
71
|
+
|
72
|
+
|
74
73
|
# Pydantic BaseModels are defined with a custom metaclass, but its namespace
|
75
74
|
# has changed between pydantic versions.
|
76
75
|
#
|
@@ -87,28 +86,22 @@ class V1MixinMetaclass(PydanticModelMetaclass):
|
|
87
86
|
namespace: dict[str, Any],
|
88
87
|
**kwargs: Any,
|
89
88
|
):
|
90
|
-
#
|
91
|
-
#
|
92
|
-
# class MyModel(BaseModel):
|
89
|
+
# In the class definition, convert the model config, if any:
|
90
|
+
# # BEFORE
|
91
|
+
# class MyModel(BaseModel): # v2 model with `ConfigDict`
|
93
92
|
# model_config = ConfigDict(populate_by_name=True)
|
94
93
|
#
|
95
|
-
#
|
96
|
-
#
|
97
|
-
# class MyModel(BaseModel):
|
94
|
+
# # AFTER
|
95
|
+
# class MyModel(BaseModel): # v1 model with inner `Config` class
|
98
96
|
# class Config:
|
99
97
|
# allow_population_by_field_name = True
|
100
|
-
#
|
101
98
|
if config_dict := namespace.pop("model_config", None):
|
102
|
-
namespace["Config"] = type("Config", (),
|
99
|
+
namespace["Config"] = type("Config", (), convert_v2_config(config_dict))
|
103
100
|
return super().__new__(cls, name, bases, namespace, **kwargs)
|
104
101
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
@property
|
110
|
-
def model_fields(self) -> dict[str, Any]:
|
111
|
-
return self.__fields__
|
102
|
+
@property
|
103
|
+
def model_fields(self) -> dict[str, Any]:
|
104
|
+
return self.__fields__ # type: ignore[deprecated]
|
112
105
|
|
113
106
|
|
114
107
|
# Mixin to ensure compatibility of Pydantic models if Pydantic v1 is detected.
|
@@ -118,6 +111,23 @@ class V1MixinMetaclass(PydanticModelMetaclass):
|
|
118
111
|
# Whenever possible, users should strongly prefer upgrading to Pydantic v2 to
|
119
112
|
# ensure full compatibility.
|
120
113
|
class V1Mixin(metaclass=V1MixinMetaclass):
|
114
|
+
# Internal compat helpers
|
115
|
+
@classmethod
|
116
|
+
def _dump_json_vals(cls, values: dict[str, Any], by_alias: bool) -> dict[str, Any]:
|
117
|
+
"""Reserialize values from `Json`-typed fields after dumping the model to dict."""
|
118
|
+
# Get the expected keys (after `.model_dump()`) for `Json`-typed fields.
|
119
|
+
# Note: In v1, `Json` fields have `ModelField.parse_json == True`
|
120
|
+
json_fields = (f for f in cls.__fields__.values() if f.parse_json) # type: ignore[deprecated]
|
121
|
+
get_key = attrgetter("alias" if by_alias else "name")
|
122
|
+
json_field_keys = set(map(get_key, json_fields))
|
123
|
+
|
124
|
+
return {
|
125
|
+
# Only serialize `Json` fields with non-null values.
|
126
|
+
k: to_json(v) if ((v is not None) and (k in json_field_keys)) else v
|
127
|
+
for k, v in values.items()
|
128
|
+
}
|
129
|
+
|
130
|
+
# ------------------------------------------------------------------------------
|
121
131
|
@classmethod
|
122
132
|
def __try_update_forward_refs__(cls: type[V1Model], **localns: Any) -> None:
|
123
133
|
if hasattr(sup := super(), "__try_update_forward_refs__"):
|
@@ -139,23 +149,35 @@ class V1Mixin(metaclass=V1MixinMetaclass):
|
|
139
149
|
def model_validate_json(cls, *args: Any, **kwargs: Any) -> V1Model:
|
140
150
|
return cls.parse_raw(*args, **kwargs)
|
141
151
|
|
142
|
-
def model_dump(self: V1Model,
|
143
|
-
|
152
|
+
def model_dump(self: V1Model, **kwargs: Any) -> dict[str, Any]:
|
153
|
+
# Pass only kwargs that are allowed in the V1 method.
|
154
|
+
allowed_keys = allowed_arg_names(self.dict) & kwargs.keys()
|
155
|
+
dict_ = self.dict(**{k: kwargs[k] for k in allowed_keys})
|
156
|
+
|
157
|
+
# Ugly hack: Try to serialize `Json` fields correctly when `round_trip=True` in pydantic v1
|
158
|
+
if kwargs.get("round_trip", False):
|
159
|
+
by_alias: bool = kwargs.get("by_alias", False)
|
160
|
+
return self._dump_json_vals(dict_, by_alias=by_alias)
|
161
|
+
|
162
|
+
return dict_
|
144
163
|
|
145
|
-
def model_dump_json(self: V1Model,
|
146
|
-
|
164
|
+
def model_dump_json(self: V1Model, **kwargs: Any) -> str:
|
165
|
+
# Pass only kwargs that are allowed in the V1 method.
|
166
|
+
allowed_keys = allowed_arg_names(self.json) & kwargs.keys()
|
167
|
+
json_ = self.json(**{k: kwargs[k] for k in allowed_keys})
|
147
168
|
|
148
|
-
|
149
|
-
|
169
|
+
# Ugly hack: Try to serialize `Json` fields correctly when `round_trip=True` in pydantic v1
|
170
|
+
if kwargs.get("round_trip", False):
|
171
|
+
by_alias: bool = kwargs.get("by_alias", False)
|
172
|
+
dict_ = json.loads(json_)
|
173
|
+
return json.dumps(self._dump_json_vals(dict_, by_alias=by_alias))
|
150
174
|
|
151
|
-
|
152
|
-
# versions, so this will have to do until changes are needed.
|
153
|
-
if (3, 9) <= PYTHON_VERSION < (3, 13):
|
175
|
+
return json_
|
154
176
|
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
177
|
+
def model_copy(self: V1Model, **kwargs: Any) -> V1Model:
|
178
|
+
# Pass only kwargs that are allowed in the V1 method.
|
179
|
+
allowed_keys = allowed_arg_names(self.copy) & kwargs.keys()
|
180
|
+
return self.copy(**{k: kwargs[k] for k in allowed_keys})
|
159
181
|
|
160
182
|
@property
|
161
183
|
def model_fields_set(self: V1Model) -> set[str]:
|
@@ -191,7 +213,7 @@ else:
|
|
191
213
|
check_fields: bool | None = None,
|
192
214
|
**_: Any,
|
193
215
|
) -> Callable:
|
194
|
-
return pydantic.validator(
|
216
|
+
return pydantic.validator( # type: ignore[deprecated]
|
195
217
|
field,
|
196
218
|
*fields,
|
197
219
|
pre=(mode == "before"),
|
wandb/apis/public/__init__.py
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
from wandb.apis.public.api import Api, RetryingClient, requests
|
2
2
|
from wandb.apis.public.artifacts import (
|
3
|
-
ARTIFACT_FILES_FRAGMENT,
|
4
|
-
ARTIFACTS_TYPES_FRAGMENT,
|
5
3
|
ArtifactCollection,
|
6
4
|
ArtifactCollections,
|
7
5
|
ArtifactFiles,
|
@@ -10,8 +8,10 @@ from wandb.apis.public.artifacts import (
|
|
10
8
|
ArtifactTypes,
|
11
9
|
RunArtifacts,
|
12
10
|
)
|
11
|
+
from wandb.apis.public.automations import Automations
|
13
12
|
from wandb.apis.public.files import FILE_FRAGMENT, File, Files
|
14
13
|
from wandb.apis.public.history import HistoryScan, SampledHistoryScan
|
14
|
+
from wandb.apis.public.integrations import SlackIntegrations, WebhookIntegrations
|
15
15
|
from wandb.apis.public.jobs import (
|
16
16
|
Job,
|
17
17
|
QueuedRun,
|