wandb 0.22.1__py3-none-musllinux_1_2_aarch64.whl → 0.22.3__py3-none-musllinux_1_2_aarch64.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 (166) hide show
  1. wandb/__init__.py +1 -1
  2. wandb/__init__.pyi +7 -4
  3. wandb/_pydantic/__init__.py +8 -1
  4. wandb/_pydantic/base.py +54 -18
  5. wandb/_pydantic/field_types.py +8 -3
  6. wandb/_pydantic/pagination.py +46 -0
  7. wandb/_pydantic/utils.py +2 -2
  8. wandb/apis/public/api.py +24 -19
  9. wandb/apis/public/artifacts.py +259 -270
  10. wandb/apis/public/registries/_utils.py +40 -54
  11. wandb/apis/public/registries/registries_search.py +70 -85
  12. wandb/apis/public/registries/registry.py +173 -156
  13. wandb/apis/public/runs.py +27 -6
  14. wandb/apis/public/utils.py +43 -20
  15. wandb/automations/_generated/create_automation.py +2 -2
  16. wandb/automations/_generated/create_generic_webhook_integration.py +4 -4
  17. wandb/automations/_generated/delete_automation.py +2 -2
  18. wandb/automations/_generated/fragments.py +31 -52
  19. wandb/automations/_generated/generic_webhook_integrations_by_entity.py +3 -3
  20. wandb/automations/_generated/get_automations.py +3 -3
  21. wandb/automations/_generated/get_automations_by_entity.py +3 -3
  22. wandb/automations/_generated/input_types.py +9 -9
  23. wandb/automations/_generated/integrations_by_entity.py +3 -3
  24. wandb/automations/_generated/operations.py +6 -6
  25. wandb/automations/_generated/slack_integrations_by_entity.py +3 -3
  26. wandb/automations/_generated/update_automation.py +2 -2
  27. wandb/automations/_utils.py +3 -3
  28. wandb/automations/actions.py +3 -3
  29. wandb/automations/automations.py +6 -5
  30. wandb/bin/gpu_stats +0 -0
  31. wandb/bin/wandb-core +0 -0
  32. wandb/cli/beta.py +23 -3
  33. wandb/cli/beta_leet.py +75 -0
  34. wandb/cli/beta_sync.py +1 -1
  35. wandb/cli/cli.py +34 -7
  36. wandb/errors/term.py +8 -8
  37. wandb/jupyter.py +0 -51
  38. wandb/old/settings.py +6 -6
  39. wandb/proto/v3/wandb_api_pb2.py +86 -0
  40. wandb/proto/v3/wandb_server_pb2.py +38 -37
  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_server_pb2.py +38 -37
  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_server_pb2.py +38 -37
  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_server_pb2.py +38 -37
  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/_generated/__init__.py +96 -40
  58. wandb/sdk/artifacts/_generated/add_aliases.py +3 -3
  59. wandb/sdk/artifacts/_generated/add_artifact_collection_tags.py +26 -0
  60. wandb/sdk/artifacts/_generated/artifact_by_id.py +2 -2
  61. wandb/sdk/artifacts/_generated/artifact_by_name.py +3 -3
  62. wandb/sdk/artifacts/_generated/artifact_collection_membership_file_urls.py +27 -8
  63. wandb/sdk/artifacts/_generated/artifact_collection_membership_files.py +27 -8
  64. wandb/sdk/artifacts/_generated/artifact_created_by.py +7 -20
  65. wandb/sdk/artifacts/_generated/artifact_file_urls.py +19 -6
  66. wandb/sdk/artifacts/_generated/artifact_membership_by_name.py +26 -0
  67. wandb/sdk/artifacts/_generated/artifact_type.py +5 -5
  68. wandb/sdk/artifacts/_generated/artifact_used_by.py +8 -17
  69. wandb/sdk/artifacts/_generated/artifact_version_files.py +19 -8
  70. wandb/sdk/artifacts/_generated/delete_aliases.py +3 -3
  71. wandb/sdk/artifacts/_generated/delete_artifact.py +4 -4
  72. wandb/sdk/artifacts/_generated/delete_artifact_collection_tags.py +23 -0
  73. wandb/sdk/artifacts/_generated/delete_artifact_portfolio.py +4 -4
  74. wandb/sdk/artifacts/_generated/delete_artifact_sequence.py +4 -4
  75. wandb/sdk/artifacts/_generated/delete_registry.py +21 -0
  76. wandb/sdk/artifacts/_generated/fetch_artifact_manifest.py +8 -20
  77. wandb/sdk/artifacts/_generated/fetch_linked_artifacts.py +13 -35
  78. wandb/sdk/artifacts/_generated/fetch_org_info_from_entity.py +28 -0
  79. wandb/sdk/artifacts/_generated/fetch_registries.py +18 -8
  80. wandb/sdk/{projects → artifacts}/_generated/fetch_registry.py +4 -4
  81. wandb/sdk/artifacts/_generated/fragments.py +183 -333
  82. wandb/sdk/artifacts/_generated/input_types.py +133 -7
  83. wandb/sdk/artifacts/_generated/link_artifact.py +5 -5
  84. wandb/sdk/artifacts/_generated/operations.py +1053 -548
  85. wandb/sdk/artifacts/_generated/project_artifact_collection.py +9 -77
  86. wandb/sdk/artifacts/_generated/project_artifact_collections.py +21 -9
  87. wandb/sdk/artifacts/_generated/project_artifact_type.py +3 -3
  88. wandb/sdk/artifacts/_generated/project_artifact_types.py +19 -6
  89. wandb/sdk/artifacts/_generated/project_artifacts.py +7 -8
  90. wandb/sdk/artifacts/_generated/registry_collections.py +21 -9
  91. wandb/sdk/artifacts/_generated/registry_versions.py +20 -9
  92. wandb/sdk/artifacts/_generated/rename_registry.py +25 -0
  93. wandb/sdk/artifacts/_generated/run_input_artifacts.py +5 -9
  94. wandb/sdk/artifacts/_generated/run_output_artifacts.py +5 -9
  95. wandb/sdk/artifacts/_generated/type_info.py +2 -2
  96. wandb/sdk/artifacts/_generated/unlink_artifact.py +3 -5
  97. wandb/sdk/artifacts/_generated/update_artifact.py +3 -3
  98. wandb/sdk/artifacts/_generated/update_artifact_collection_type.py +28 -0
  99. wandb/sdk/artifacts/_generated/update_artifact_portfolio.py +7 -16
  100. wandb/sdk/artifacts/_generated/update_artifact_sequence.py +7 -16
  101. wandb/sdk/artifacts/_generated/upsert_registry.py +25 -0
  102. wandb/sdk/artifacts/_gqlutils.py +170 -6
  103. wandb/sdk/artifacts/_models/__init__.py +9 -0
  104. wandb/sdk/artifacts/_models/artifact_collection.py +109 -0
  105. wandb/sdk/artifacts/_models/manifest.py +26 -0
  106. wandb/sdk/artifacts/_models/pagination.py +26 -0
  107. wandb/sdk/artifacts/_models/registry.py +100 -0
  108. wandb/sdk/artifacts/_validators.py +45 -27
  109. wandb/sdk/artifacts/artifact.py +249 -244
  110. wandb/sdk/artifacts/artifact_file_cache.py +1 -1
  111. wandb/sdk/artifacts/artifact_manifest.py +37 -32
  112. wandb/sdk/artifacts/artifact_manifest_entry.py +82 -133
  113. wandb/sdk/artifacts/artifact_manifests/artifact_manifest_v1.py +43 -61
  114. wandb/sdk/artifacts/storage_handler.py +18 -12
  115. wandb/sdk/artifacts/storage_handlers/azure_handler.py +11 -6
  116. wandb/sdk/artifacts/storage_handlers/gcs_handler.py +17 -12
  117. wandb/sdk/artifacts/storage_handlers/http_handler.py +9 -4
  118. wandb/sdk/artifacts/storage_handlers/local_file_handler.py +10 -6
  119. wandb/sdk/artifacts/storage_handlers/multi_handler.py +5 -4
  120. wandb/sdk/artifacts/storage_handlers/s3_handler.py +10 -8
  121. wandb/sdk/artifacts/storage_handlers/tracking_handler.py +6 -4
  122. wandb/sdk/artifacts/storage_handlers/wb_artifact_handler.py +24 -21
  123. wandb/sdk/artifacts/storage_handlers/wb_local_artifact_handler.py +4 -2
  124. wandb/sdk/artifacts/storage_policies/_multipart.py +187 -0
  125. wandb/sdk/artifacts/storage_policies/wandb_storage_policy.py +61 -242
  126. wandb/sdk/artifacts/storage_policy.py +25 -12
  127. wandb/sdk/data_types/image.py +2 -2
  128. wandb/sdk/data_types/object_3d.py +67 -2
  129. wandb/sdk/interface/interface.py +72 -64
  130. wandb/sdk/interface/interface_queue.py +27 -18
  131. wandb/sdk/interface/interface_shared.py +61 -23
  132. wandb/sdk/interface/interface_sock.py +9 -5
  133. wandb/sdk/internal/_generated/server_features_query.py +4 -4
  134. wandb/sdk/internal/job_builder.py +27 -10
  135. wandb/sdk/internal/sender.py +4 -1
  136. wandb/sdk/launch/create_job.py +2 -1
  137. wandb/sdk/launch/inputs/schema.py +13 -10
  138. wandb/sdk/lib/apikey.py +8 -12
  139. wandb/sdk/lib/asyncio_compat.py +1 -1
  140. wandb/sdk/lib/asyncio_manager.py +5 -5
  141. wandb/sdk/lib/console_capture.py +38 -30
  142. wandb/sdk/lib/progress.py +151 -125
  143. wandb/sdk/lib/retry.py +3 -2
  144. wandb/sdk/lib/service/service_connection.py +2 -2
  145. wandb/sdk/lib/wb_logging.py +2 -1
  146. wandb/sdk/mailbox/mailbox.py +1 -1
  147. wandb/sdk/wandb_init.py +11 -14
  148. wandb/sdk/wandb_run.py +14 -48
  149. wandb/sdk/wandb_settings.py +114 -30
  150. {wandb-0.22.1.dist-info → wandb-0.22.3.dist-info}/METADATA +2 -1
  151. {wandb-0.22.1.dist-info → wandb-0.22.3.dist-info}/RECORD +154 -146
  152. wandb/sdk/artifacts/_generated/artifact_via_membership_by_name.py +0 -26
  153. wandb/sdk/artifacts/_generated/create_artifact_collection_tag_assignments.py +0 -36
  154. wandb/sdk/artifacts/_generated/delete_artifact_collection_tag_assignments.py +0 -25
  155. wandb/sdk/artifacts/_generated/move_artifact_collection.py +0 -35
  156. wandb/sdk/projects/_generated/__init__.py +0 -26
  157. wandb/sdk/projects/_generated/delete_project.py +0 -22
  158. wandb/sdk/projects/_generated/enums.py +0 -4
  159. wandb/sdk/projects/_generated/fragments.py +0 -41
  160. wandb/sdk/projects/_generated/input_types.py +0 -13
  161. wandb/sdk/projects/_generated/operations.py +0 -88
  162. wandb/sdk/projects/_generated/rename_project.py +0 -27
  163. wandb/sdk/projects/_generated/upsert_registry_project.py +0 -27
  164. {wandb-0.22.1.dist-info → wandb-0.22.3.dist-info}/WHEEL +0 -0
  165. {wandb-0.22.1.dist-info → wandb-0.22.3.dist-info}/entry_points.txt +0 -0
  166. {wandb-0.22.1.dist-info → wandb-0.22.3.dist-info}/licenses/LICENSE +0 -0
wandb/__init__.py CHANGED
@@ -10,7 +10,7 @@ For reference documentation, see https://docs.wandb.com/ref/python.
10
10
  """
11
11
  from __future__ import annotations
12
12
 
13
- __version__ = "0.22.1"
13
+ __version__ = "0.22.3"
14
14
 
15
15
 
16
16
  from wandb.errors import Error
wandb/__init__.pyi CHANGED
@@ -107,7 +107,7 @@ if TYPE_CHECKING:
107
107
  import wandb
108
108
  from wandb.plot import CustomChart
109
109
 
110
- __version__: str = "0.22.1"
110
+ __version__: str = "0.22.3"
111
111
 
112
112
  run: Run | None
113
113
  config: wandb_config.Config
@@ -580,7 +580,7 @@ def log(
580
580
  run.log({"accuracy": 0.8}, step=current_step)
581
581
  current_step += 1
582
582
  run.log({"train-loss": 0.4}, step=current_step)
583
- run.log({"accuracy": 0.9}, step=current_step)
583
+ run.log({"accuracy": 0.9}, step=current_step, commit=True)
584
584
  ```
585
585
 
586
586
  Args:
@@ -754,6 +754,9 @@ def save(
754
754
  When given an absolute path or glob and no `base_path`, one
755
755
  directory level is preserved as in the example above.
756
756
 
757
+ Files are automatically deduplicated: calling `save()` multiple times
758
+ on the same file without modifications will not re-upload it.
759
+
757
760
  Args:
758
761
  glob_str: A relative or absolute path or Unix glob.
759
762
  base_path: A path to use to infer a directory structure; see examples.
@@ -778,10 +781,10 @@ def save(
778
781
  run.save("these/are/myfiles/*", base_path="these")
779
782
  # => Saves files in an "are/myfiles/" folder in the run.
780
783
 
781
- run.save("/User/username/Documents/run123/*.txt")
784
+ run.save("/Users/username/Documents/run123/*.txt")
782
785
  # => Saves files in a "run123/" folder in the run. See note below.
783
786
 
784
- run.save("/User/username/Documents/run123/*.txt", base_path="/User")
787
+ run.save("/Users/username/Documents/run123/*.txt", base_path="/Users")
785
788
  # => Saves files in a "username/Documents/run123/" folder in the run.
786
789
 
787
790
  run.save("files/*/saveme.txt")
@@ -5,6 +5,12 @@ __all__ = [
5
5
  "CompatBaseModel",
6
6
  "JsonableModel",
7
7
  "GQLBase",
8
+ "GQLInput",
9
+ "GQLResult",
10
+ "Connection",
11
+ "ConnectionWithTotal",
12
+ "Edge",
13
+ "PageInfo",
8
14
  "Typename",
9
15
  "GQLId",
10
16
  "AliasChoices",
@@ -18,8 +24,9 @@ __all__ = [
18
24
  "gql_typename",
19
25
  ]
20
26
 
21
- from .base import CompatBaseModel, GQLBase, JsonableModel
27
+ from .base import CompatBaseModel, GQLBase, GQLInput, GQLResult, JsonableModel
22
28
  from .field_types import GQLId, Typename
29
+ from .pagination import Connection, ConnectionWithTotal, Edge, PageInfo
23
30
  from .utils import IS_PYDANTIC_V2, from_json, gql_typename, pydantic_isinstance, to_json
24
31
  from .v1_compat import (
25
32
  AliasChoices,
wandb/_pydantic/base.py CHANGED
@@ -1,29 +1,37 @@
1
1
  """Base classes and other customizations for generated pydantic types."""
2
2
 
3
+ # Older-style type annotations required for Pydantic v1 / python 3.8 compatibility.
4
+ # ruff: noqa: UP006
5
+
3
6
  from __future__ import annotations
4
7
 
5
8
  from abc import ABC
6
- from typing import TYPE_CHECKING, Any, Callable, ClassVar, Literal
9
+ from typing import TYPE_CHECKING, Any, Callable, ClassVar, Dict, Literal, overload
7
10
 
8
11
  from pydantic import BaseModel, ConfigDict
9
12
  from typing_extensions import TypedDict, Unpack, override
10
13
 
11
- from .v1_compat import PydanticCompatMixin
14
+ from .v1_compat import PydanticCompatMixin, to_camel
12
15
 
13
16
  if TYPE_CHECKING:
14
17
  from pydantic.main import IncEx
15
18
 
16
19
 
17
20
  class ModelDumpKwargs(TypedDict, total=False):
18
- """Shared keyword arguments for `BaseModel.model_{dump,dump_json}`."""
21
+ """Shared keyword arguments for `BaseModel.model_{dump,dump_json}`.
22
+
23
+ Newer pydantic versions may accept more arguments than are listed here.
24
+ Last updated for pydantic v2.12.0.
25
+ """
19
26
 
20
27
  include: IncEx | None
21
28
  exclude: IncEx | None
22
- context: dict[str, Any] | None
29
+ context: Any | None
23
30
  by_alias: bool | None
24
31
  exclude_unset: bool
25
32
  exclude_defaults: bool
26
33
  exclude_none: bool
34
+ exclude_computed_fields: bool
27
35
  round_trip: bool
28
36
  warnings: bool | Literal["none", "warn", "error"]
29
37
  fallback: Callable[[Any], Any] | None
@@ -76,33 +84,61 @@ class JsonableModel(CompatBaseModel, ABC):
76
84
  # Custom defaults keyword args for `JsonableModel.model_{dump,dump_json}`:
77
85
  # - by_alias: Convert keys to JSON-ready names and objects to JSON-ready dicts.
78
86
  # - round_trip: Ensure round-trippable result
79
- __DUMP_DEFAULTS: ClassVar[ModelDumpKwargs] = dict(by_alias=True, round_trip=True)
87
+ __DUMP_DEFAULTS: ClassVar[Dict[str, Any]] = dict(by_alias=True, round_trip=True)
80
88
 
81
- @override
89
+ @overload # Actual signature
82
90
  def model_dump(
83
- self,
84
- *,
85
- mode: Literal["json", "python"] | str = "json", # NOTE: changed default
86
- **kwargs: Unpack[ModelDumpKwargs],
87
- ) -> dict[str, Any]:
91
+ self, *, mode: str, **kwargs: Unpack[ModelDumpKwargs]
92
+ ) -> dict[str, Any]: ...
93
+ @overload # In case pydantic adds more kwargs in future releases
94
+ def model_dump(self, **kwargs: Any) -> dict[str, Any]: ...
95
+
96
+ @override
97
+ def model_dump(self, *, mode: str = "json", **kwargs: Any) -> dict[str, Any]:
88
98
  kwargs = {**self.__DUMP_DEFAULTS, **kwargs} # allows overrides, if needed
89
99
  return super().model_dump(mode=mode, **kwargs)
90
100
 
91
- @override
101
+ @overload # Actual signature
92
102
  def model_dump_json(
93
- self,
94
- *,
95
- indent: int | None = None,
96
- **kwargs: Unpack[ModelDumpKwargs],
97
- ) -> str:
103
+ self, *, indent: int | None, **kwargs: Unpack[ModelDumpKwargs]
104
+ ) -> str: ...
105
+ @overload # In case pydantic adds more kwargs in future releases
106
+ def model_dump_json(self, **kwargs: Any) -> str: ...
107
+
108
+ @override
109
+ def model_dump_json(self, *, indent: int | None = None, **kwargs: Any) -> str:
98
110
  kwargs = {**self.__DUMP_DEFAULTS, **kwargs} # allows overrides, if needed
99
111
  return super().model_dump_json(indent=indent, **kwargs)
100
112
 
101
113
 
102
- # Base class for all GraphQL-generated types.
114
+ # Base class for all GraphQL-derived types.
103
115
  class GQLBase(JsonableModel, ABC):
104
116
  model_config = ConfigDict(
105
117
  validate_default=True,
106
118
  revalidate_instances="always",
107
119
  protected_namespaces=(), # Some GraphQL fields may begin with "model_"
108
120
  )
121
+
122
+
123
+ # Base class for GraphQL result types, i.e. parsed GraphQL response data.
124
+ class GQLResult(GQLBase, ABC):
125
+ model_config = ConfigDict(
126
+ alias_generator=to_camel, # Assume JSON names are camelCase, by default
127
+ frozen=True, # Keep the actual response data immutable
128
+ )
129
+
130
+
131
+ # Base class for GraphQL input types, i.e. prepared GraphQL variables or input objects for queries and mutations.
132
+ class GQLInput(GQLBase, ABC):
133
+ # For GraphQL input types, exclude null input values when preparing the JSON-able request data.
134
+ __DUMP_DEFAULTS: ClassVar[Dict[str, Any]] = dict(exclude_none=True)
135
+
136
+ @override
137
+ def model_dump(self, *, mode: str = "json", **kwargs: Any) -> dict[str, Any]:
138
+ kwargs = {**self.__DUMP_DEFAULTS, **kwargs}
139
+ return super().model_dump(mode=mode, **kwargs)
140
+
141
+ @override
142
+ def model_dump_json(self, *, indent: int | None = None, **kwargs: Any) -> str:
143
+ kwargs = {**self.__DUMP_DEFAULTS, **kwargs}
144
+ return super().model_dump_json(indent=indent, **kwargs)
@@ -11,13 +11,18 @@ from .utils import IS_PYDANTIC_V2
11
11
 
12
12
  T = TypeVar("T")
13
13
 
14
+ # HACK: Pydantic no longer seems to like it when you define a type alias
15
+ # at the module level with `Annotated[...]`.
16
+ # The commented TypeAliases are a hack to unblock CI for now.
14
17
 
15
- #: GraphQL `__typename` fields
16
- Typename = Annotated[T, Field(repr=False, frozen=True, alias="__typename")]
18
+ # Typename = Annotated[T, Field(repr=False, frozen=True, alias="__typename")]
19
+ Typename = Annotated[T, Field(alias="__typename")]
20
+ """Annotates GraphQL `__typename` fields."""
17
21
 
18
22
 
19
23
  if IS_PYDANTIC_V2 or TYPE_CHECKING:
20
- GQLId = Annotated[StrictStr, Field(repr=False, frozen=True)]
24
+ # GQLId = Annotated[StrictStr, Field(repr=False, frozen=True)]
25
+ GQLId = StrictStr
21
26
 
22
27
  else:
23
28
  # FIXME: Find a way to fix this for pydantic v1, which doesn't like when
@@ -0,0 +1,46 @@
1
+ """Definitions and utilities for client-side handling of "relay-style" GraphQL types for pagination.
2
+
3
+ For formal specs and definitions, see: https://relay.dev/graphql/connections.htm
4
+ """
5
+
6
+ from typing import Generic, Iterator, List, Literal, Optional, TypeVar
7
+
8
+ from pydantic import NonNegativeInt
9
+
10
+ from .base import GQLResult
11
+
12
+ NodeT = TypeVar("NodeT", bound=GQLResult)
13
+ """A generic type variable for a GraphQL relay node."""
14
+
15
+
16
+ class PageInfo(GQLResult):
17
+ typename__: Literal["PageInfo"] = "PageInfo"
18
+ end_cursor: Optional[str]
19
+ has_next_page: bool
20
+
21
+
22
+ class Edge(GQLResult, Generic[NodeT]):
23
+ node: NodeT
24
+
25
+
26
+ class Connection(GQLResult, Generic[NodeT]):
27
+ edges: List[Edge[NodeT]]
28
+ page_info: PageInfo
29
+
30
+ def nodes(self) -> Iterator[NodeT]:
31
+ """Returns an iterator over the nodes in the connection."""
32
+ return (node for edge in self.edges if (node := edge.node))
33
+
34
+ @property
35
+ def has_next(self) -> bool:
36
+ """Returns True if there are more pages to fetch."""
37
+ return self.page_info.has_next_page
38
+
39
+ @property
40
+ def next_cursor(self) -> Optional[str]:
41
+ """Returns the start cursor for the next page to fetch."""
42
+ return self.page_info.end_cursor
43
+
44
+
45
+ class ConnectionWithTotal(Connection[NodeT], Generic[NodeT]):
46
+ total_count: NonNegativeInt
wandb/_pydantic/utils.py CHANGED
@@ -30,7 +30,7 @@ def gql_typename(cls: type[BaseModel]) -> str:
30
30
  if IS_PYDANTIC_V2:
31
31
  import pydantic_core # pydantic_core is only installed by pydantic v2
32
32
 
33
- def from_json(s: str) -> Any:
33
+ def from_json(s: str | bytes) -> Any:
34
34
  """Quickly deserialize a JSON string to a Python object."""
35
35
  return pydantic_core.from_json(s)
36
36
 
@@ -63,7 +63,7 @@ else:
63
63
 
64
64
  from pydantic.json import pydantic_encoder # Only valid in pydantic v1
65
65
 
66
- def from_json(s: str) -> Any:
66
+ def from_json(s: str | bytes) -> Any:
67
67
  return json.loads(s)
68
68
 
69
69
  def to_json(v: Any) -> str:
wandb/apis/public/api.py CHANGED
@@ -313,7 +313,9 @@ class Api:
313
313
  )
314
314
  self.settings["entity"] = _overrides["username"]
315
315
 
316
- if _thread_local_api_settings.cookies is None:
316
+ use_api_key = api_key is not None or _thread_local_api_settings.cookies is None
317
+
318
+ if use_api_key:
317
319
  self.api_key = self._load_api_key(
318
320
  base_url=self.settings["base_url"],
319
321
  init_api_key=api_key,
@@ -331,7 +333,7 @@ class Api:
331
333
  self._default_entity = None
332
334
  self._timeout = timeout if timeout is not None else self._HTTP_TIMEOUT
333
335
  auth = None
334
- if not _thread_local_api_settings.cookies:
336
+ if use_api_key:
335
337
  auth = ("api", self.api_key)
336
338
  proxies = self.settings.get("_proxies") or json.loads(
337
339
  os.environ.get("WANDB__PROXIES", "{}")
@@ -365,17 +367,18 @@ class Api:
365
367
  """Attempts to load a configured API key or prompt if one is not found.
366
368
 
367
369
  The API key is loaded in the following order:
368
- 1. Thread local api key
369
- 2. User explicitly provided api key
370
+ 1. User explicitly provided api key
371
+ 2. Thread local api key
370
372
  3. Environment variable
371
373
  4. Netrc file
372
374
  5. Prompt for api key using wandb.login
373
375
  """
374
- # just use thread local api key if it's set
375
- if _thread_local_api_settings.api_key:
376
- return _thread_local_api_settings.api_key
376
+ # Use explicit key before thread local.
377
+ # This allow user switching keys without picking up the wrong key from thread local.
377
378
  if init_api_key is not None:
378
379
  return init_api_key
380
+ if _thread_local_api_settings.api_key:
381
+ return _thread_local_api_settings.api_key
379
382
  if os.getenv("WANDB_API_KEY"):
380
383
  return os.environ["WANDB_API_KEY"]
381
384
 
@@ -958,8 +961,8 @@ class Api:
958
961
  entity: Name of the entity requested. If None, will fall back to
959
962
  the default entity passed to `Api`. If no default entity,
960
963
  will raise a `ValueError`.
961
- per_page: Sets the page size for query pagination. If set to `None`,
962
- use the default size. Usually there is no reason to change this.
964
+ per_page: Sets the page size for query pagination.
965
+ Usually there is no reason to change this.
963
966
 
964
967
  Returns:
965
968
  A `Projects` object which is an iterable collection of `Project`objects.
@@ -1015,9 +1018,8 @@ class Api:
1015
1018
  entity that created the project as a prefix followed by a
1016
1019
  forward slash.
1017
1020
  name: Name of the report requested.
1018
- per_page: Sets the page size for query pagination. If set to
1019
- `None`, use the default size. Usually there is no reason to
1020
- change this.
1021
+ per_page: Sets the page size for query pagination.
1022
+ Usually there is no reason to change this.
1021
1023
 
1022
1024
  Returns:
1023
1025
  A `Reports` object which is an iterable collection of
@@ -1380,7 +1382,7 @@ class Api:
1380
1382
  Args:
1381
1383
  project_name: The name of the project to filter on.
1382
1384
  type_name: The name of the artifact type to filter on.
1383
- per_page: Sets the page size for query pagination. None will use the default size.
1385
+ per_page: Sets the page size for query pagination.
1384
1386
  Usually there is no reason to change this.
1385
1387
 
1386
1388
  Returns:
@@ -1483,9 +1485,8 @@ class Api:
1483
1485
  name: The artifact's collection name. Optionally append the
1484
1486
  entity that logged the artifact as a prefix followed by
1485
1487
  a forward slash.
1486
- per_page: Sets the page size for query pagination. If set to
1487
- `None`, use the default size. Usually there is no reason
1488
- to change this.
1488
+ per_page: Sets the page size for query pagination. Usually
1489
+ there is no reason to change this.
1489
1490
  tags: Only return artifacts with all of these tags.
1490
1491
 
1491
1492
  Returns:
@@ -1788,6 +1789,7 @@ class Api:
1788
1789
  self,
1789
1790
  organization: str | None = None,
1790
1791
  filter: dict[str, Any] | None = None,
1792
+ per_page: int = 100,
1791
1793
  ) -> Registries:
1792
1794
  """Returns a lazy iterator of `Registry` objects.
1793
1795
 
@@ -1804,6 +1806,7 @@ class Api:
1804
1806
  `name`, `tag`, `description`, `created_at`, `updated_at`
1805
1807
  Fields available to filter for versions are
1806
1808
  `tag`, `alias`, `created_at`, `updated_at`, `metadata`
1809
+ per_page: Sets the page size for query pagination.
1807
1810
 
1808
1811
  Returns:
1809
1812
  A lazy iterator of `Registry` objects.
@@ -1849,7 +1852,9 @@ class Api:
1849
1852
  organization = organization or fetch_org_from_settings_or_entity(
1850
1853
  self.settings, self.default_entity
1851
1854
  )
1852
- return Registries(self.client, organization, filter)
1855
+ return Registries(
1856
+ self.client, organization=organization, filter=filter, per_page=per_page
1857
+ )
1853
1858
 
1854
1859
  @tracked
1855
1860
  def registry(self, name: str, organization: str | None = None) -> Registry:
@@ -2325,7 +2330,7 @@ class Api:
2325
2330
  # If needed, rewrite the GraphQL field selection set to omit unsupported fields/fragments/types
2326
2331
  omit_fragments = self._omitted_automation_fragments()
2327
2332
  mutation = gql_compat(CREATE_AUTOMATION_GQL, omit_fragments=omit_fragments)
2328
- variables = {"params": gql_input.model_dump(exclude_none=True)}
2333
+ variables = {"input": gql_input.model_dump()}
2329
2334
 
2330
2335
  name = gql_input.name
2331
2336
  try:
@@ -2445,7 +2450,7 @@ class Api:
2445
2450
  # If needed, rewrite the GraphQL field selection set to omit unsupported fields/fragments/types
2446
2451
  omit_fragments = self._omitted_automation_fragments()
2447
2452
  mutation = gql_compat(UPDATE_AUTOMATION_GQL, omit_fragments=omit_fragments)
2448
- variables = {"params": gql_input.model_dump(exclude_none=True)}
2453
+ variables = {"input": gql_input.model_dump()}
2449
2454
 
2450
2455
  name = gql_input.name
2451
2456
  try: