Skip to content

Commit 850be24

Browse files
authored
✨ Is621/api server exposes GET /solvers/*/releases/*/jobs/*/outputs/logfile (⚠️ devops) (ITISFoundation#3051)
1 parent f6ed2fd commit 850be24

File tree

29 files changed

+857
-150
lines changed

29 files changed

+857
-150
lines changed

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

Lines changed: 43 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
required fields in postgres_database.models tables or pydantic models.
1111
"""
1212

13+
1314
import itertools
1415
import json
1516
import random
@@ -19,6 +20,8 @@
1920

2021
import faker
2122
from simcore_postgres_database.models.comp_pipeline import StateType
23+
from simcore_postgres_database.models.projects import projects
24+
from simcore_postgres_database.models.users import users
2225
from simcore_postgres_database.webserver_models import ProjectType, UserStatus
2326

2427
STATES = [
@@ -30,40 +33,69 @@
3033
]
3134

3235

33-
fake = faker.Faker()
36+
_faker = faker.Faker()
37+
38+
39+
def _compute_hash(password: str) -> str:
40+
try:
41+
# 'passlib' will be used only if already installed.
42+
# This way we do not force all modules to install
43+
# it only for testing.
44+
import passlib.hash
45+
46+
return passlib.hash.sha256_crypt.using(rounds=1000).hash(password)
47+
48+
except ImportError:
49+
# if 'passlib' is not installed, we will use a library
50+
# from the python distribution for convenience
51+
import hashlib
52+
53+
return hashlib.sha224(password.encode("ascii")).hexdigest()
54+
55+
56+
_DEFAULT_HASH = _compute_hash("secret")
3457

3558

3659
def random_user(**overrides) -> Dict[str, Any]:
3760
data = dict(
38-
name=fake.name(),
39-
email=fake.email(),
40-
password_hash=fake.numerify(text="#" * 5),
61+
name=_faker.name(),
62+
email=_faker.email(),
63+
password_hash=_DEFAULT_HASH,
4164
status=UserStatus.ACTIVE,
42-
created_ip=fake.ipv4(),
65+
created_ip=_faker.ipv4(),
4366
)
67+
assert set(data.keys()).issubset(set(c.name for c in users.columns)) # nosec
68+
69+
# transform password in hash
70+
password = overrides.pop("password", None)
71+
if password:
72+
overrides["password_hash"] = _compute_hash(password)
73+
4474
data.update(overrides)
4575
return data
4676

4777

4878
def random_project(**overrides) -> Dict[str, Any]:
4979
"""Generates random fake data projects DATABASE table"""
5080
data = dict(
51-
uuid=fake.uuid4(),
52-
name=fake.word(),
53-
description=fake.sentence(),
54-
prj_owner=fake.pyint(),
55-
thumbnail=fake.image_url(width=120, height=120),
81+
uuid=_faker.uuid4(),
82+
name=_faker.word(),
83+
description=_faker.sentence(),
84+
prj_owner=_faker.pyint(),
85+
thumbnail=_faker.image_url(width=120, height=120),
5686
access_rights={},
5787
workbench={},
5888
published=False,
5989
)
90+
assert set(data.keys()).issubset(set(c.name for c in projects.columns)) # nosec
91+
6092
data.update(overrides)
6193
return data
6294

6395

6496
def random_group(**overrides) -> Dict[str, Any]:
6597
data = dict(
66-
name=fake.company(), description=fake.text(), type=ProjectType.STANDARD.name
98+
name=_faker.company(), description=_faker.text(), type=ProjectType.STANDARD.name
6799
)
68100
data.update(overrides)
69101
return data

services/api-server/VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.3.1
1+
0.4.0

services/api-server/openapi.json

Lines changed: 90 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"info": {
44
"title": "osparc.io web API",
55
"description": "osparc-simcore public web API specifications",
6-
"version": "0.3.1",
6+
"version": "0.4.0",
77
"x-logo": {
88
"url": "https://raw.githubusercontent.com/ITISFoundation/osparc-manual/b809d93619512eb60c827b7e769c6145758378d0/_media/osparc-logo.svg",
99
"altText": "osparc-simcore logo"
@@ -993,6 +993,93 @@
993993
}
994994
]
995995
}
996+
},
997+
"/v0/solvers/{solver_key}/releases/{version}/jobs/{job_id}/outputs/logfile": {
998+
"get": {
999+
"tags": [
1000+
"solvers"
1001+
],
1002+
"summary": "Get Job Output Logfile",
1003+
"description": "Special extra output with persistent logs file for the solver run.\n\nNOTE: this is not a log stream but a predefined output that is only\navailable after the job is done.",
1004+
"operationId": "get_job_output_logfile",
1005+
"parameters": [
1006+
{
1007+
"required": true,
1008+
"schema": {
1009+
"title": "Solver Key",
1010+
"pattern": "^(simcore)/(services)/comp(/[\\w/-]+)+$",
1011+
"type": "string"
1012+
},
1013+
"name": "solver_key",
1014+
"in": "path"
1015+
},
1016+
{
1017+
"required": true,
1018+
"schema": {
1019+
"title": "Version",
1020+
"pattern": "^(0|[1-9]\\d*)(\\.(0|[1-9]\\d*)){2}(-(0|[1-9]\\d*|\\d*[-a-zA-Z][-\\da-zA-Z]*)(\\.(0|[1-9]\\d*|\\d*[-a-zA-Z][-\\da-zA-Z]*))*)?(\\+[-\\da-zA-Z]+(\\.[-\\da-zA-Z-]+)*)?$",
1021+
"type": "string"
1022+
},
1023+
"name": "version",
1024+
"in": "path"
1025+
},
1026+
{
1027+
"required": true,
1028+
"schema": {
1029+
"title": "Job Id",
1030+
"type": "string",
1031+
"format": "uuid"
1032+
},
1033+
"name": "job_id",
1034+
"in": "path"
1035+
}
1036+
],
1037+
"responses": {
1038+
"307": {
1039+
"description": "Successful Response"
1040+
},
1041+
"200": {
1042+
"description": "Returns a log file",
1043+
"content": {
1044+
"application/octet-stream": {
1045+
"schema": {
1046+
"type": "string",
1047+
"format": "binary"
1048+
}
1049+
},
1050+
"application/zip": {
1051+
"schema": {
1052+
"type": "string",
1053+
"format": "binary"
1054+
}
1055+
},
1056+
"text/plain": {
1057+
"schema": {
1058+
"type": "string"
1059+
}
1060+
}
1061+
}
1062+
},
1063+
"404": {
1064+
"description": "Log not found"
1065+
},
1066+
"422": {
1067+
"description": "Validation Error",
1068+
"content": {
1069+
"application/json": {
1070+
"schema": {
1071+
"$ref": "#/components/schemas/HTTPValidationError"
1072+
}
1073+
}
1074+
}
1075+
}
1076+
},
1077+
"security": [
1078+
{
1079+
"HTTPBasic": []
1080+
}
1081+
]
1082+
}
9961083
}
9971084
},
9981085
"components": {
@@ -1509,7 +1596,8 @@
15091596
"ANONYMOUS",
15101597
"GUEST",
15111598
"USER",
1512-
"TESTER"
1599+
"TESTER",
1600+
"ADMIN"
15131601
],
15141602
"type": "string",
15151603
"description": "An enumeration."

services/api-server/requirements/_test.in

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ codecov
1717
coveralls
1818
docker
1919
faker
20-
fsspec # upload/download files to minio
20+
types-boto3
21+
moto[server] # mock out tests based on AWS-S3
2122
passlib[bcrypt]
2223
pylint
2324
pytest
@@ -27,4 +28,3 @@ pytest-docker
2728
pytest-mock
2829
pytest-runner
2930
respx
30-
tenacity

0 commit comments

Comments
 (0)