Skip to content

Commit 95df8da

Browse files
authored
Cleanup catalog service (#1582)
Cleanup of catalog service before adding more functionality * Major refactoring - api/dependencies: dependencies injected in handlers - api/routes: endpoint handlers and routing - api/root.py: join all openapi-specs into a single router - models: domain (orm and business logic models) and schema (i/o schemas for openapi) models - db: database tables (i.e. sa schemas for tables) and repositories (crud layer between handlers and db calls) - core: init application and settings (parses values by args, environs, .env or default, in this order) - services: modules/plugins with logic for the app - __main__,__version__ : main entrypoint and version
1 parent a329aea commit 95df8da

Some content is hidden

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

76 files changed

+1755
-1190
lines changed

ci/github/unit-testing/catalog.bash

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ install() {
1212
test() {
1313
pytest --cov=simcore_service_catalog --durations=10 --cov-append \
1414
--color=yes --cov-report=term-missing --cov-report=xml \
15-
-v -m "not travis" services/catalog/tests
15+
-v -m "not travis" services/catalog/tests/unit
1616
}
1717

1818
# Check if the function exists (bash specific)

ci/helpers/ensure_python_pip.bash

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ set -euo pipefail
99
IFS=$'\n\t'
1010

1111
# Pin pip version to a compatible release https://www.python.org/dev/peps/pep-0440/#compatible-release
12-
PIP_VERSION=19.3.1
12+
PIP_VERSION=20.1.1
1313

1414
echo "INFO:" "$(python --version)" "@" "$(command -v python)"
1515

ci/travis/unit-testing/catalog.bash

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ script() {
3434
then
3535
pytest --cov=simcore_service_catalog --durations=10 --cov-append \
3636
--color=yes --cov-report=term-missing --cov-report=xml \
37-
-v -m "not travis" services/catalog/tests
37+
-v -m "not travis" services/catalog/tests/unit
3838
else
3939
echo "No changes detected. Skipping unit-testing of catalog."
4040
fi

packages/postgres-database/docker/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ RUN apt-get update &&\
2323
RUN python -m venv ${VIRTUAL_ENV}
2424

2525
RUN pip --no-cache-dir install --upgrade \
26-
pip~=20.0.2 \
26+
pip~=20.1.1 \
2727
wheel \
2828
setuptools
2929

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
"""
2+
sets up a docker-compose
3+
4+
IMPORTANT: incompatible with pytest_simcore.docker_compose and pytest_simcore.postgres_service
5+
6+
"""
7+
# pylint:disable=unused-variable
8+
# pylint:disable=unused-argument
9+
# pylint:disable=redefined-outer-name
10+
11+
import os
12+
import shutil
13+
import subprocess
14+
import sys
15+
from pathlib import Path
16+
from typing import Callable, Coroutine, Dict, Union
17+
18+
import aiopg.sa
19+
import pytest
20+
import sqlalchemy as sa
21+
import yaml
22+
from dotenv import dotenv_values
23+
24+
import simcore_postgres_database.cli as pg_cli
25+
from simcore_postgres_database.models.base import metadata
26+
27+
current_dir = Path(sys.argv[0] if __name__ == "__main__" else __file__).resolve().parent
28+
29+
30+
@pytest.fixture(scope="session")
31+
def env_devel_file(project_slug_dir: Path) -> Path:
32+
# takes as a bas
33+
env_devel_path = project_slug_dir / ".env-devel"
34+
assert env_devel_path.exists()
35+
return env_devel_path
36+
37+
38+
@pytest.fixture(scope="session")
39+
def test_environment(env_devel_file: Path) -> Dict[str, str]:
40+
env = dotenv_values(env_devel_file, verbose=True, interpolate=True)
41+
return env
42+
43+
44+
@pytest.fixture(scope="session")
45+
def test_docker_compose_file(pytestconfig) -> Path:
46+
"""Get an absolute path to the `docker-compose.yml` file.
47+
Override this fixture in your tests if you need a custom location.
48+
"""
49+
return os.path.join(str(pytestconfig.rootdir), "tests", "docker-compose.yml")
50+
51+
52+
@pytest.fixture(scope="session")
53+
def docker_compose_file(test_environment: Dict[str, str], tmpdir_factory, test_docker_compose_file) -> Path:
54+
# Overrides fixture in https://github.com/avast/pytest-docker
55+
56+
environ = dict(
57+
os.environ
58+
) # NOTE: do not forget to add the current environ here, otherwise docker-compose fails
59+
environ.update(test_environment)
60+
61+
# assumes prototype in cwd
62+
src_path = test_docker_compose_file
63+
assert src_path.exists, f"Expected prototype at cwd, i.e. {src_path.resolve()}"
64+
65+
dst_path = Path(
66+
str(
67+
tmpdir_factory.mktemp("docker_compose_file_fixture").join(
68+
"docker-compose.yml"
69+
)
70+
)
71+
)
72+
73+
shutil.copy(src_path, dst_path.parent)
74+
assert dst_path.exists()
75+
76+
# configs
77+
subprocess.run(
78+
f'docker-compose --file "{src_path}" config > "{dst_path}"',
79+
shell=True,
80+
check=True,
81+
env=environ,
82+
)
83+
84+
return dst_path
85+
86+
87+
@pytest.fixture(scope="session")
88+
def postgres_service2(docker_services, docker_ip, docker_compose_file: Path) -> Dict:
89+
90+
# check docker-compose's environ is resolved properly
91+
config = yaml.safe_load(docker_compose_file.read_text())
92+
environ = config["services"]["postgres"]["environment"]
93+
94+
# builds DSN
95+
config = dict(
96+
user=environ["POSTGRES_USER"],
97+
password=environ["POSTGRES_PASSWORD"],
98+
host=docker_ip,
99+
port=docker_services.port_for("postgres", 5432),
100+
database=environ["POSTGRES_DB"],
101+
)
102+
103+
dsn = "postgresql://{user}:{password}@{host}:{port}/{database}".format(**config)
104+
105+
def _create_checker() -> Callable:
106+
def is_postgres_responsive() -> bool:
107+
try:
108+
engine = sa.create_engine(dsn)
109+
conn = engine.connect()
110+
conn.close()
111+
except sa.exc.OperationalError:
112+
return False
113+
return True
114+
115+
return is_postgres_responsive
116+
117+
# Wait until service is responsive.
118+
docker_services.wait_until_responsive(
119+
check=_create_checker(), timeout=30.0, pause=0.1,
120+
)
121+
122+
config["dsn"] = dsn
123+
return config
124+
125+
126+
@pytest.fixture(scope="session")
127+
def make_engine(postgres_service2: Dict) -> Callable:
128+
dsn = postgres_service2["dsn"] # session scope freezes dsn
129+
130+
def maker(is_async=True) -> Union[Coroutine, Callable]:
131+
return aiopg.sa.create_engine(dsn) if is_async else sa.create_engine(dsn)
132+
133+
return maker
134+
135+
136+
@pytest.fixture
137+
def apply_migration(postgres_service2: Dict, make_engine) -> None:
138+
kwargs = postgres_service2.copy()
139+
kwargs.pop("dsn")
140+
pg_cli.discover.callback(**kwargs)
141+
pg_cli.upgrade.callback("head")
142+
yield
143+
pg_cli.downgrade.callback("base")
144+
pg_cli.clean.callback()
145+
146+
# FIXME: deletes all because downgrade is not reliable!
147+
engine = make_engine(False)
148+
metadata.drop_all(engine)

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
# formatter
1717
black
18+
isort
1819
# dependency manager
1920
pip-tools
2021
# version manager

scripts/openapi/oas_resolver/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ WORKDIR /src
1212

1313
# update pip
1414
RUN pip install --no-cache-dir --upgrade \
15-
pip~=20.0.2 \
15+
pip~=20.1.1 \
1616
wheel \
1717
setuptools
1818

services/api-server/Dockerfile

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
ARG PYTHON_VERSION="3.6.10"
2-
FROM python:${PYTHON_VERSION}-slim as base
2+
FROM python:${PYTHON_VERSION}-slim-buster as base
33
#
44
# USAGE:
55
# cd sercices/api-server
@@ -43,7 +43,7 @@ ENV PYTHONDONTWRITEBYTECODE=1 \
4343
# those from our virtualenv.
4444
ENV PATH="${VIRTUAL_ENV}/bin:$PATH"
4545

46-
EXPOSE 8001
46+
EXPOSE 8000
4747
EXPOSE 3000
4848

4949
# -------------------------- Build stage -------------------
@@ -64,7 +64,7 @@ RUN apt-get update &&\
6464
RUN python -m venv ${VIRTUAL_ENV}
6565

6666
RUN pip install --upgrade --no-cache-dir \
67-
pip~=20.0.2 \
67+
pip~=20.1.1 \
6868
wheel \
6969
setuptools
7070

@@ -111,7 +111,10 @@ ENV PYTHONOPTIMIZE=TRUE
111111

112112
WORKDIR /home/scu
113113

114+
# Starting from clean base image, copies pre-installed virtualenv from cache
114115
COPY --chown=scu:scu --from=cache ${VIRTUAL_ENV} ${VIRTUAL_ENV}
116+
117+
# Copies booting scripts
115118
COPY --chown=scu:scu services/api-server/docker services/api-server/docker
116119
RUN chmod +x services/api-server/docker/*.sh
117120

services/api-server/Makefile

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,13 @@
44
include ../../scripts/common.Makefile
55

66
# Custom variables
7-
APP_NAME := $(notdir $(CURDIR))
8-
APP_CLI_NAME := simcore-service-$(APP_NAME)
9-
export APP_VERSION = $(shell cat VERSION)
10-
SRC_DIR := $(abspath $(CURDIR)/src/$(subst -,_,$(APP_CLI_NAME)))
7+
APP_NAME := $(notdir $(CURDIR))
8+
APP_CLI_NAME := simcore-service-$(APP_NAME)
9+
APP_PACKAGE_NAME := $(subst -,_,$(APP_CLI_NAME))
10+
APP_VERSION := $(shell cat VERSION)
11+
SRC_DIR := $(abspath $(CURDIR)/src/$(APP_PACKAGE_NAME))
12+
13+
export APP_VERSION
1114

1215
.PHONY: reqs
1316
reqs: ## compiles pip requirements (.in -> .txt)
@@ -71,18 +74,32 @@ down: docker-compose.yml ## stops pg fixture
7174
# killing any process using port 8000
7275
-@fuser --kill --verbose --namespace tcp 8000
7376

74-
######################
7577

7678

77-
.PHONY: build
78-
build: ## builds docker image (using main services/docker-compose-build.yml)
79-
@$(MAKE_C) ${REPO_BASE_DIR} target=${APP_NAME} $@
79+
# BUILD ########
80+
81+
82+
.PHONY: build build-nc build-devel build-devel-nc build-cache build-cache-nc
83+
build build-nc build-devel build-devel-nc build-cache build-cache-nc: ## builds docker image (using main services/docker-compose-build.yml)
84+
@$(MAKE_C) ${REPO_BASE_DIR} $@ target=${APP_NAME}
85+
8086

87+
.PHONY: openapi-specs openapi.json
88+
openapi-specs: openapi.json
89+
openapi.json: .env
90+
# generating openapi specs file
91+
python3 -c "import json; from $(APP_PACKAGE_NAME).__main__ import *; print( json.dumps(the_app.openapi(), indent=2) )" > $@
8192

82-
# GENERATION python client -------------------------------------------------
93+
94+
# GENERATION python client ########
8395
.PHONY: python-client generator-help
96+
8497
# SEE https://openapi-generator.tech/docs/usage#generate
8598
# SEE https://openapi-generator.tech/docs/generators/python
99+
#
100+
# TODO: put instead to additional-props.yaml and --config=openapi-generator/python-config.yaml
101+
# TODO: copy this code to https://github.com/ITISFoundation/osparc-simcore-python-client/blob/master/Makefile
102+
#
86103

87104
# NOTE: assumes this repo exists
88105
GIT_USER_ID := ITISFoundation
@@ -91,7 +108,6 @@ GIT_REPO_ID := osparc-simcore-python-client
91108
SCRIPTS_DIR := $(abspath $(CURDIR)/../../scripts)
92109
GENERATOR_NAME := python
93110

94-
# TODO: put instead to additional-props.yaml and --config=openapi-generator/python-config.yaml
95111
ADDITIONAL_PROPS := \
96112
generateSourceCodeOnly=false\
97113
hideGenerationTimestamp=true\
@@ -106,21 +122,13 @@ null :=
106122
space := $(null) #
107123
comma := ,
108124

109-
# TODO: fix this, shall be generated upon start when flag is provided
110-
111-
112-
113-
# TODO: code_samples still added by hand!
114125
client:
115126
# cloning $(GIT_USER_ID)/$(GIT_REPO_ID) -> $@
116127
git clone [email protected]:$(GIT_USER_ID)/$(GIT_REPO_ID).git $@
117128
cd client; git checkout -b "upgrade-${APP_VERSION}"
118129

119130

120-
python-client: client ## runs python client generator
121-
# download openapi.json
122-
curl -O http://localhost:8000/api/v0/openapi.json
123-
131+
python-client: client openapi.json ## runs python client generator
124132
cd $(CURDIR); \
125133
$(SCRIPTS_DIR)/openapi-generator-cli.bash generate \
126134
--generator-name=$(GENERATOR_NAME) \
@@ -134,8 +142,6 @@ python-client: client ## runs python client generator
134142
--release-note="Updated to $(APP_VERSION)"
135143

136144

137-
138-
139145
generator-help: ## help on client-api generator
140146
# generate help
141147
@$(SCRIPTS_DIR)/openapi-generator-cli.bash help generate

services/api-server/openapi.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"openapi": "3.0.2",
33
"info": {
44
"title": "Public API Server",
5-
"description": "**osparc-simcore Public RESTful API Specifications**\n## Python Client\n- Github [repo](https://github.com/ITISFoundation/osparc-simcore-python-client)\n- Quick install: ``pip install git+https://github.com/ITISFoundation/osparc-simcore-python-client.git``\n",
5+
"description": "**osparc-simcore Public RESTful API Specifications**\n## Python Library\n- Check the [documentation](https://itisfoundation.github.io/osparc-simcore-python-client)\n- Quick install: ``pip install git+https://github.com/ITISFoundation/osparc-simcore-python-client.git``\n",
66
"version": "0.3.0",
77
"x-logo": {
88
"url": "https://raw.githubusercontent.com/ITISFoundation/osparc-manual/b809d93619512eb60c827b7e769c6145758378d0/_media/osparc-logo.svg",

services/catalog/.cookiecutterrc

Lines changed: 0 additions & 23 deletions
This file was deleted.

services/catalog/.env-devel

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#
2+
# Environment variables used to configure this service
3+
#
4+
5+
LOG_LEVEL=DEBUG
6+
7+
POSTGRES_USER=test
8+
POSTGRES_PASSWORD=test
9+
POSTGRES_DB=test
10+
POSTGRES_HOST=localhost
11+
12+
# Enables debug
13+
SC_BOOT_MODE=debug-ptvsd

services/catalog/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
docker-compose.yml
2+
.env

0 commit comments

Comments
 (0)