Skip to content
Merged
Show file tree
Hide file tree
Changes from 96 commits
Commits
Show all changes
97 commits
Select commit Hold shift + click to select a range
0214ef9
agent(pydantic-v2): initialize agent
Mar 24, 2026
806076c
agent(pydantic-v2): add Claude Code permissions settings
Mar 24, 2026
e414067
agent(pydantic-v2): discovery
Mar 24, 2026
10f7cfa
agent(pydantic-v2): migrate v1 API surface across codebase (Extra, er…
Mar 24, 2026
6b1b19f
agent(pydantic-v2): migrate .json() to .model_dump_json() in operator…
Mar 24, 2026
00a20f3
agent(pydantic-v2): migrate validators and inner Config classes in au…
Mar 24, 2026
b24aeea
agent(pydantic-v2): migrate inner Config classes to model_config in j…
Mar 24, 2026
99a2935
agent(pydantic-v2): migrate inner Config classes to model_config in d…
Mar 24, 2026
323d2e2
agent(pydantic-v2): migrate storage Client Config classes and add pyd…
Mar 24, 2026
90899c9
agent(pydantic-v2): migrate ExecutorParameters to pydantic-settings v…
Mar 24, 2026
02b81bc
agent(pydantic-v2): migrate all validators to v2 syntax and add migra…
Mar 24, 2026
6836af5
agent(pydantic-v2): fix field_validator to use info.data instead of v…
Mar 24, 2026
ad59ada
agent(pydantic-v2): fix duplicate @classmethod decorators and use Fie…
Mar 24, 2026
78ecfeb
agent(pydantic-v2): remove migrate_validators.py migration script
Mar 24, 2026
9e0d009
agent(pydantic-v2): migrate model config to ConfigDict in StorageBack…
Mar 24, 2026
c61dd0d
agent(pydantic-v2): bump pydantic to 2.12.5 and add pydantic-settings…
Mar 24, 2026
df793eb
agent(pydantic-v2): migrate .copy() to .model_copy() in service tests
Mar 24, 2026
8cbab45
agent(pydantic-v2): add migrate_fields.py script for Field() extra kw…
Mar 24, 2026
7f74b77
agent(pydantic-v2): migrate StaticConfig to use model_fields, json_sc…
Mar 24, 2026
073276d
agent(pydantic-v2): migrate Field() extra kwargs to json_schema_extra…
Mar 24, 2026
d811910
agent(pydantic-v2): migrate __fields__.keys() to model_fields.keys() …
Mar 24, 2026
e11f4b8
agent(pydantic-v2): migrate .construct() to .model_construct() across…
Mar 24, 2026
f58b2a2
agent(pydantic-v2): migrate .dict() to .model_dump() and fix lint acr…
Mar 24, 2026
228778b
agent(pydantic-v2): migrate FieldValidationInfo to ValidationInfo in …
Mar 24, 2026
03a9305
agent(pydantic-v2): regenerate locked_requirements.txt for pydantic v…
Mar 24, 2026
8152692
agent(pydantic-v2): replace const=True Fields with Literal types in s…
Mar 24, 2026
65da15c
agent(pydantic-v2): rename Field regex= to pattern= in storage client
Mar 24, 2026
e2cdbb3
agent(pydantic-v2): replace deprecated Field min_items with min_lengt…
Mar 24, 2026
b7cfb03
agent(pydantic-v2): add coerce_numbers_to_str to Version model and re…
Mar 24, 2026
e2e6430
agent(pydantic-v2): handle dict-or-model access in WorkflowSpec model…
Mar 24, 2026
6f5ddc0
agent(pydantic-v2): remove migration scripts
Mar 24, 2026
e695f0c
agent(pydantic-v2): add migration episode notes documenting changes a…
Mar 24, 2026
53d3f67
agent(pydantic-v2): add agent discovered knowledge doc
Mar 24, 2026
d62151f
agent(pydantic-v2): fix model_fields access on instance -> class
Mar 24, 2026
92f7e18
intervention(pydantic-v2): manually regen locked_requirements using 3…
fernandol-nvidia Mar 25, 2026
51915f5
agent(pydantic-v2): add default for optional field and update test as…
Mar 25, 2026
9350441
agent(pydantic-v2): handle json_schema_extra being Callable or None i…
Mar 25, 2026
0a3c6eb
agent(pydantic-v2): add mypy ignore for pydantic_settings module
Mar 25, 2026
83c1851
agent(pydantic-v2): normalize extra='forbid' to single quotes in back…
Mar 25, 2026
2703869
agent(pydantic-v2): normalize extra='forbid' to single quotes across …
Mar 25, 2026
c102abd
agent(pydantic-v2): replace removed pydantic.json.pydantic_encoder wi…
Mar 25, 2026
c402794
agent(pydantic-v2): replace custom positive_integer validators with p…
Mar 25, 2026
d40ef9d
agent(pydantic-v2): reformat long json_schema_extra line in node vali…
Mar 25, 2026
ba3b4a7
agent(pydantic-v2): enable coerce_numbers_to_str on ResourceUsage for…
Mar 25, 2026
2888b43
agent(pydantic-v2): update field validator signature and add defaults…
Mar 25, 2026
802e7a0
agent(pydantic-v2): add None defaults to optional fields in workflow …
Mar 25, 2026
b38c655
agent(pydantic-v2): add None defaults to optional fields across respo…
Mar 25, 2026
a2de2a6
agent(pydantic-v2): add None defaults to optional fields in UpdateSta…
Mar 25, 2026
df1e33f
agent(pydantic-v2): Consolidate Pydantic v2 migration notes and updat…
Mar 25, 2026
2d2460e
agent(pydantic-v2): Update migration episode and long-term memory wit…
Mar 25, 2026
44f0623
agent(pydantic-v2): extend pydantic_encoder to handle datetime, UUID,…
Mar 26, 2026
0f962c7
agent(pydantic-v2): fix ExtraArgBaseModel.set_extra to propagate to s…
Mar 26, 2026
487b7f5
agent(pydantic-v2): Fix config history test assertions
Mar 26, 2026
d06c139
agent(pydantic-v2): fix ExtraArgBaseModel.set_extra to rebuild subcla…
Mar 26, 2026
7ac98df
agent(pydantic-v2): fix SubmitResponse pre-validator to use safe fiel…
Mar 26, 2026
bd5c7ae
agent(pydantic-v2): suppress pylint unused-argument warnings in Execu…
Mar 26, 2026
11bcb7f
agent(pydantic-v2): reformat long json_schema_extra lines and functio…
Mar 26, 2026
76b2d25
agent(pydantic-v2): normalize string quotes to double quotes in data …
Mar 26, 2026
8fcfd63
agent(pydantic-v2): normalize ExtraType quotes and suppress pylint pr…
Mar 26, 2026
c40f78e
agent(pydantic-v2): remove unused validation import and reformat long…
Mar 26, 2026
107cfb6
agent(pydantic-v2): reformat long lines in job, task, and workflow mo…
Mar 26, 2026
9223c49
agent(pydantic-v2): extract log key variable to fix line length in Cl…
Mar 26, 2026
a71e161
agent(pydantic-v2): Add final verification memory and long-term patterns
Mar 26, 2026
496819e
agent(pydantic-v2): Add quality verification episode memory
Mar 26, 2026
d835868
agent(pydantic-v2): migrate __fields_set__ to model_fields_set in log…
Mar 26, 2026
bdb485b
agent(pydantic-v2): Final quality gate verification — all 131 tests pass
Mar 26, 2026
e7893b2
agent(pydantic-v2): Add beyond-tests validation episode — model_field…
Mar 26, 2026
68854d1
agent(pydantic-v2): Add ClassVar and Optional imports from typing module
Mar 26, 2026
4c876ed
agent(pydantic-v2): Change _instance fields to ClassVar annotations i…
Mar 26, 2026
e90d7ce
agent(pydantic-v2): Deserialize resource_validations items into Resou…
Mar 26, 2026
cfc0170
agent(pydantic-v2): Add pydantic_encoder to parsed_resource_validatio…
Mar 26, 2026
70eff1b
agent(pydantic-v2): Reformat long line in Pool into multiple lines fo…
Mar 26, 2026
c8dd305
agent(pydantic-v2): Add runtime validation episode and long-term patt…
Mar 26, 2026
c582692
agent(pydantic-v2): update runtime validation episode with full CRUD …
Mar 26, 2026
0bb94c3
intervention(pydantic-v2): Fix static_config
fernandol-nvidia Mar 26, 2026
f9dcba0
intervention(pydantic-v2): backwards compatibility for int value coer…
fernandol-nvidia Mar 26, 2026
d0dc626
intervention(pydantic-v2): Fix implicit None/Any types
fernandol-nvidia Mar 26, 2026
eb7b9e5
intervention(pydantic-v2): More optional default none fixes
fernandol-nvidia Mar 27, 2026
906733b
intervention(pydantic-v2): fix extra ignore behavior
fernandol-nvidia Mar 27, 2026
4d80454
intervention(pydantic-v2): fix more extra ignore
fernandol-nvidia Mar 27, 2026
1b76e95
intervention(pydantic-v2): remove 'dev' and enforce extra=forbid on i…
fernandol-nvidia Mar 31, 2026
3bdad0c
intervention(pydantic-v2): populate_by_name for ExtraArgBaseModel
fernandol-nvidia Apr 1, 2026
5535c2d
intervention(pydantic-v2): fix to_timedelta
fernandol-nvidia Apr 2, 2026
a0249ef
intervention(pydantic-v2): use default_factory for job uuid
fernandol-nvidia Apr 2, 2026
423c3cf
intervention(pydantic-v2): dataclass validation
fernandol-nvidia Apr 2, 2026
8a93035
intervention(pydantic-v2): fix resource rounding errors
fernandol-nvidia Apr 7, 2026
1bd5505
intervention(pydantic-v2): regenerate api for UI
fernandol-nvidia Apr 7, 2026
251ae03
intervention(pydantic-v2): use number for date-time
fernandol-nvidia Apr 7, 2026
2482704
intervention(pydantic-v2): handle type coercion and migration
fernandol-nvidia Apr 7, 2026
c78db79
intervention(pydantic-v2): fix lint
fernandol-nvidia Apr 7, 2026
835d72c
intervention(pydantic-v2): fix resource spec
fernandol-nvidia Apr 7, 2026
16bc105
intervention(pydantic-v2): Remove agent artifacts
fernandol-nvidia Apr 7, 2026
3d7544b
intervention(pydantic-v2): update docs requirements
fernandol-nvidia Apr 7, 2026
a91fbe7
intervention(pydantic-v2): coderabbit feedback
fernandol-nvidia Apr 7, 2026
e439dc5
intervention(pydantic-v2): address breakage due to coderabbit feedback
fernandol-nvidia Apr 8, 2026
175a618
intervention(pydantic-v2): more coderabbit feedback
fernandol-nvidia Apr 8, 2026
e390e1c
intervention(pydantic-v2): more coderabbit feedback
fernandol-nvidia Apr 8, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions bzl/mypy/mypy.ini
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ ignore_missing_imports = True
[mypy-packaging.*]
ignore_missing_imports = True

[mypy-pydantic_settings.*]
ignore_missing_imports = True

[mypy-prometheus_client.*]
ignore_missing_imports = True

Expand Down
5 changes: 2 additions & 3 deletions docs/docs_requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,8 @@
# pip-compile ./docs_requirements.txt -o locked_requirements.txt --allow-unsafe -v --generate-hashes

# Building documentation
# Pin pydantic to match src/requirements.txt
pydantic==1.10.26
autodoc_pydantic==1.9.1
pydantic==2.12.5
autodoc_pydantic==2.2.0
commonmark==0.9.1
nvidia-sphinx-theme==0.0.8
sphinx==7.4.7
Expand Down
230 changes: 169 additions & 61 deletions docs/locked_requirements.txt

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/cli/login.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ class UrlValidator(pydantic.BaseModel):
url: pydantic.AnyHttpUrl
try:
_ = UrlValidator(url=url)
except pydantic.error_wrappers.ValidationError as error:
except pydantic.ValidationError as error:
raise osmo_errors.OSMOUserError(f'Bad url {url}: {error}')

print(f'Logging in to {url}')
Expand Down
2 changes: 1 addition & 1 deletion src/cli/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def _client_version(service_client: client.ServiceClient, args: argparse.Namespa
pass
client_version = version.VERSION
if args.format_type == 'json':
output = {'client': client_version.dict()}
output = {'client': client_version.model_dump()}
if result:
output['service'] = result
print(json.dumps(output, indent=common.JSON_INDENT_SIZE))
Expand Down
2 changes: 1 addition & 1 deletion src/cli/workflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
RESIZE_PREFIX = b'\x00RESIZE:'


class TemplateData(pydantic.BaseModel, extra=pydantic.Extra.forbid):
class TemplateData(pydantic.BaseModel, extra='forbid'):
"""Pydantic model representing parsed template data from workflow files."""
file: str
set_variables: List[str]
Expand Down
14 changes: 7 additions & 7 deletions src/lib/data/dataset/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ class RemoteToRemoteMapping(NamedTuple):

@pydantic.dataclasses.dataclass(
config=pydantic.ConfigDict(
extra=pydantic.Extra.forbid,
extra='forbid',
frozen=True,
),
)
Expand All @@ -211,7 +211,7 @@ class UploadStartResult:

@pydantic.dataclasses.dataclass(
config=pydantic.ConfigDict(
extra=pydantic.Extra.forbid,
extra='forbid',
frozen=True,
),
)
Expand All @@ -225,7 +225,7 @@ class UploadResult:

@pydantic.dataclasses.dataclass(
config=pydantic.ConfigDict(
extra=pydantic.Extra.forbid,
extra='forbid',
frozen=True,
),
)
Expand All @@ -235,14 +235,14 @@ class UpdateStartResult:
"""
upload_response: UploadResponse
current_manifest_path: str
local_update_paths: List[LocalToRemoteMapping] | None
backend_update_paths: List[RemoteToRemoteMapping] | None
remove_regex: str | None
local_update_paths: List[LocalToRemoteMapping] | None = None
backend_update_paths: List[RemoteToRemoteMapping] | None = None
remove_regex: str | None = None


@pydantic.dataclasses.dataclass(
config=pydantic.ConfigDict(
extra=pydantic.Extra.forbid,
extra='forbid',
frozen=True,
),
)
Expand Down
11 changes: 6 additions & 5 deletions src/lib/data/dataset/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,12 @@ class Manager(pydantic.BaseModel):
Manager for a dataset.
"""

class Config:
arbitrary_types_allowed = True
extra = pydantic.Extra.forbid
frozen = True
keep_untouched = (functools.cached_property,)
model_config = pydantic.ConfigDict(
arbitrary_types_allowed=True,
extra='forbid',
frozen=True,
ignored_types=(functools.cached_property,),
)

#########################
# Required fields #
Expand Down
21 changes: 5 additions & 16 deletions src/lib/data/storage/backends/backends.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,9 +229,8 @@ class SwiftBackend(Boto3Backend):
Swift Backend
"""

scheme: str = pydantic.Field(
scheme: Literal['swift'] = pydantic.Field(
default=common.StorageBackendType.SWIFT.value,
const=True,
description='The scheme of the Swift backend.',
)

Expand All @@ -242,7 +241,6 @@ class SwiftBackend(Boto3Backend):

supports_batch_delete: Literal[True] = pydantic.Field(
default=True,
const=True,
description='Whether the backend supports batch delete.',
)

Expand Down Expand Up @@ -390,21 +388,18 @@ class S3Backend(Boto3Backend):
AWS S3 Backend
"""

scheme: str = pydantic.Field(
scheme: Literal['s3'] = pydantic.Field(
default=common.StorageBackendType.S3.value,
const=True,
description='The scheme of the S3 backend.',
)

supports_batch_delete: Literal[True] = pydantic.Field(
default=True,
const=True,
description='Whether the backend supports batch delete.',
)

supports_environment_auth: Literal[True] = pydantic.Field(
default=True,
const=True,
description='Whether the backend supports environment authentication.',
)

Expand Down Expand Up @@ -585,17 +580,15 @@ class GSBackend(Boto3Backend):
Google Cloud Platform GS Backend
"""

scheme: str = pydantic.Field(
scheme: Literal['gs'] = pydantic.Field(
default=common.StorageBackendType.GS.value,
const=True,
description='The scheme of the GS backend.',
)

# Google Cloud Storage does not support batch delete via S3 API:
# https://issuetracker.google.com/issues/162653700
supports_batch_delete: Literal[False] = pydantic.Field(
default=False,
const=True,
description='Whether the backend supports batch delete.',
)

Expand Down Expand Up @@ -708,15 +701,13 @@ class TOSBackend(Boto3Backend):
https://docs.byteplus.com/en/docs/tos/docs-compatibility-with-amazon-s3#appendix-tos-compatible-s3-apis
"""

scheme: str = pydantic.Field(
scheme: Literal['tos'] = pydantic.Field(
default=common.StorageBackendType.TOS.value,
const=True,
description='The scheme of the TOS backend.',
)

supports_batch_delete: Literal[True] = pydantic.Field(
default=True,
const=True,
description='Whether the backend supports batch delete.',
)

Expand Down Expand Up @@ -819,9 +810,8 @@ class AzureBlobStorageBackend(common.StorageBackend):
Azure Blob Storage Backend
"""

scheme: str = pydantic.Field(
scheme: Literal['azure'] = pydantic.Field(
default=common.StorageBackendType.AZURE.value,
const=True,
description='The scheme of the Azure Blob Storage backend.',
)

Expand All @@ -832,7 +822,6 @@ class AzureBlobStorageBackend(common.StorageBackend):

supports_environment_auth: Literal[True] = pydantic.Field(
default=True,
const=True,
description='Whether the backend supports environment authentication.',
)

Expand Down
8 changes: 5 additions & 3 deletions src/lib/data/storage/backends/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,13 +99,15 @@ class StoragePath:
class StorageBackend(
abc.ABC,
pydantic.BaseModel,
extra=pydantic.Extra.forbid,
arbitrary_types_allowed=True,
keep_untouched=(functools.cached_property,), # Don't serialize cached properties
):
"""
Represents information about a storage backend.
"""
model_config = pydantic.ConfigDict(
extra='forbid',
arbitrary_types_allowed=True,
ignored_types=(functools.cached_property,), # Don't serialize cached properties
)

scheme: str
uri: str
Expand Down
31 changes: 13 additions & 18 deletions src/lib/data/storage/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,11 @@ class Client(pydantic.BaseModel):
A storage client that can be used to perform data operations against a remote storage.
"""

class Config:
extra = pydantic.Extra.forbid
frozen = True
keep_untouched = (functools.cached_property,)
model_config = pydantic.ConfigDict(
extra='forbid',
frozen=True,
ignored_types=(functools.cached_property,),
)

#########################
# Factory methods #
Expand Down Expand Up @@ -192,7 +193,7 @@ def create(

storage_uri: str = pydantic.Field(
...,
regex=constants.STORAGE_BACKEND_REGEX,
pattern=constants.STORAGE_BACKEND_REGEX,
description='The URI of the remote storage this instance of storage Client will '
'operate against. Must point to a valid container.',
)
Expand Down Expand Up @@ -231,29 +232,25 @@ def create(
description='Headers to apply to all requests of this client.',
)

@pydantic.root_validator(skip_on_failure=True)
@classmethod
def validate_data_credential_endpoint(cls, values):
@pydantic.model_validator(mode='after')
def validate_data_credential_endpoint(self):
"""
Validates that the data credential endpoint matches the storage backend profile.
"""
data_credential_input = values.get('data_credential_input')
if data_credential_input is not None:
storage_uri = values.get('storage_uri')

if self.data_credential_input is not None:
# Construct backends to validate profiles match
data_cred_backend = backends.construct_storage_backend(
uri=data_credential_input.endpoint,
uri=self.data_credential_input.endpoint,
)
storage_backend = backends.construct_storage_backend(
uri=storage_uri,
uri=self.storage_uri,
)

if data_cred_backend.profile != storage_backend.profile:
raise osmo_errors.OSMOCredentialError(
'Credential endpoint must match the storage backend profile')

return values
return self

@functools.cached_property
def data_credential(self) -> credentials.DataCredential:
Expand Down Expand Up @@ -1195,9 +1192,7 @@ class SingleObjectClient(pydantic.BaseModel):
interacting with a single object.
"""

class Config:
extra = pydantic.Extra.forbid
frozen = True
model_config = pydantic.ConfigDict(extra='forbid', frozen=True)

@overload
@classmethod
Expand Down
6 changes: 3 additions & 3 deletions src/lib/data/storage/constants/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
TOS_REGEX = fr'^tos://{URI_COMPONENT}(/{URI_COMPONENT})+/*$'
AZURE_REGEX = fr'^azure://{URI_COMPONENT}(/{URI_COMPONENT})+/*$'
STORAGE_BACKEND_REGEX = fr'({SWIFT_REGEX}|{S3_REGEX}|{GS_REGEX}|{TOS_REGEX}|{AZURE_REGEX})'
StorageBackendPattern = Annotated[str, pydantic.Field(regex=STORAGE_BACKEND_REGEX)]
StorageBackendPattern = Annotated[str, pydantic.Field(pattern=STORAGE_BACKEND_REGEX)]


# Regex rules for storage profiles
Expand All @@ -50,7 +50,7 @@
STORAGE_PROFILE_REGEX = fr'({SWIFT_PROFILE_REGEX}|{S3_PROFILE_REGEX}|' \
fr'{GS_PROFILE_REGEX}|{TOS_PROFILE_REGEX}|' \
fr'{AZURE_PROFILE_REGEX})'
StorageProfilePattern = Annotated[str, pydantic.Field(regex=STORAGE_PROFILE_REGEX)]
StorageProfilePattern = Annotated[str, pydantic.Field(pattern=STORAGE_PROFILE_REGEX)]

STORAGE_CREDENTIAL_REGEX = fr'({STORAGE_PROFILE_REGEX}|{STORAGE_BACKEND_REGEX})'
StorageCredentialPattern = Annotated[str, pydantic.Field(regex=STORAGE_CREDENTIAL_REGEX)]
StorageCredentialPattern = Annotated[str, pydantic.Field(pattern=STORAGE_CREDENTIAL_REGEX)]
1 change: 1 addition & 0 deletions src/lib/data/storage/core/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ osmo_py_library(
"//src/lib/utils:logging",
"//src/lib/utils:osmo_errors",
requirement("pydantic"),
requirement("pydantic-settings"),
requirement("tqdm"),
],
)
44 changes: 20 additions & 24 deletions src/lib/data/storage/core/executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
)

import pydantic
import pydantic_settings

from . import progress, provider
from ....utils import common, logging as logging_utils, osmo_errors
Expand All @@ -67,32 +68,30 @@
# Executor Schemas (External) #
###################################

class ExecutorParameters(pydantic.BaseSettings):
class ExecutorParameters(pydantic_settings.BaseSettings):
"""
A class for storing parameters regarding multi-process/thread operations.

Allows for environment variable overrides of the parameters.
"""

class Config:
"""
Pydantic configuration for the ExecutorParameters class.
"""
env_prefix = 'OSMO_EXECUTOR_'

@classmethod
def customise_sources(
cls,
init_settings,
env_settings,
file_secret_settings,
):
# Treat explicit None as "unset" so env vars can apply
def init_without_none(settings):
data = init_settings(settings)
return {k: v for k, v in data.items() if v is not None}

return (init_without_none, env_settings, file_secret_settings)
model_config = pydantic_settings.SettingsConfigDict(env_prefix='OSMO_EXECUTOR_')

@classmethod
def settings_customise_sources(
cls,
settings_cls, # pylint: disable=unused-argument
init_settings,
env_settings,
dotenv_settings, # pylint: disable=unused-argument
file_secret_settings,
):
# Treat explicit None as "unset" so env vars can apply.
# Override init_settings to filter out None values.
init_settings.init_kwargs = {
k: v for k, v in init_settings.init_kwargs.items() if v is not None
}
return (init_settings, env_settings, file_secret_settings)

num_processes: int | None = pydantic.Field(
default=None,
Expand Down Expand Up @@ -130,10 +129,7 @@ def init_without_none(settings):
description='The size of the log queue for the executor. Only used for multi-process jobs.',
)

@pydantic.validator(
'num_threads_inflight_multiplier',
'chunk_queue_size_multiplier',
)
@pydantic.field_validator('num_threads_inflight_multiplier', 'chunk_queue_size_multiplier')
@classmethod
def _validate_multiplier_max(cls, v: int) -> int:
if v > MAX_MULTIPLIER:
Expand Down
Loading
Loading