wandb 0.22.0__py3-none-macosx_12_0_arm64.whl → 0.22.2__py3-none-macosx_12_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.
Files changed (114) hide show
  1. wandb/__init__.py +1 -1
  2. wandb/__init__.pyi +8 -5
  3. wandb/_pydantic/__init__.py +12 -11
  4. wandb/_pydantic/base.py +49 -19
  5. wandb/apis/__init__.py +2 -0
  6. wandb/apis/attrs.py +2 -0
  7. wandb/apis/importers/internals/internal.py +16 -23
  8. wandb/apis/internal.py +2 -0
  9. wandb/apis/normalize.py +2 -0
  10. wandb/apis/public/__init__.py +3 -2
  11. wandb/apis/public/api.py +215 -164
  12. wandb/apis/public/artifacts.py +23 -20
  13. wandb/apis/public/const.py +2 -0
  14. wandb/apis/public/files.py +33 -24
  15. wandb/apis/public/history.py +2 -0
  16. wandb/apis/public/jobs.py +20 -18
  17. wandb/apis/public/projects.py +4 -2
  18. wandb/apis/public/query_generator.py +3 -0
  19. wandb/apis/public/registries/__init__.py +7 -0
  20. wandb/apis/public/registries/_freezable_list.py +9 -12
  21. wandb/apis/public/registries/registries_search.py +8 -6
  22. wandb/apis/public/registries/registry.py +22 -17
  23. wandb/apis/public/reports.py +2 -0
  24. wandb/apis/public/runs.py +261 -57
  25. wandb/apis/public/sweeps.py +10 -9
  26. wandb/apis/public/teams.py +2 -0
  27. wandb/apis/public/users.py +2 -0
  28. wandb/apis/public/utils.py +16 -15
  29. wandb/automations/_generated/__init__.py +54 -127
  30. wandb/automations/_generated/create_generic_webhook_integration.py +1 -7
  31. wandb/automations/_generated/fragments.py +26 -91
  32. wandb/bin/gpu_stats +0 -0
  33. wandb/bin/wandb-core +0 -0
  34. wandb/cli/beta.py +16 -2
  35. wandb/cli/beta_leet.py +74 -0
  36. wandb/cli/beta_sync.py +9 -11
  37. wandb/cli/cli.py +34 -7
  38. wandb/errors/errors.py +3 -3
  39. wandb/proto/v3/wandb_api_pb2.py +86 -0
  40. wandb/proto/v3/wandb_internal_pb2.py +352 -351
  41. wandb/proto/v3/wandb_settings_pb2.py +2 -2
  42. wandb/proto/v3/wandb_sync_pb2.py +19 -6
  43. wandb/proto/v4/wandb_api_pb2.py +37 -0
  44. wandb/proto/v4/wandb_internal_pb2.py +352 -351
  45. wandb/proto/v4/wandb_settings_pb2.py +2 -2
  46. wandb/proto/v4/wandb_sync_pb2.py +10 -6
  47. wandb/proto/v5/wandb_api_pb2.py +38 -0
  48. wandb/proto/v5/wandb_internal_pb2.py +352 -351
  49. wandb/proto/v5/wandb_settings_pb2.py +2 -2
  50. wandb/proto/v5/wandb_sync_pb2.py +10 -6
  51. wandb/proto/v6/wandb_api_pb2.py +48 -0
  52. wandb/proto/v6/wandb_internal_pb2.py +352 -351
  53. wandb/proto/v6/wandb_settings_pb2.py +2 -2
  54. wandb/proto/v6/wandb_sync_pb2.py +10 -6
  55. wandb/proto/wandb_api_pb2.py +18 -0
  56. wandb/proto/wandb_generate_proto.py +1 -0
  57. wandb/sdk/artifacts/_factories.py +7 -2
  58. wandb/sdk/artifacts/_generated/__init__.py +112 -412
  59. wandb/sdk/artifacts/_generated/fragments.py +65 -0
  60. wandb/sdk/artifacts/_generated/operations.py +52 -22
  61. wandb/sdk/artifacts/_generated/run_input_artifacts.py +3 -23
  62. wandb/sdk/artifacts/_generated/run_output_artifacts.py +3 -23
  63. wandb/sdk/artifacts/_generated/type_info.py +19 -0
  64. wandb/sdk/artifacts/_gqlutils.py +47 -0
  65. wandb/sdk/artifacts/_models/__init__.py +4 -0
  66. wandb/sdk/artifacts/_models/base_model.py +20 -0
  67. wandb/sdk/artifacts/_validators.py +40 -12
  68. wandb/sdk/artifacts/artifact.py +99 -118
  69. wandb/sdk/artifacts/artifact_file_cache.py +6 -1
  70. wandb/sdk/artifacts/artifact_manifest_entry.py +67 -14
  71. wandb/sdk/artifacts/storage_handler.py +18 -12
  72. wandb/sdk/artifacts/storage_handlers/azure_handler.py +11 -6
  73. wandb/sdk/artifacts/storage_handlers/gcs_handler.py +9 -6
  74. wandb/sdk/artifacts/storage_handlers/http_handler.py +9 -4
  75. wandb/sdk/artifacts/storage_handlers/local_file_handler.py +10 -6
  76. wandb/sdk/artifacts/storage_handlers/multi_handler.py +5 -4
  77. wandb/sdk/artifacts/storage_handlers/s3_handler.py +10 -8
  78. wandb/sdk/artifacts/storage_handlers/tracking_handler.py +6 -4
  79. wandb/sdk/artifacts/storage_handlers/wb_artifact_handler.py +24 -21
  80. wandb/sdk/artifacts/storage_handlers/wb_local_artifact_handler.py +4 -2
  81. wandb/sdk/artifacts/storage_policies/_multipart.py +187 -0
  82. wandb/sdk/artifacts/storage_policies/wandb_storage_policy.py +71 -242
  83. wandb/sdk/artifacts/storage_policy.py +25 -12
  84. wandb/sdk/data_types/bokeh.py +5 -1
  85. wandb/sdk/data_types/image.py +17 -6
  86. wandb/sdk/data_types/object_3d.py +67 -2
  87. wandb/sdk/interface/interface.py +31 -4
  88. wandb/sdk/interface/interface_queue.py +10 -0
  89. wandb/sdk/interface/interface_shared.py +0 -7
  90. wandb/sdk/interface/interface_sock.py +9 -3
  91. wandb/sdk/internal/_generated/__init__.py +2 -12
  92. wandb/sdk/internal/job_builder.py +27 -10
  93. wandb/sdk/internal/sender.py +5 -2
  94. wandb/sdk/internal/settings_static.py +2 -82
  95. wandb/sdk/launch/create_job.py +2 -1
  96. wandb/sdk/launch/runner/kubernetes_runner.py +25 -20
  97. wandb/sdk/launch/utils.py +82 -1
  98. wandb/sdk/lib/progress.py +8 -74
  99. wandb/sdk/lib/service/service_client.py +5 -9
  100. wandb/sdk/lib/service/service_connection.py +39 -23
  101. wandb/sdk/mailbox/mailbox_handle.py +2 -0
  102. wandb/sdk/projects/_generated/__init__.py +12 -33
  103. wandb/sdk/wandb_init.py +23 -3
  104. wandb/sdk/wandb_login.py +53 -27
  105. wandb/sdk/wandb_run.py +10 -5
  106. wandb/sdk/wandb_settings.py +63 -25
  107. wandb/sync/sync.py +7 -2
  108. wandb/util.py +1 -1
  109. {wandb-0.22.0.dist-info → wandb-0.22.2.dist-info}/METADATA +1 -1
  110. {wandb-0.22.0.dist-info → wandb-0.22.2.dist-info}/RECORD +113 -103
  111. wandb/sdk/artifacts/_graphql_fragments.py +0 -19
  112. {wandb-0.22.0.dist-info → wandb-0.22.2.dist-info}/WHEEL +0 -0
  113. {wandb-0.22.0.dist-info → wandb-0.22.2.dist-info}/entry_points.txt +0 -0
  114. {wandb-0.22.0.dist-info → wandb-0.22.2.dist-info}/licenses/LICENSE +0 -0
@@ -33,6 +33,7 @@ __all__ = [
33
33
  "REGISTRY_VERSIONS_GQL",
34
34
  "RUN_INPUT_ARTIFACTS_GQL",
35
35
  "RUN_OUTPUT_ARTIFACTS_GQL",
36
+ "TYPE_INFO_GQL",
36
37
  "UNLINK_ARTIFACT_GQL",
37
38
  "UPDATE_ARTIFACT_GQL",
38
39
  "UPDATE_ARTIFACT_PORTFOLIO_GQL",
@@ -456,17 +457,7 @@ query RunOutputArtifacts($entity: String!, $project: String!, $runName: String!,
456
457
  project(name: $project, entityName: $entity) {
457
458
  run(name: $runName) {
458
459
  outputArtifacts(after: $cursor, first: $perPage) {
459
- totalCount
460
- edges {
461
- node {
462
- ...ArtifactFragment
463
- }
464
- cursor
465
- }
466
- pageInfo {
467
- endCursor
468
- hasNextPage
469
- }
460
+ ...RunOutputArtifactConnectionFragment
470
461
  }
471
462
  }
472
463
  }
@@ -519,6 +510,20 @@ fragment ArtifactFragmentWithoutAliases on Artifact {
519
510
  createdAt
520
511
  updatedAt
521
512
  }
513
+
514
+ fragment RunOutputArtifactConnectionFragment on ArtifactConnection {
515
+ totalCount
516
+ edges {
517
+ node {
518
+ ...ArtifactFragment
519
+ }
520
+ cursor
521
+ }
522
+ pageInfo {
523
+ endCursor
524
+ hasNextPage
525
+ }
526
+ }
522
527
  """
523
528
 
524
529
  RUN_INPUT_ARTIFACTS_GQL = """
@@ -526,17 +531,7 @@ query RunInputArtifacts($entity: String!, $project: String!, $runName: String!,
526
531
  project(name: $project, entityName: $entity) {
527
532
  run(name: $runName) {
528
533
  inputArtifacts(after: $cursor, first: $perPage) {
529
- totalCount
530
- edges {
531
- node {
532
- ...ArtifactFragment
533
- }
534
- cursor
535
- }
536
- pageInfo {
537
- endCursor
538
- hasNextPage
539
- }
534
+ ...RunInputArtifactConnectionFragment
540
535
  }
541
536
  }
542
537
  }
@@ -589,6 +584,20 @@ fragment ArtifactFragmentWithoutAliases on Artifact {
589
584
  createdAt
590
585
  updatedAt
591
586
  }
587
+
588
+ fragment RunInputArtifactConnectionFragment on InputArtifactConnection {
589
+ totalCount
590
+ edges {
591
+ node {
592
+ ...ArtifactFragment
593
+ }
594
+ cursor
595
+ }
596
+ pageInfo {
597
+ endCursor
598
+ hasNextPage
599
+ }
600
+ }
592
601
  """
593
602
 
594
603
  FETCH_LINKED_ARTIFACTS_GQL = """
@@ -1040,6 +1049,27 @@ mutation UnlinkArtifact($artifactID: ID!, $artifactPortfolioID: ID!) {
1040
1049
  }
1041
1050
  """
1042
1051
 
1052
+ TYPE_INFO_GQL = """
1053
+ query TypeInfo($name: String!) {
1054
+ __type(name: $name) {
1055
+ ...TypeInfoFragment
1056
+ }
1057
+ }
1058
+
1059
+ fragment TypeInfoFragment on __Type {
1060
+ name
1061
+ fields {
1062
+ name
1063
+ args {
1064
+ name
1065
+ }
1066
+ }
1067
+ inputFields {
1068
+ name
1069
+ }
1070
+ }
1071
+ """
1072
+
1043
1073
  REGISTRY_VERSIONS_GQL = """
1044
1074
  query RegistryVersions($organization: String!, $registryFilter: JSONString, $collectionFilter: JSONString, $artifactFilter: JSONString, $cursor: String, $perPage: Int) {
1045
1075
  organization(name: $organization) {
@@ -3,13 +3,13 @@
3
3
 
4
4
  from __future__ import annotations
5
5
 
6
- from typing import List, Optional
6
+ from typing import Optional
7
7
 
8
8
  from pydantic import Field
9
9
 
10
10
  from wandb._pydantic import GQLBase
11
11
 
12
- from .fragments import ArtifactFragment
12
+ from .fragments import RunInputArtifactConnectionFragment
13
13
 
14
14
 
15
15
  class RunInputArtifacts(GQLBase):
@@ -21,31 +21,11 @@ class RunInputArtifactsProject(GQLBase):
21
21
 
22
22
 
23
23
  class RunInputArtifactsProjectRun(GQLBase):
24
- input_artifacts: Optional[RunInputArtifactsProjectRunInputArtifacts] = Field(
24
+ input_artifacts: Optional[RunInputArtifactConnectionFragment] = Field(
25
25
  alias="inputArtifacts"
26
26
  )
27
27
 
28
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
29
  RunInputArtifacts.model_rebuild()
48
30
  RunInputArtifactsProject.model_rebuild()
49
31
  RunInputArtifactsProjectRun.model_rebuild()
50
- RunInputArtifactsProjectRunInputArtifacts.model_rebuild()
51
- RunInputArtifactsProjectRunInputArtifactsEdges.model_rebuild()
@@ -3,13 +3,13 @@
3
3
 
4
4
  from __future__ import annotations
5
5
 
6
- from typing import List, Optional
6
+ from typing import Optional
7
7
 
8
8
  from pydantic import Field
9
9
 
10
10
  from wandb._pydantic import GQLBase
11
11
 
12
- from .fragments import ArtifactFragment
12
+ from .fragments import RunOutputArtifactConnectionFragment
13
13
 
14
14
 
15
15
  class RunOutputArtifacts(GQLBase):
@@ -21,31 +21,11 @@ class RunOutputArtifactsProject(GQLBase):
21
21
 
22
22
 
23
23
  class RunOutputArtifactsProjectRun(GQLBase):
24
- output_artifacts: Optional[RunOutputArtifactsProjectRunOutputArtifacts] = Field(
24
+ output_artifacts: Optional[RunOutputArtifactConnectionFragment] = Field(
25
25
  alias="outputArtifacts"
26
26
  )
27
27
 
28
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
29
  RunOutputArtifacts.model_rebuild()
48
30
  RunOutputArtifactsProject.model_rebuild()
49
31
  RunOutputArtifactsProjectRun.model_rebuild()
50
- RunOutputArtifactsProjectRunOutputArtifacts.model_rebuild()
51
- RunOutputArtifactsProjectRunOutputArtifactsEdges.model_rebuild()
@@ -0,0 +1,19 @@
1
+ # Generated by ariadne-codegen
2
+ # Source: tools/graphql_codegen/artifacts/
3
+
4
+ from __future__ import annotations
5
+
6
+ from typing import Optional
7
+
8
+ from pydantic import Field
9
+
10
+ from wandb._pydantic import GQLBase
11
+
12
+ from .fragments import TypeInfoFragment
13
+
14
+
15
+ class TypeInfo(GQLBase):
16
+ type: Optional[TypeInfoFragment] = Field(alias="__type")
17
+
18
+
19
+ TypeInfo.model_rebuild()
@@ -0,0 +1,47 @@
1
+ from __future__ import annotations
2
+
3
+ from functools import lru_cache
4
+
5
+ from wandb_gql import Client, gql
6
+
7
+ from ._generated import TYPE_INFO_GQL, TypeInfo, TypeInfoFragment
8
+
9
+ OMITTABLE_ARTIFACT_FIELDS = frozenset(
10
+ {
11
+ "ttlDurationSeconds",
12
+ "ttlIsInherited",
13
+ "aliases",
14
+ "tags",
15
+ "historyStep",
16
+ }
17
+ )
18
+
19
+
20
+ @lru_cache(maxsize=16)
21
+ def type_info(client: Client, typename: str) -> TypeInfoFragment | None:
22
+ """Returns the type info for a given GraphQL type."""
23
+ data = client.execute(gql(TYPE_INFO_GQL), variable_values={"name": typename})
24
+ return TypeInfo.model_validate(data).type
25
+
26
+
27
+ def supports_enable_tracking_var(client: Client) -> bool:
28
+ """Returns True if the server supports the `enableTracking` variable for the `Project.artifact(...)` field."""
29
+ typ = type_info(client, "Project")
30
+ if (
31
+ typ
32
+ and typ.fields
33
+ and (art_field := next((f for f in typ.fields if f.name == "artifact"), None))
34
+ ):
35
+ return any("enableTracking" == arg.name for arg in art_field.args)
36
+ return False
37
+
38
+
39
+ def allowed_fields(client: Client, typename: str) -> set[str]:
40
+ """Returns the allowed field names for a given GraphQL type."""
41
+ typ = type_info(client, typename)
42
+ return {f.name for f in typ.fields} if (typ and typ.fields) else set()
43
+
44
+
45
+ def omit_artifact_fields(client: Client) -> set[str]:
46
+ """Return names of Artifact fields to remove from GraphQL requests (for server compatibility)."""
47
+ return set(OMITTABLE_ARTIFACT_FIELDS) - allowed_fields(client, "Artifact")
@@ -0,0 +1,4 @@
1
+ """Pydantic model classes and related helpers for artifacts code.
2
+
3
+ Excludes GraphQL-generated classes.
4
+ """
@@ -0,0 +1,20 @@
1
+ from __future__ import annotations
2
+
3
+ from abc import ABC
4
+
5
+ from pydantic import ConfigDict
6
+
7
+ from wandb._pydantic import JsonableModel
8
+
9
+
10
+ # Abstract base class with a common default configuration that's shared by all
11
+ # pydantic classes in artifacts code (excluding GraphQL-generated types).
12
+ class ArtifactsBase(JsonableModel, ABC):
13
+ # See: https://docs.pydantic.dev/latest/api/config/#pydantic.config.ConfigDict
14
+ model_config = ConfigDict(
15
+ # Most likely, some fields won't be pydantic types
16
+ arbitrary_types_allowed=True,
17
+ # Assume instances of the same class have already been validated to save time,
18
+ # but validate subclasses in case they override the default behavior.
19
+ revalidate_instances="subclass-instances",
20
+ )
@@ -4,7 +4,7 @@ from __future__ import annotations
4
4
 
5
5
  import json
6
6
  import re
7
- from dataclasses import astuple, dataclass, field, replace
7
+ from dataclasses import dataclass, field, replace
8
8
  from functools import wraps
9
9
  from typing import TYPE_CHECKING, Any, Callable, Dict, Literal, Optional, TypeVar, cast
10
10
 
@@ -277,34 +277,62 @@ def remove_registry_prefix(project: str) -> str:
277
277
 
278
278
  @pydantic_dataclass
279
279
  class ArtifactPath:
280
- #: The collection name.
281
280
  name: str
282
- #: The project name, which can also be a registry name.
281
+ """The collection or artifact version name."""
283
282
  project: Optional[str] = None # noqa: UP045
284
- #: Prefix is often an org or entity name.
283
+ """The project name."""
285
284
  prefix: Optional[str] = None # noqa: UP045
285
+ """Typically the entity or org name."""
286
286
 
287
287
  @classmethod
288
288
  def from_str(cls, path: str) -> Self:
289
- """Instantiate by parsing an artifact path."""
290
- if len(parts := path.split("/")) <= 3:
291
- return cls(*reversed(parts))
292
- raise ValueError(
293
- f"Expected a valid path like `name`, `project/name`, or `prefix/project/name`. Got: {path!r}"
294
- )
289
+ """Instantiate by parsing a string artifact path.
290
+
291
+ Raises:
292
+ ValueError: If the string is not a valid artifact path.
293
+ """
294
+ # Separate the alias first, which may itself contain slashes.
295
+ # If there's no alias, note that both sep and alias will be empty.
296
+ collection_path, sep, alias = path.partition(":")
297
+
298
+ prefix, project = None, None # defaults, if missing
299
+ if len(parts := collection_path.split("/")) == 1:
300
+ name = parts[0]
301
+ elif len(parts) == 2:
302
+ project, name = parts
303
+ elif len(parts) == 3:
304
+ prefix, project, name = parts
305
+ else:
306
+ raise ValueError(f"Invalid artifact path: {path!r}")
307
+ return cls(prefix=prefix, project=project, name=f"{name}{sep}{alias}")
295
308
 
296
309
  def to_str(self) -> str:
297
310
  """Returns the slash-separated string representation of the path."""
298
- return "/".join(filter(bool, reversed(astuple(self))))
311
+ ordered_parts = (self.prefix, self.project, self.name)
312
+ return "/".join(part for part in ordered_parts if part)
299
313
 
300
314
  def with_defaults(
301
315
  self,
316
+ *,
302
317
  prefix: str | None = None,
303
318
  project: str | None = None,
304
319
  ) -> Self:
305
- """Returns this path with missing values set to the given defaults."""
320
+ """Returns a copy of this path with missing values set to the given defaults."""
306
321
  return replace(
307
322
  self,
308
323
  prefix=self.prefix or prefix,
309
324
  project=self.project or project,
310
325
  )
326
+
327
+ def is_registry_path(self) -> bool:
328
+ """Returns True if this path appears to be a registry path."""
329
+ return bool((p := self.project) and is_artifact_registry_project(p))
330
+
331
+
332
+ @pydantic_dataclass
333
+ class FullArtifactPath(ArtifactPath):
334
+ """Same as ArtifactPath, but with all parts required."""
335
+
336
+ name: str
337
+ project: str
338
+ prefix: str