wandb 0.19.9__py3-none-macosx_11_0_arm64.whl → 0.19.10__py3-none-macosx_11_0_arm64.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 +4 -1
- wandb/_pydantic/__init__.py +14 -7
- wandb/_pydantic/base.py +44 -9
- wandb/_pydantic/utils.py +66 -0
- wandb/_pydantic/v1_compat.py +78 -56
- wandb/apis/public/__init__.py +2 -2
- wandb/apis/public/api.py +114 -2
- wandb/apis/public/artifacts.py +365 -673
- wandb/apis/public/automations.py +69 -0
- wandb/apis/public/integrations.py +168 -0
- wandb/apis/public/projects.py +29 -0
- wandb/apis/public/utils.py +107 -1
- wandb/automations/__init__.py +81 -0
- wandb/automations/_filters/__init__.py +40 -0
- wandb/automations/_filters/expressions.py +179 -0
- wandb/automations/_filters/operators.py +267 -0
- wandb/automations/_filters/run_metrics.py +183 -0
- wandb/automations/_generated/__init__.py +184 -0
- wandb/automations/_generated/create_filter_trigger.py +21 -0
- wandb/automations/_generated/create_generic_webhook_integration.py +43 -0
- wandb/automations/_generated/delete_trigger.py +19 -0
- wandb/automations/_generated/enums.py +33 -0
- wandb/automations/_generated/fragments.py +343 -0
- wandb/automations/_generated/generic_webhook_integrations_by_entity.py +22 -0
- wandb/automations/_generated/get_triggers.py +24 -0
- wandb/automations/_generated/get_triggers_by_entity.py +24 -0
- wandb/automations/_generated/input_types.py +104 -0
- wandb/automations/_generated/integrations_by_entity.py +22 -0
- wandb/automations/_generated/operations.py +710 -0
- wandb/automations/_generated/slack_integrations_by_entity.py +22 -0
- wandb/automations/_generated/update_filter_trigger.py +21 -0
- wandb/automations/_utils.py +123 -0
- wandb/automations/_validators.py +73 -0
- wandb/automations/actions.py +205 -0
- wandb/automations/automations.py +109 -0
- wandb/automations/events.py +235 -0
- wandb/automations/integrations.py +26 -0
- wandb/automations/scopes.py +76 -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/integration/keras/keras.py +2 -1
- wandb/integration/langchain/wandb_tracer.py +2 -1
- wandb/jupyter.py +137 -118
- wandb/old/summary.py +0 -2
- wandb/proto/v3/wandb_internal_pb2.py +293 -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 +248 -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_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/fragments.py +186 -0
- wandb/sdk/artifacts/_generated/input_types.py +16 -0
- wandb/sdk/artifacts/_generated/move_artifact_collection.py +35 -0
- wandb/sdk/artifacts/_generated/operations.py +510 -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_portfolio.py +35 -0
- wandb/sdk/artifacts/_generated/update_artifact_sequence.py +35 -0
- wandb/sdk/artifacts/_graphql_fragments.py +56 -79
- wandb/sdk/artifacts/artifact.py +40 -13
- wandb/sdk/artifacts/artifact_manifest_entry.py +2 -1
- wandb/sdk/artifacts/storage_handlers/azure_handler.py +1 -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 +14 -26
- wandb/sdk/interface/interface.py +2 -0
- wandb/sdk/internal/profiler.py +6 -5
- wandb/sdk/internal/run.py +13 -6
- 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/service/server_sock.py +19 -14
- wandb/sdk/service/service.py +9 -7
- wandb/sdk/service/streams.py +5 -0
- wandb/sdk/verify/verify.py +6 -3
- wandb/sdk/wandb_init.py +185 -65
- wandb/sdk/wandb_login.py +13 -4
- wandb/sdk/wandb_run.py +382 -286
- wandb/sdk/wandb_settings.py +21 -3
- wandb/sdk/wandb_setup.py +49 -0
- wandb/util.py +29 -29
- {wandb-0.19.9.dist-info → wandb-0.19.10.dist-info}/METADATA +5 -5
- {wandb-0.19.9.dist-info → wandb-0.19.10.dist-info}/RECORD +125 -72
- 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.10.dist-info}/WHEEL +0 -0
- {wandb-0.19.9.dist-info → wandb-0.19.10.dist-info}/entry_points.txt +0 -0
- {wandb-0.19.9.dist-info → wandb-0.19.10.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,42 @@
|
|
1
|
+
# Generated by ariadne-codegen
|
2
|
+
# Source: tools/graphql_codegen/artifacts/
|
3
|
+
|
4
|
+
from __future__ import annotations
|
5
|
+
|
6
|
+
from typing import Literal, Optional
|
7
|
+
|
8
|
+
from pydantic import Field
|
9
|
+
|
10
|
+
from wandb._pydantic import GQLBase, Typename
|
11
|
+
|
12
|
+
from .fragments import ArtifactsFragment
|
13
|
+
|
14
|
+
|
15
|
+
class ProjectArtifacts(GQLBase):
|
16
|
+
project: Optional[ProjectArtifactsProject]
|
17
|
+
|
18
|
+
|
19
|
+
class ProjectArtifactsProject(GQLBase):
|
20
|
+
artifact_type: Optional[ProjectArtifactsProjectArtifactType] = Field(
|
21
|
+
alias="artifactType"
|
22
|
+
)
|
23
|
+
|
24
|
+
|
25
|
+
class ProjectArtifactsProjectArtifactType(GQLBase):
|
26
|
+
artifact_collection: Optional[
|
27
|
+
ProjectArtifactsProjectArtifactTypeArtifactCollection
|
28
|
+
] = Field(alias="artifactCollection")
|
29
|
+
|
30
|
+
|
31
|
+
class ProjectArtifactsProjectArtifactTypeArtifactCollection(GQLBase):
|
32
|
+
typename__: Typename[
|
33
|
+
Literal["ArtifactCollection", "ArtifactPortfolio", "ArtifactSequence"]
|
34
|
+
]
|
35
|
+
name: str
|
36
|
+
artifacts: Optional[ArtifactsFragment]
|
37
|
+
|
38
|
+
|
39
|
+
ProjectArtifacts.model_rebuild()
|
40
|
+
ProjectArtifactsProject.model_rebuild()
|
41
|
+
ProjectArtifactsProjectArtifactType.model_rebuild()
|
42
|
+
ProjectArtifactsProjectArtifactTypeArtifactCollection.model_rebuild()
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# Generated by ariadne-codegen
|
2
|
+
# Source: tools/graphql_codegen/artifacts/
|
3
|
+
|
4
|
+
from __future__ import annotations
|
5
|
+
|
6
|
+
from typing import List, Optional
|
7
|
+
|
8
|
+
from pydantic import Field
|
9
|
+
|
10
|
+
from wandb._pydantic import GQLBase
|
11
|
+
|
12
|
+
from .fragments import ArtifactFragment
|
13
|
+
|
14
|
+
|
15
|
+
class RunInputArtifacts(GQLBase):
|
16
|
+
project: Optional[RunInputArtifactsProject]
|
17
|
+
|
18
|
+
|
19
|
+
class RunInputArtifactsProject(GQLBase):
|
20
|
+
run: Optional[RunInputArtifactsProjectRun]
|
21
|
+
|
22
|
+
|
23
|
+
class RunInputArtifactsProjectRun(GQLBase):
|
24
|
+
input_artifacts: Optional[RunInputArtifactsProjectRunInputArtifacts] = Field(
|
25
|
+
alias="inputArtifacts"
|
26
|
+
)
|
27
|
+
|
28
|
+
|
29
|
+
class RunInputArtifactsProjectRunInputArtifacts(GQLBase):
|
30
|
+
total_count: int = Field(alias="totalCount")
|
31
|
+
edges: List[RunInputArtifactsProjectRunInputArtifactsEdges]
|
32
|
+
page_info: RunInputArtifactsProjectRunInputArtifactsPageInfo = Field(
|
33
|
+
alias="pageInfo"
|
34
|
+
)
|
35
|
+
|
36
|
+
|
37
|
+
class RunInputArtifactsProjectRunInputArtifactsEdges(GQLBase):
|
38
|
+
node: Optional[ArtifactFragment]
|
39
|
+
cursor: str
|
40
|
+
|
41
|
+
|
42
|
+
class RunInputArtifactsProjectRunInputArtifactsPageInfo(GQLBase):
|
43
|
+
end_cursor: Optional[str] = Field(alias="endCursor")
|
44
|
+
has_next_page: bool = Field(alias="hasNextPage")
|
45
|
+
|
46
|
+
|
47
|
+
RunInputArtifacts.model_rebuild()
|
48
|
+
RunInputArtifactsProject.model_rebuild()
|
49
|
+
RunInputArtifactsProjectRun.model_rebuild()
|
50
|
+
RunInputArtifactsProjectRunInputArtifacts.model_rebuild()
|
51
|
+
RunInputArtifactsProjectRunInputArtifactsEdges.model_rebuild()
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# Generated by ariadne-codegen
|
2
|
+
# Source: tools/graphql_codegen/artifacts/
|
3
|
+
|
4
|
+
from __future__ import annotations
|
5
|
+
|
6
|
+
from typing import List, Optional
|
7
|
+
|
8
|
+
from pydantic import Field
|
9
|
+
|
10
|
+
from wandb._pydantic import GQLBase
|
11
|
+
|
12
|
+
from .fragments import ArtifactFragment
|
13
|
+
|
14
|
+
|
15
|
+
class RunOutputArtifacts(GQLBase):
|
16
|
+
project: Optional[RunOutputArtifactsProject]
|
17
|
+
|
18
|
+
|
19
|
+
class RunOutputArtifactsProject(GQLBase):
|
20
|
+
run: Optional[RunOutputArtifactsProjectRun]
|
21
|
+
|
22
|
+
|
23
|
+
class RunOutputArtifactsProjectRun(GQLBase):
|
24
|
+
output_artifacts: Optional[RunOutputArtifactsProjectRunOutputArtifacts] = Field(
|
25
|
+
alias="outputArtifacts"
|
26
|
+
)
|
27
|
+
|
28
|
+
|
29
|
+
class RunOutputArtifactsProjectRunOutputArtifacts(GQLBase):
|
30
|
+
total_count: int = Field(alias="totalCount")
|
31
|
+
edges: List[RunOutputArtifactsProjectRunOutputArtifactsEdges]
|
32
|
+
page_info: RunOutputArtifactsProjectRunOutputArtifactsPageInfo = Field(
|
33
|
+
alias="pageInfo"
|
34
|
+
)
|
35
|
+
|
36
|
+
|
37
|
+
class RunOutputArtifactsProjectRunOutputArtifactsEdges(GQLBase):
|
38
|
+
node: Optional[ArtifactFragment]
|
39
|
+
cursor: str
|
40
|
+
|
41
|
+
|
42
|
+
class RunOutputArtifactsProjectRunOutputArtifactsPageInfo(GQLBase):
|
43
|
+
end_cursor: Optional[str] = Field(alias="endCursor")
|
44
|
+
has_next_page: bool = Field(alias="hasNextPage")
|
45
|
+
|
46
|
+
|
47
|
+
RunOutputArtifacts.model_rebuild()
|
48
|
+
RunOutputArtifactsProject.model_rebuild()
|
49
|
+
RunOutputArtifactsProjectRun.model_rebuild()
|
50
|
+
RunOutputArtifactsProjectRunOutputArtifacts.model_rebuild()
|
51
|
+
RunOutputArtifactsProjectRunOutputArtifactsEdges.model_rebuild()
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# Generated by ariadne-codegen
|
2
|
+
# Source: tools/graphql_codegen/artifacts/
|
3
|
+
|
4
|
+
from __future__ import annotations
|
5
|
+
|
6
|
+
from typing import Literal, Optional
|
7
|
+
|
8
|
+
from pydantic import Field
|
9
|
+
|
10
|
+
from wandb._pydantic import GQLBase, GQLId, Typename
|
11
|
+
|
12
|
+
|
13
|
+
class UpdateArtifactPortfolio(GQLBase):
|
14
|
+
update_artifact_portfolio: Optional[
|
15
|
+
UpdateArtifactPortfolioUpdateArtifactPortfolio
|
16
|
+
] = Field(alias="updateArtifactPortfolio")
|
17
|
+
|
18
|
+
|
19
|
+
class UpdateArtifactPortfolioUpdateArtifactPortfolio(GQLBase):
|
20
|
+
artifact_collection: UpdateArtifactPortfolioUpdateArtifactPortfolioArtifactCollection = Field(
|
21
|
+
alias="artifactCollection"
|
22
|
+
)
|
23
|
+
|
24
|
+
|
25
|
+
class UpdateArtifactPortfolioUpdateArtifactPortfolioArtifactCollection(GQLBase):
|
26
|
+
typename__: Typename[
|
27
|
+
Literal["ArtifactCollection", "ArtifactPortfolio", "ArtifactSequence"]
|
28
|
+
]
|
29
|
+
id: GQLId
|
30
|
+
name: str
|
31
|
+
description: Optional[str]
|
32
|
+
|
33
|
+
|
34
|
+
UpdateArtifactPortfolio.model_rebuild()
|
35
|
+
UpdateArtifactPortfolioUpdateArtifactPortfolio.model_rebuild()
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# Generated by ariadne-codegen
|
2
|
+
# Source: tools/graphql_codegen/artifacts/
|
3
|
+
|
4
|
+
from __future__ import annotations
|
5
|
+
|
6
|
+
from typing import Literal, Optional
|
7
|
+
|
8
|
+
from pydantic import Field
|
9
|
+
|
10
|
+
from wandb._pydantic import GQLBase, GQLId, Typename
|
11
|
+
|
12
|
+
|
13
|
+
class UpdateArtifactSequence(GQLBase):
|
14
|
+
update_artifact_sequence: Optional[UpdateArtifactSequenceUpdateArtifactSequence] = (
|
15
|
+
Field(alias="updateArtifactSequence")
|
16
|
+
)
|
17
|
+
|
18
|
+
|
19
|
+
class UpdateArtifactSequenceUpdateArtifactSequence(GQLBase):
|
20
|
+
artifact_collection: UpdateArtifactSequenceUpdateArtifactSequenceArtifactCollection = Field(
|
21
|
+
alias="artifactCollection"
|
22
|
+
)
|
23
|
+
|
24
|
+
|
25
|
+
class UpdateArtifactSequenceUpdateArtifactSequenceArtifactCollection(GQLBase):
|
26
|
+
typename__: Typename[
|
27
|
+
Literal["ArtifactCollection", "ArtifactPortfolio", "ArtifactSequence"]
|
28
|
+
]
|
29
|
+
id: GQLId
|
30
|
+
name: str
|
31
|
+
description: Optional[str]
|
32
|
+
|
33
|
+
|
34
|
+
UpdateArtifactSequence.model_rebuild()
|
35
|
+
UpdateArtifactSequenceUpdateArtifactSequence.model_rebuild()
|
@@ -1,62 +1,57 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
from textwrap import dedent
|
4
|
+
|
5
|
+
from wandb_graphql.language.printer import print_ast
|
6
|
+
|
7
|
+
from wandb.apis.public.utils import gql_compat
|
1
8
|
from wandb.sdk.internal.internal_api import Api as InternalApi
|
2
9
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
createdAt
|
11
|
-
}
|
12
|
-
cursor
|
10
|
+
OMITTABLE_ARTIFACT_FIELDS = frozenset(
|
11
|
+
{
|
12
|
+
"ttlDurationSeconds",
|
13
|
+
"ttlIsInherited",
|
14
|
+
"aliases",
|
15
|
+
"tags",
|
16
|
+
"historyStep",
|
13
17
|
}
|
14
|
-
|
15
|
-
endCursor
|
16
|
-
hasNextPage
|
17
|
-
}
|
18
|
-
}
|
19
|
-
"""
|
18
|
+
)
|
20
19
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
url
|
27
|
-
sizeBytes
|
28
|
-
storagePath
|
29
|
-
mimetype
|
30
|
-
updatedAt
|
31
|
-
digest
|
32
|
-
md5
|
33
|
-
directUrl
|
34
|
-
}
|
35
|
-
cursor
|
36
|
-
}
|
37
|
-
pageInfo {
|
38
|
-
endCursor
|
39
|
-
hasNextPage
|
40
|
-
}
|
41
|
-
}"""
|
20
|
+
|
21
|
+
def omit_artifact_fields(api: InternalApi) -> set[str]:
|
22
|
+
"""Return names of Artifact fields to remove from GraphQL requests (for server compatibility)."""
|
23
|
+
allowed_fields = set(api.server_artifact_introspection())
|
24
|
+
return set(OMITTABLE_ARTIFACT_FIELDS - allowed_fields)
|
42
25
|
|
43
26
|
|
44
27
|
def _gql_artifact_fragment(include_aliases: bool = True) -> str:
|
45
28
|
"""Return a GraphQL query fragment with all parseable Artifact attributes."""
|
46
|
-
|
29
|
+
omit_fields = omit_artifact_fields(api=InternalApi())
|
47
30
|
|
48
|
-
|
49
|
-
|
31
|
+
# Respect the `include_aliases` flag
|
32
|
+
if not include_aliases:
|
33
|
+
omit_fields.add("aliases")
|
50
34
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
35
|
+
artifact_fragment_str = dedent(
|
36
|
+
"""\
|
37
|
+
fragment ArtifactFragment on Artifact {
|
38
|
+
id
|
39
|
+
artifactSequence {
|
40
|
+
project {
|
41
|
+
entityName
|
42
|
+
name
|
43
|
+
}
|
44
|
+
name
|
45
|
+
}
|
46
|
+
versionIndex
|
47
|
+
artifactType {
|
48
|
+
name
|
49
|
+
}
|
50
|
+
description
|
51
|
+
metadata
|
52
|
+
ttlDurationSeconds
|
53
|
+
ttlIsInherited
|
54
|
+
aliases {
|
60
55
|
artifactCollection {
|
61
56
|
project {
|
62
57
|
entityName
|
@@ -65,43 +60,25 @@ def _gql_artifact_fragment(include_aliases: bool = True) -> str:
|
|
65
60
|
name
|
66
61
|
}
|
67
62
|
alias
|
68
|
-
}
|
69
|
-
|
70
|
-
else ""
|
71
|
-
)
|
72
|
-
|
73
|
-
return f"""
|
74
|
-
fragment ArtifactFragment on Artifact {{
|
75
|
-
id
|
76
|
-
artifactSequence {{
|
77
|
-
project {{
|
78
|
-
entityName
|
79
|
-
name
|
80
|
-
}}
|
81
|
-
name
|
82
|
-
}}
|
83
|
-
versionIndex
|
84
|
-
artifactType {{
|
63
|
+
}
|
64
|
+
tags {
|
85
65
|
name
|
86
|
-
}
|
87
|
-
|
88
|
-
metadata
|
89
|
-
{ttl_duration_seconds}
|
90
|
-
{ttl_is_inherited}
|
91
|
-
{aliases}
|
92
|
-
{tags}
|
66
|
+
}
|
67
|
+
historyStep
|
93
68
|
state
|
94
|
-
currentManifest {
|
95
|
-
file {
|
69
|
+
currentManifest {
|
70
|
+
file {
|
96
71
|
directUrl
|
97
|
-
}
|
98
|
-
}
|
72
|
+
}
|
73
|
+
}
|
99
74
|
commitHash
|
100
75
|
fileCount
|
101
76
|
createdAt
|
102
77
|
updatedAt
|
103
|
-
}
|
104
|
-
|
78
|
+
}"""
|
79
|
+
)
|
80
|
+
compat_doc = gql_compat(artifact_fragment_str, omit_fields=omit_fields)
|
81
|
+
return print_ast(compat_doc)
|
105
82
|
|
106
83
|
|
107
84
|
def _gql_registry_fragment() -> str:
|
wandb/sdk/artifacts/artifact.py
CHANGED
@@ -31,6 +31,8 @@ from wandb.apis.public import ArtifactCollection, ArtifactFiles, RetryingClient,
|
|
31
31
|
from wandb.data_types import WBValue
|
32
32
|
from wandb.errors.term import termerror, termlog, termwarn
|
33
33
|
from wandb.proto import wandb_internal_pb2 as pb
|
34
|
+
from wandb.proto.wandb_deprecated import Deprecated
|
35
|
+
from wandb.sdk import wandb_setup
|
34
36
|
from wandb.sdk.artifacts._graphql_fragments import _gql_artifact_fragment
|
35
37
|
from wandb.sdk.artifacts._validators import (
|
36
38
|
ensure_logged,
|
@@ -59,7 +61,7 @@ from wandb.sdk.data_types._dtypes import TypeRegistry
|
|
59
61
|
from wandb.sdk.internal.internal_api import Api as InternalApi
|
60
62
|
from wandb.sdk.internal.thread_local_settings import _thread_local_api_settings
|
61
63
|
from wandb.sdk.lib import filesystem, retry, runid, telemetry
|
62
|
-
from wandb.sdk.lib.deprecate import
|
64
|
+
from wandb.sdk.lib.deprecate import deprecate
|
63
65
|
from wandb.sdk.lib.hashutil import B64MD5, b64_to_hex_id, md5_file_b64
|
64
66
|
from wandb.sdk.lib.paths import FilePathStr, LogicalPath, StrPath, URIStr
|
65
67
|
from wandb.sdk.lib.runid import generate_id
|
@@ -189,6 +191,7 @@ class Artifact:
|
|
189
191
|
self._created_at: str | None = None
|
190
192
|
self._updated_at: str | None = None
|
191
193
|
self._final: bool = False
|
194
|
+
self._history_step: int | None = None
|
192
195
|
|
193
196
|
# Cache.
|
194
197
|
artifact_instance_cache[self._client_id] = self
|
@@ -409,6 +412,7 @@ class Artifact:
|
|
409
412
|
self._file_count = attrs["fileCount"]
|
410
413
|
self._created_at = attrs["createdAt"]
|
411
414
|
self._updated_at = attrs["updatedAt"]
|
415
|
+
self._history_step = attrs.get("historyStep", None)
|
412
416
|
|
413
417
|
@ensure_logged
|
414
418
|
def new_draft(self) -> Artifact:
|
@@ -886,6 +890,26 @@ class Artifact:
|
|
886
890
|
assert self._created_at is not None
|
887
891
|
return self._updated_at or self._created_at
|
888
892
|
|
893
|
+
@property
|
894
|
+
@ensure_logged
|
895
|
+
def history_step(self) -> int | None:
|
896
|
+
"""The nearest step at which history metrics were logged for the source run of the artifact.
|
897
|
+
|
898
|
+
Examples:
|
899
|
+
```python
|
900
|
+
run = artifact.logged_by()
|
901
|
+
if run and (artifact.history_step is not None):
|
902
|
+
history = run.sample_history(
|
903
|
+
min_step=artifact.history_step,
|
904
|
+
max_step=artifact.history_step + 1,
|
905
|
+
keys=["my_metric"],
|
906
|
+
)
|
907
|
+
```
|
908
|
+
"""
|
909
|
+
if self._history_step is None:
|
910
|
+
return None
|
911
|
+
return max(0, self._history_step - 1)
|
912
|
+
|
889
913
|
# State management.
|
890
914
|
|
891
915
|
def finalize(self) -> None:
|
@@ -931,7 +955,12 @@ class Artifact:
|
|
931
955
|
with telemetry.context() as tel:
|
932
956
|
tel.feature.artifact_incremental = True
|
933
957
|
|
934
|
-
|
958
|
+
singleton = wandb_setup._setup(start_service=False)
|
959
|
+
|
960
|
+
if run := singleton.most_recent_active_run:
|
961
|
+
# TODO: Deprecate and encourage explicit log_artifact().
|
962
|
+
run.log_artifact(self)
|
963
|
+
else:
|
935
964
|
if settings is None:
|
936
965
|
settings = wandb.Settings(silent="true")
|
937
966
|
with wandb.init( # type: ignore
|
@@ -946,8 +975,6 @@ class Artifact:
|
|
946
975
|
with telemetry.context(run=run) as tel:
|
947
976
|
tel.feature.artifact_incremental = True
|
948
977
|
run.log_artifact(self)
|
949
|
-
else:
|
950
|
-
wandb.run.log_artifact(self)
|
951
978
|
|
952
979
|
def _set_save_handle(
|
953
980
|
self,
|
@@ -1771,15 +1798,10 @@ class Artifact:
|
|
1771
1798
|
|
1772
1799
|
Raises:
|
1773
1800
|
ArtifactNotLoggedError: If the artifact is not logged.
|
1774
|
-
RuntimeError: If the artifact is attempted to be downloaded in offline mode.
|
1775
1801
|
"""
|
1776
1802
|
root = FilePathStr(str(root or self._default_root()))
|
1777
1803
|
self._add_download_root(root)
|
1778
1804
|
|
1779
|
-
# TODO: we need a better way to check for offline mode across the app, as this is an anti-pattern
|
1780
|
-
if env.is_offline() or util._is_offline():
|
1781
|
-
raise RuntimeError("Cannot download artifacts in offline mode.")
|
1782
|
-
|
1783
1805
|
# TODO: download artifacts using core when implemented
|
1784
1806
|
# if is_require_core():
|
1785
1807
|
# return self._download_using_core(
|
@@ -1806,6 +1828,7 @@ class Artifact:
|
|
1806
1828
|
|
1807
1829
|
from wandb.sdk.backend.backend import Backend
|
1808
1830
|
|
1831
|
+
# TODO: Create a special stream instead of relying on an existing run.
|
1809
1832
|
if wandb.run is None:
|
1810
1833
|
wl = wandb.setup()
|
1811
1834
|
|
@@ -2227,16 +2250,20 @@ class Artifact:
|
|
2227
2250
|
Raises:
|
2228
2251
|
ArtifactNotLoggedError: If the artifact is not logged.
|
2229
2252
|
"""
|
2230
|
-
|
2231
|
-
|
2253
|
+
singleton = wandb_setup._setup(start_service=False)
|
2254
|
+
|
2255
|
+
if run := singleton.most_recent_active_run:
|
2256
|
+
# TODO: Deprecate and encourage explicit link_artifact().
|
2257
|
+
run.link_artifact(self, target_path, aliases)
|
2258
|
+
|
2259
|
+
else:
|
2260
|
+
with wandb.init(
|
2232
2261
|
entity=self._source_entity,
|
2233
2262
|
project=self._source_project,
|
2234
2263
|
job_type="auto",
|
2235
2264
|
settings=wandb.Settings(silent="true"),
|
2236
2265
|
) as run:
|
2237
2266
|
run.link_artifact(self, target_path, aliases)
|
2238
|
-
else:
|
2239
|
-
wandb.run.link_artifact(self, target_path, aliases)
|
2240
2267
|
|
2241
2268
|
@ensure_logged
|
2242
2269
|
def unlink(self) -> None:
|
@@ -9,8 +9,9 @@ from pathlib import Path
|
|
9
9
|
from typing import TYPE_CHECKING
|
10
10
|
from urllib.parse import urlparse
|
11
11
|
|
12
|
+
from wandb.proto.wandb_deprecated import Deprecated
|
12
13
|
from wandb.sdk.lib import filesystem
|
13
|
-
from wandb.sdk.lib.deprecate import
|
14
|
+
from wandb.sdk.lib.deprecate import deprecate
|
14
15
|
from wandb.sdk.lib.hashutil import (
|
15
16
|
B64MD5,
|
16
17
|
ETag,
|
@@ -171,6 +171,7 @@ class AzureHandler(StorageHandler):
|
|
171
171
|
def _get_credential(
|
172
172
|
self, account_url: str
|
173
173
|
) -> azure.identity.DefaultAzureCredential | str:
|
174
|
+
# NOTE: Always returns default credential for reinit="create_new" runs.
|
174
175
|
if (
|
175
176
|
wandb.run
|
176
177
|
and wandb.run.settings.azure_account_url_to_access_key is not None
|
@@ -7,7 +7,6 @@ from typing import TYPE_CHECKING, Any, Dict, Optional, Sequence, Type, Union, ca
|
|
7
7
|
|
8
8
|
import wandb
|
9
9
|
from wandb import util
|
10
|
-
from wandb._globals import _datatypes_callback
|
11
10
|
from wandb.sdk.lib import filesystem
|
12
11
|
from wandb.sdk.lib.paths import LogicalPath
|
13
12
|
|
@@ -192,7 +191,7 @@ class Media(WBValue):
|
|
192
191
|
shutil.move(self._path, new_path)
|
193
192
|
self._path = new_path
|
194
193
|
self._is_tmp = False
|
195
|
-
|
194
|
+
run._publish_file(media_path)
|
196
195
|
else:
|
197
196
|
try:
|
198
197
|
shutil.copy(self._path, new_path)
|
@@ -200,7 +199,7 @@ class Media(WBValue):
|
|
200
199
|
if not ignore_copy_err:
|
201
200
|
raise e
|
202
201
|
self._path = new_path
|
203
|
-
|
202
|
+
run._publish_file(media_path)
|
204
203
|
|
205
204
|
def to_json(self, run: Union["LocalRun", "Artifact"]) -> dict:
|
206
205
|
"""Serialize the object into a JSON blob.
|
@@ -1,7 +1,7 @@
|
|
1
1
|
from typing import TYPE_CHECKING, Any, ClassVar, Dict, List, Optional, Type, Union
|
2
2
|
|
3
|
-
import wandb
|
4
3
|
from wandb import util
|
4
|
+
from wandb.sdk import wandb_setup
|
5
5
|
|
6
6
|
if TYPE_CHECKING: # pragma: no cover
|
7
7
|
from wandb.sdk.artifacts.artifact import Artifact
|
@@ -11,6 +11,31 @@ if TYPE_CHECKING: # pragma: no cover
|
|
11
11
|
TypeMappingType = Dict[str, Type["WBValue"]]
|
12
12
|
|
13
13
|
|
14
|
+
def _is_maybe_offline() -> bool:
|
15
|
+
"""Guess whether wandb is configured to be offline.
|
16
|
+
|
17
|
+
This is an anti-pattern because there is no library-level "offline" mode:
|
18
|
+
only runs can be offline. Online and offline runs can exist in the same
|
19
|
+
process. This function is a heuristic that works only if there is at most
|
20
|
+
one run in the process, and could otherwise produce unexpected results.
|
21
|
+
|
22
|
+
Returns:
|
23
|
+
Whether the user likely configured wandb to be offline.
|
24
|
+
"""
|
25
|
+
singleton = wandb_setup._setup(start_service=False)
|
26
|
+
|
27
|
+
# First check: if there's a run, check if it is offline.
|
28
|
+
#
|
29
|
+
# This covers uses like `wandb.init(mode="offline")` which don't modify
|
30
|
+
# the singleton's settings.
|
31
|
+
if run := singleton.most_recent_active_run:
|
32
|
+
return run.offline
|
33
|
+
|
34
|
+
# Second check: default to global defaults derived from environment
|
35
|
+
# variables or passed explicitly to `wandb.setup()`.
|
36
|
+
return singleton.settings._offline
|
37
|
+
|
38
|
+
|
14
39
|
def _server_accepts_client_ids() -> bool:
|
15
40
|
from wandb.util import parse_version
|
16
41
|
|
@@ -25,15 +50,13 @@ def _server_accepts_client_ids() -> bool:
|
|
25
50
|
# AS OF NOW, 2024/11/06, we assume that all customer's server deployments accept
|
26
51
|
# client IDs.
|
27
52
|
|
28
|
-
if
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
return False
|
34
|
-
# Assume client IDs are accepted
|
53
|
+
if _is_maybe_offline():
|
54
|
+
singleton = wandb_setup._setup(start_service=False)
|
55
|
+
|
56
|
+
if run := singleton.most_recent_active_run:
|
57
|
+
return run._settings.allow_offline_artifacts
|
35
58
|
else:
|
36
|
-
return
|
59
|
+
return singleton.settings.allow_offline_artifacts
|
37
60
|
|
38
61
|
# If the script is online, request the max_cli_version and ensure the server
|
39
62
|
# is of a high enough version.
|
@@ -240,7 +263,7 @@ class WBValue:
|
|
240
263
|
self._artifact_target
|
241
264
|
and self._artifact_target.name
|
242
265
|
and self._artifact_target.artifact._is_draft_save_started()
|
243
|
-
and not
|
266
|
+
and not _is_maybe_offline()
|
244
267
|
and not _server_accepts_client_ids()
|
245
268
|
):
|
246
269
|
self._artifact_target.artifact.wait()
|
@@ -271,7 +294,7 @@ class WBValue:
|
|
271
294
|
self._artifact_target
|
272
295
|
and self._artifact_target.name
|
273
296
|
and self._artifact_target.artifact._is_draft_save_started()
|
274
|
-
and not
|
297
|
+
and not _is_maybe_offline()
|
275
298
|
and not _server_accepts_client_ids()
|
276
299
|
):
|
277
300
|
self._artifact_target.artifact.wait()
|