Skip to content

Commit 245e495

Browse files
authored
Is621/director2 adds routes to access logfile (ITISFoundation#3067)
1 parent d38fe91 commit 245e495

File tree

28 files changed

+2403
-808
lines changed

28 files changed

+2403
-808
lines changed

packages/pytest-simcore/src/pytest_simcore/docker_compose.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ def simcore_docker_compose(
145145
docker_compose_path.exists() for docker_compose_path in docker_compose_paths
146146
)
147147

148-
config = run_docker_compose_config(
148+
compose_specs = run_docker_compose_config(
149149
project_dir=osparc_simcore_root_dir / "services",
150150
docker_compose_paths=docker_compose_paths,
151151
env_file_path=env_file_for_testing,
@@ -154,10 +154,10 @@ def simcore_docker_compose(
154154
# NOTE: do not add indent. Copy&Paste log into editor instead
155155
print(
156156
HEADER_STR.format("simcore docker-compose"),
157-
json.dumps(config),
157+
json.dumps(compose_specs),
158158
HEADER_STR.format("-"),
159159
)
160-
return config
160+
return compose_specs
161161

162162

163163
@pytest.fixture(scope="module")
@@ -214,7 +214,7 @@ def ops_docker_compose(
214214
)
215215
assert docker_compose_path.exists()
216216

217-
config = run_docker_compose_config(
217+
compose_specs = run_docker_compose_config(
218218
project_dir=osparc_simcore_root_dir / "services",
219219
docker_compose_paths=docker_compose_path,
220220
env_file_path=env_file_for_testing,
@@ -223,10 +223,10 @@ def ops_docker_compose(
223223
# NOTE: do not add indent. Copy&Paste log into editor instead
224224
print(
225225
HEADER_STR.format("ops docker-compose"),
226-
json.dumps(config),
226+
json.dumps(compose_specs),
227227
HEADER_STR.format("-"),
228228
)
229-
return config
229+
return compose_specs
230230

231231

232232
@pytest.fixture(scope="module")

packages/pytest-simcore/src/pytest_simcore/docker_swarm.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,7 @@ def docker_stack(
242242
f"returncode={err.returncode}",
243243
f"stdout={err.stdout}",
244244
f"stderr={err.stderr}",
245+
"\nTIP: frequent failure is due to a corrupt .env file: Delete .env and .env.bak",
245246
)
246247
raise
247248

packages/pytest-simcore/src/pytest_simcore/postgres_service.py

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
# pylint:disable=redefined-outer-name
2-
# pylint:disable=unused-argument
3-
# pylint:disable=unused-variable
4-
from typing import AsyncIterator, Dict, Final, Iterator, List
1+
# pylint: disable=redefined-outer-name
2+
# pylint: disable=unused-argument
3+
# pylint: disable=unused-variable
4+
5+
from typing import AsyncIterator, Final, Iterator, TypedDict
56

67
import pytest
78
import sqlalchemy as sa
@@ -17,9 +18,17 @@
1718
TEMPLATE_DB_TO_RESTORE = "template_simcore_db"
1819

1920

21+
class PostgresTestConfig(TypedDict):
22+
user: str
23+
password: str
24+
database: str
25+
host: str
26+
port: str
27+
28+
2029
def execute_queries(
2130
postgres_engine: sa.engine.Engine,
22-
sql_statements: List[str],
31+
sql_statements: list[str],
2332
ignore_errors: bool = False,
2433
) -> None:
2534
"""runs the queries in the list in order"""
@@ -34,7 +43,9 @@ def execute_queries(
3443
print(f"SQL error which can be ignored {e}")
3544

3645

37-
def create_template_db(postgres_dsn: Dict, postgres_engine: sa.engine.Engine) -> None:
46+
def create_template_db(
47+
postgres_dsn: PostgresTestConfig, postgres_engine: sa.engine.Engine
48+
) -> None:
3849
# create a template db, the removal is necessary to allow for the usage of --keep-docker-up
3950
queries = [
4051
# disconnect existing users
@@ -69,15 +80,17 @@ def drop_template_db(postgres_engine: sa.engine.Engine) -> None:
6980

7081
@pytest.fixture(scope="module")
7182
def postgres_with_template_db(
72-
postgres_db: sa.engine.Engine, postgres_dsn: Dict, postgres_engine: sa.engine.Engine
83+
postgres_db: sa.engine.Engine,
84+
postgres_dsn: PostgresTestConfig,
85+
postgres_engine: sa.engine.Engine,
7386
) -> Iterator[sa.engine.Engine]:
7487
create_template_db(postgres_dsn, postgres_engine)
7588
yield postgres_engine
7689
drop_template_db(postgres_engine)
7790

7891

7992
@pytest.fixture
80-
def drop_db_engine(postgres_dsn: Dict) -> sa.engine.Engine:
93+
def drop_db_engine(postgres_dsn: PostgresTestConfig) -> sa.engine.Engine:
8194
postgres_dsn_copy = postgres_dsn.copy() # make a copy to change these parameters
8295
postgres_dsn_copy["database"] = "postgres"
8396
dsn = "postgresql://{user}:{password}@{host}:{port}/{database}".format(
@@ -88,7 +101,7 @@ def drop_db_engine(postgres_dsn: Dict) -> sa.engine.Engine:
88101

89102
@pytest.fixture
90103
def database_from_template_before_each_function(
91-
postgres_dsn: Dict, drop_db_engine: sa.engine.Engine, postgres_db
104+
postgres_dsn: PostgresTestConfig, drop_db_engine: sa.engine.Engine, postgres_db
92105
) -> None:
93106
"""
94107
Will recrate the db before running each test.
@@ -118,10 +131,10 @@ def database_from_template_before_each_function(
118131

119132

120133
@pytest.fixture(scope="module")
121-
def postgres_dsn(docker_stack: Dict, testing_environ_vars: Dict) -> Dict[str, str]:
134+
def postgres_dsn(docker_stack: dict, testing_environ_vars: dict) -> PostgresTestConfig:
122135
assert "pytest-simcore_postgres" in docker_stack["services"]
123136

124-
pg_config = {
137+
pg_config: PostgresTestConfig = {
125138
"user": testing_environ_vars["POSTGRES_USER"],
126139
"password": testing_environ_vars["POSTGRES_PASSWORD"],
127140
"database": testing_environ_vars["POSTGRES_DB"],
@@ -138,7 +151,7 @@ def postgres_dsn(docker_stack: Dict, testing_environ_vars: Dict) -> Dict[str, st
138151

139152

140153
@pytest.fixture(scope="module")
141-
def postgres_engine(postgres_dsn: Dict[str, str]) -> Iterator[sa.engine.Engine]:
154+
def postgres_engine(postgres_dsn: PostgresTestConfig) -> Iterator[sa.engine.Engine]:
142155
dsn = "postgresql://{user}:{password}@{host}:{port}/{database}".format(
143156
**postgres_dsn
144157
)
@@ -165,15 +178,15 @@ def postgres_engine(postgres_dsn: Dict[str, str]) -> Iterator[sa.engine.Engine]:
165178

166179

167180
@pytest.fixture(scope="module")
168-
def postgres_dsn_url(postgres_dsn: Dict[str, str]) -> str:
181+
def postgres_dsn_url(postgres_dsn: PostgresTestConfig) -> str:
169182
return "postgresql://{user}:{password}@{host}:{port}/{database}".format(
170183
**postgres_dsn
171184
)
172185

173186

174187
@pytest.fixture(scope="module")
175188
def postgres_db(
176-
postgres_dsn: Dict[str, str],
189+
postgres_dsn: PostgresTestConfig[str, str],
177190
postgres_engine: sa.engine.Engine,
178191
) -> Iterator[sa.engine.Engine]:
179192
"""An postgres database init with empty tables and an sqlalchemy engine connected to it"""
@@ -215,7 +228,10 @@ async def sqlalchemy_async_engine(
215228

216229

217230
@pytest.fixture(scope="function")
218-
def postgres_host_config(postgres_dsn: Dict[str, str], monkeypatch) -> Dict[str, str]:
231+
def postgres_host_config(
232+
postgres_dsn: PostgresTestConfig, monkeypatch
233+
) -> PostgresTestConfig:
234+
"""sets postgres env vars and returns config"""
219235
monkeypatch.setenv("POSTGRES_USER", postgres_dsn["user"])
220236
monkeypatch.setenv("POSTGRES_PASSWORD", postgres_dsn["password"])
221237
monkeypatch.setenv("POSTGRES_DB", postgres_dsn["database"])

packages/simcore-sdk/src/simcore_sdk/node_ports_common/filemanager.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ async def _get_download_link(
4343
session: ClientSession,
4444
link_type: storage_client.LinkType,
4545
) -> URL:
46+
"""
47+
:raises exceptions.S3InvalidPathError
48+
:raises exceptions.StorageInvalidCall
49+
:raises exceptions.StorageServerIssue
50+
"""
4651
link: AnyUrl = await storage_client.get_download_file_link(
4752
session, file_id, store_id, user_id, link_type
4853
)
@@ -145,7 +150,13 @@ async def get_download_link_from_s3(
145150
s3_object: str,
146151
link_type: storage_client.LinkType,
147152
client_session: Optional[ClientSession] = None,
148-
) -> Optional[URL]:
153+
) -> URL:
154+
"""
155+
:raises exceptions.NodeportsException
156+
:raises exceptions.S3InvalidPathError
157+
:raises exceptions.StorageInvalidCall
158+
:raises exceptions.StorageServerIssue
159+
"""
149160
if store_name is None and store_id is None:
150161
raise exceptions.NodeportsException(msg="both store name and store id are None")
151162

packages/simcore-sdk/src/simcore_sdk/node_ports_common/storage_client.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,10 @@ async def get_download_file_link(
7676
user_id: UserID,
7777
link_type: LinkType,
7878
) -> AnyUrl:
79+
"""
80+
:raises exceptions.StorageInvalidCall
81+
:raises exceptions.StorageServerIssue
82+
"""
7983
if (
8084
not isinstance(file_id, str)
8185
or not isinstance(location_id, str)

packages/simcore-sdk/src/simcore_sdk/node_ports_v2/port_utils.py

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,16 +68,45 @@ async def get_value_from_link(
6868

6969
async def get_download_link_from_storage(
7070
user_id: int, value: FileLink, link_type: LinkType
71-
) -> Optional[AnyUrl]:
71+
) -> AnyUrl:
72+
"""
73+
:raises exceptions.NodeportsException
74+
:raises exceptions.S3InvalidPathError
75+
:raises exceptions.StorageInvalidCall
76+
:raises exceptions.StorageServerIssue
77+
"""
7278
log.debug("getting link to file from storage %s", value)
79+
7380
link = await filemanager.get_download_link_from_s3(
7481
user_id=user_id,
7582
store_id=f"{value.store}",
7683
store_name=None,
7784
s3_object=value.path,
7885
link_type=link_type,
7986
)
80-
return parse_obj_as(AnyUrl, f"{link}") if link else None
87+
88+
# could raise ValidationError but will never do it since
89+
assert isinstance(link, URL) # nosec
90+
return parse_obj_as(AnyUrl, f"{link}")
91+
92+
93+
async def get_download_link_from_storage_overload(
94+
user_id: int, project_id: str, node_id: str, file_name: str, link_type: LinkType
95+
) -> AnyUrl:
96+
"""Overloads get_download_link_from_storage with arguments that match those in
97+
get_upload_link_from_storage
98+
99+
"""
100+
# NOTE: might consider using https://github.com/mrocklin/multipledispatch/ in the future?
101+
s3_object = data_items_utils.encode_file_id(Path(file_name), project_id, node_id)
102+
link = await filemanager.get_download_link_from_s3(
103+
user_id=user_id,
104+
store_name=config.STORE,
105+
store_id=None,
106+
s3_object=s3_object,
107+
link_type=link_type,
108+
)
109+
return parse_obj_as(AnyUrl, f"{link}")
81110

82111

83112
async def get_upload_link_from_storage(

scripts/common.Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ REPO_BASE_DIR := $(shell git rev-parse --show-toplevel)
3737

3838
# relevant repo folders
3939
SCRIPTS_DIR := $(abspath $(REPO_BASE_DIR)/scripts)
40+
PACKAGES_DIR := $(abspath $(REPO_BASE_DIR)/packages)
4041

4142
# virtual env
4243
EXPECTED_PYTHON_VERSION := $(shell cat $(REPO_BASE_DIR)/requirements/PYTHON_VERSION)

services/director-v2/Makefile

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,22 @@ openapi.json: .env
2121
python3 -c "import json; from $(APP_PACKAGE_NAME).main import *; print( json.dumps(the_app.openapi(), indent=2) )" > $@
2222

2323

24+
DOCKER_API_VERSION ?= 1.41
25+
.PHONY: directorv2_rest_api_schemas.py
26+
directorv2_rest_api_schemas.py: openapi.json ## auto-generates pydantic models for Docker REST API models
27+
# auto-generates $@ from $<
28+
$(SCRIPTS_DIR)/openapi-pydantic-models-generator.bash \
29+
--input $< \
30+
--output $@ \
31+
--field-constraints \
32+
--reuse-model \
33+
--enum-field-as-literal=all
34+
35+
# formats
36+
@black $@
37+
# copy output to src/models_library/generated_models...
38+
@mv $@ $(PACKAGES_DIR)/models-library/src/models_library/generated_models/$@
39+
# done
2440

2541
# DEVELOPMENT #############
2642
include .env

services/director-v2/VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2.0.0
1+
2.1.0

0 commit comments

Comments
 (0)