Skip to content

Commit 1616c0d

Browse files
authored
Merge branch 'master' into feature/new-plus-button
2 parents 0ff6b24 + 5d052a6 commit 1616c0d

File tree

45 files changed

+1801
-1208
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+1801
-1208
lines changed

packages/common-library/src/common_library/basic_types.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@
33

44
from pydantic_core import PydanticUndefined
55

6-
# SEE https://github.com/fastapi/fastapi/blob/master/fastapi/_compat.py#L75-L78
76
Undefined = PydanticUndefined
87
DEFAULT_FACTORY: Any = Undefined
9-
# Use `UNSET` as default when default_factory
8+
# Use `DEFAULT_FACTORY` as field default when using Field(default_factory=...)
109
# SEE https://github.com/ITISFoundation/osparc-simcore/pull/6882
10+
# SEE https://github.com/ITISFoundation/osparc-simcore/pull/7112#discussion_r1933432238
11+
# SEE https://github.com/fastapi/fastapi/blob/master/fastapi/_compat.py#L75-L78
1112

1213

1314
class LogLevel(StrEnum):
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
"""Add product owners email col
2+
3+
Revision ID: 1bc517536e0a
4+
Revises: 5f88b513cd4c
5+
Create Date: 2025-01-29 10:05:58.254306+00:00
6+
7+
"""
8+
import sqlalchemy as sa
9+
from alembic import op
10+
11+
# revision identifiers, used by Alembic.
12+
revision = "1bc517536e0a"
13+
down_revision = "5f88b513cd4c"
14+
branch_labels = None
15+
depends_on = None
16+
17+
18+
def upgrade():
19+
# ### commands auto generated by Alembic - please adjust! ###
20+
op.add_column(
21+
"products", sa.Column("product_owners_email", sa.String(), nullable=True)
22+
)
23+
# ### end Alembic commands ###
24+
25+
26+
def downgrade():
27+
# ### commands auto generated by Alembic - please adjust! ###
28+
op.drop_column("products", "product_owners_email")
29+
# ### end Alembic commands ###

packages/postgres-database/src/simcore_postgres_database/models/products.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,12 @@ class ProductLoginSettingsDict(TypedDict, total=False):
154154
doc="Support email for this product"
155155
'Therefore smtp_sender = f"{display_name} support <{support_email}>"',
156156
),
157+
sa.Column(
158+
"product_owners_email",
159+
sa.String,
160+
nullable=True,
161+
doc="Alternative support email directed to POs only (e.g. for account request, sales, etc)",
162+
),
157163
sa.Column(
158164
"twilio_messaging_sid",
159165
sa.String,

packages/pytest-simcore/src/pytest_simcore/helpers/faker_factories.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,12 @@ def random_product(
227227
"short_name": suffix[:4],
228228
"host_regex": r"[a-zA-Z0-9]+\.com",
229229
"support_email": f"support@{suffix}.io",
230-
"twilio_messaging_sid": fake.random_element(elements=(None, fake.uuid4()[:34])),
230+
"product_owners_email": fake.random_element(
231+
elements=[f"product-onwers@{suffix}.io", None]
232+
),
233+
"twilio_messaging_sid": fake.random_element(
234+
elements=(None, f"{fake.uuid4()}"[:34])
235+
),
231236
"vendor": Vendor(
232237
name=fake.company(),
233238
copyright=fake.company_suffix(),

packages/settings-library/setup.cfg

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ universal = 1
1414
# Define setup.py command aliases here
1515
test = pytest
1616

17-
# NOTE: uncomment when pytest-asyncio is added in requirements
18-
# [tool:pytest]
19-
# asyncio_mode = auto
17+
[tool:pytest]
18+
# SEE https://docs.pytest.org/en/stable/how-to/capture-warnings.html
19+
filterwarnings =
20+
error

packages/settings-library/src/settings_library/application.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from typing import Annotated
2+
13
from pydantic import Field, PositiveInt
24

35
from .base import BaseCustomSettings
@@ -18,11 +20,13 @@ class BaseApplicationSettings(BaseCustomSettings):
1820
# @Dockerfile
1921
SC_BOOT_MODE: BootModeEnum | None = None
2022
SC_BOOT_TARGET: BuildTargetEnum | None = None
21-
SC_HEALTHCHECK_TIMEOUT: PositiveInt | None = Field(
22-
default=None,
23-
description="If a single run of the check takes longer than timeout seconds "
24-
"then the check is considered to have failed."
25-
"It takes retries consecutive failures of the health check for the container to be considered unhealthy.",
26-
)
23+
SC_HEALTHCHECK_TIMEOUT: Annotated[
24+
PositiveInt | None,
25+
Field(
26+
description="If a single run of the check takes longer than timeout seconds "
27+
"then the check is considered to have failed."
28+
"It takes retries consecutive failures of the health check for the container to be considered unhealthy.",
29+
),
30+
] = None
2731
SC_USER_ID: int | None = None
2832
SC_USER_NAME: str | None = None

packages/settings-library/src/settings_library/director_v0.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from functools import cached_property
2+
from typing import Annotated
23

34
from pydantic import AnyHttpUrl, Field, TypeAdapter
45
from settings_library.base import BaseCustomSettings
@@ -10,9 +11,9 @@ class DirectorV0Settings(BaseCustomSettings):
1011

1112
DIRECTOR_HOST: str = "director"
1213
DIRECTOR_PORT: PortInt = TypeAdapter(PortInt).validate_python(8000)
13-
DIRECTOR_VTAG: VersionTag = Field(
14-
default="v0", description="Director-v0 service API's version tag"
15-
)
14+
DIRECTOR_VTAG: Annotated[
15+
VersionTag, Field(description="Director-v0 service API's version tag")
16+
] = "v0"
1617

1718
@cached_property
1819
def endpoint(self) -> str:

packages/settings-library/src/settings_library/docker_registry.py

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from functools import cached_property
2-
from typing import Any, Self
2+
from typing import Annotated, Any, Self
33

44
from pydantic import (
55
AnyHttpUrl,
@@ -15,37 +15,45 @@
1515

1616

1717
class RegistrySettings(BaseCustomSettings):
18-
REGISTRY_AUTH: bool = Field(..., description="do registry authentication")
19-
REGISTRY_PATH: str | None = Field(
20-
default=None,
21-
# This is useful in case of a local registry, where the registry url (path) is relative to the host docker engine"
22-
description="development mode only, in case a local registry is used - "
23-
"this is the hostname to the docker registry as seen from the host running the containers (e.g. 127.0.0.1:5000)",
24-
)
25-
# NOTE: name is missleading, http or https protocol are not included
26-
REGISTRY_URL: str = Field(
27-
...,
28-
description="hostname of docker registry (without protocol but with port if available)",
29-
min_length=1,
30-
)
18+
REGISTRY_AUTH: Annotated[bool, Field(description="do registry authentication")]
19+
REGISTRY_PATH: Annotated[
20+
str | None,
21+
Field(
22+
# This is useful in case of a local registry, where the registry url (path) is relative to the host docker engine"
23+
description="development mode only, in case a local registry is used - "
24+
"this is the hostname to the docker registry as seen from the host running the containers (e.g. 127.0.0.1:5000)",
25+
),
26+
] = None
3127

32-
REGISTRY_USER: str = Field(
33-
..., description="username to access the docker registry"
34-
)
35-
REGISTRY_PW: SecretStr = Field(
36-
..., description="password to access the docker registry"
37-
)
38-
REGISTRY_SSL: bool = Field(
39-
..., description="True if docker registry is using HTTPS protocol"
40-
)
28+
REGISTRY_URL: Annotated[
29+
str,
30+
Field(
31+
# NOTE: name is missleading, http or https protocol are not included
32+
description="hostname of docker registry (without protocol but with port if available)",
33+
min_length=1,
34+
),
35+
]
36+
37+
REGISTRY_USER: Annotated[
38+
str,
39+
Field(description="username to access the docker registry"),
40+
]
41+
REGISTRY_PW: Annotated[
42+
SecretStr,
43+
Field(description="password to access the docker registry"),
44+
]
45+
REGISTRY_SSL: Annotated[
46+
bool,
47+
Field(description="True if docker registry is using HTTPS protocol"),
48+
]
4149

4250
@field_validator("REGISTRY_PATH", mode="before")
4351
@classmethod
4452
def _escape_none_string(cls, v) -> Any | None:
4553
return None if v == "None" else v
4654

4755
@model_validator(mode="after")
48-
def check_registry_authentication(self: Self) -> Self:
56+
def _check_registry_authentication(self: Self) -> Self:
4957
if self.REGISTRY_AUTH and any(
5058
not v for v in (self.REGISTRY_USER, self.REGISTRY_PW)
5159
):

packages/settings-library/src/settings_library/ec2.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
from typing import Annotated
22

3-
from pydantic import AnyHttpUrl, BeforeValidator, Field, TypeAdapter
3+
from pydantic import BeforeValidator, Field
44
from pydantic_settings import SettingsConfigDict
55

66
from .base import BaseCustomSettings
7-
8-
ANY_HTTP_URL_ADAPTER: TypeAdapter = TypeAdapter(AnyHttpUrl)
7+
from .utils_validators import validate_nullable_url
98

109

1110
class EC2Settings(BaseCustomSettings):
1211
EC2_ACCESS_KEY_ID: str
1312
EC2_ENDPOINT: Annotated[
14-
str, BeforeValidator(lambda x: str(ANY_HTTP_URL_ADAPTER.validate_python(x)))
15-
] | None = Field(default=None, description="do not define if using standard AWS")
13+
str | None,
14+
BeforeValidator(validate_nullable_url),
15+
Field(description="do not define if using standard AWS"),
16+
] = None
1617
EC2_REGION_NAME: str = "us-east-1"
1718
EC2_SECRET_ACCESS_KEY: str
1819

packages/settings-library/src/settings_library/efs.py

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,26 @@
11
from pathlib import Path
2+
from typing import Annotated
23

34
from pydantic import Field
45

56
from .base import BaseCustomSettings
67

78

89
class AwsEfsSettings(BaseCustomSettings):
9-
EFS_DNS_NAME: str = Field(
10-
description="AWS Elastic File System DNS name",
11-
examples=["fs-xxx.efs.us-east-1.amazonaws.com"],
12-
)
10+
EFS_DNS_NAME: Annotated[
11+
str,
12+
Field(
13+
description="AWS Elastic File System DNS name",
14+
examples=["fs-xxx.efs.us-east-1.amazonaws.com"],
15+
),
16+
]
1317
EFS_PROJECT_SPECIFIC_DATA_DIRECTORY: str
14-
EFS_MOUNTED_PATH: Path = Field(
15-
description="This is the path where EFS is mounted to the EC2 machine",
16-
)
18+
EFS_MOUNTED_PATH: Annotated[
19+
Path,
20+
Field(
21+
description="This is the path where EFS is mounted to the EC2 machine",
22+
),
23+
]
1724

1825

1926
NFS_PROTOCOL = "4.1"

0 commit comments

Comments
 (0)