Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

♻️ ✨ Is638/adds CLI to dynamic-sidecar (round 2) #3152

Merged
merged 9 commits into from
Jun 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
15 changes: 10 additions & 5 deletions services/dynamic-sidecar/Makefile
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
include ../../scripts/common.Makefile
include ../../scripts/common-service.Makefile

APP_NAME := $(notdir $(CURDIR))

.DEFAULT_GOAL := help


Expand All @@ -12,10 +10,17 @@ APP_NAME := $(notdir $(CURDIR))
@echo "WARNING ##### $@ does not exist, cloning $< as $@ ############"; cp $< $@)


.PHONY: openapi.json


.PHONY: openapi-specs openapi.json
openapi-specs: openapi.json
openapi.json: .env ## Creates OAS document openapi.json
# generating openapi specs (OAS) file
export $(shell grep -v '^#' $< | xargs -0) && python3 -c "import json; from $(APP_PACKAGE_NAME).main import *; print( json.dumps(app.openapi(), indent=2) )" > $@
# generating openapi specs file under $<
@set -o allexport; \
source .env; \
set +o allexport; \
simcore-service-dynamic-sidecar openapi > $@

# validates OAS file: $@
@cd $(CURDIR); \
$(SCRIPTS_DIR)/openapi-generator-cli.bash validate --input-spec /local/$@
Expand Down
4 changes: 2 additions & 2 deletions services/dynamic-sidecar/docker/boot.sh
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,15 @@ if [ "${SC_BOOT_MODE}" = "debug-ptvsd" ]; then

exec sh -c "
cd services/dynamic-sidecar/src/simcore_service_dynamic_sidecar && \
uvicorn main:app \
uvicorn main:the_app \
--host 0.0.0.0 \
--reload \
$reload_dir_packages
--reload-dir . \
--log-level \"${SERVER_LOG_LEVEL}\"
"
else
exec uvicorn simcore_service_dynamic_sidecar.main:app \
exec uvicorn simcore_service_dynamic_sidecar.main:the_app \
--host 0.0.0.0 \
--log-level "${SERVER_LOG_LEVEL}"

Expand Down
4 changes: 4 additions & 0 deletions services/dynamic-sidecar/scripts/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ push-outputs: ## push the outputs for this service
@echo ">>>>> Expect a 204 reply if OK <<<<<"
curl -v -X POST ${BASE_ADDRESS}/containers/ports/outputs:push

.PHONY: info
info: ## displays app info
# app settings
@simcore-service-dynamic-sidecar settings --as-json

.PHONY: help
help: ## this help
Expand Down
5 changes: 5 additions & 0 deletions services/dynamic-sidecar/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ def read_reqs(reqs_path: Path) -> set[str]:
PROD_REQUIREMENTS=PROD_REQUIREMENTS,
TEST_REQUIREMENTS=TEST_REQUIREMENTS,
setup_requires=["setuptools_scm"],
entry_points={
"console_scripts": [
"simcore-service-dynamic-sidecar=simcore_service_dynamic_sidecar.cli:main",
],
},
)


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import json
import logging

import typer
from settings_library.utils_cli import create_settings_command
from simcore_service_dynamic_sidecar.core.application import create_basic_app

from ._meta import PROJECT_NAME
from .core.settings import DynamicSidecarSettings

log = logging.getLogger(__name__)
main = typer.Typer(name=PROJECT_NAME)


main.command()(create_settings_command(settings_cls=DynamicSidecarSettings, logger=log))


@main.command()
def openapi():
"""Prints OpenAPI specifications in json format"""
app = create_basic_app()
typer.secho(json.dumps(app.openapi(), indent=2))


#
# NOTE: We intentionally did NOT create a command to run the application
# Use instead $ uvicorn simcore_service_dynamic_sidecar.main:the_app
#
Original file line number Diff line number Diff line change
Expand Up @@ -45,65 +45,72 @@ def setup_logger(settings: DynamicSidecarSettings):
logging.root.setLevel(settings.log_level)


def assemble_application() -> FastAPI:
"""
Creates the application from using the env vars as a context
Also stores inside the state all instances of classes
needed in other requests and used to share data.
"""
def create_basic_app() -> FastAPI:
pcrespov marked this conversation as resolved.
Show resolved Hide resolved
# settings
settings = DynamicSidecarSettings.create_from_envs()
setup_logger(settings)
logger.debug(settings.json(indent=2))

application = FastAPI(
# minimal
app = FastAPI(
debug=settings.DEBUG,
openapi_url=f"/api/{API_VTAG}/openapi.json",
docs_url="/dev/doc",
)
override_fastapi_openapi_method(application)
override_fastapi_openapi_method(app)
app.state.settings = settings

application.state.settings = settings
application.state.shared_store = SharedStore()
application.state.application_health = ApplicationHealth()
app.include_router(main_router)
return app

# ROUTES --------------------
application.include_router(main_router)

# ERROR HANDLERS ------------
application.add_exception_handler(NodeNotFound, node_not_found_error_handler)
application.add_exception_handler(BaseDynamicSidecarError, http_error_handler)
def create_app():
"""
Creates the application from using the env vars as a context
Also stores inside the state all instances of classes
needed in other requests and used to share data.
"""

app = create_basic_app()

# MODULES SETUP --------------

if settings.is_development_mode:
remote_debug_setup(application)
app.state.shared_store = SharedStore()
app.state.application_health = ApplicationHealth()

if settings.RABBIT_SETTINGS:
setup_rabbitmq(application)
setup_background_log_fetcher(application)
if app.state.settings.is_development_mode:
remote_debug_setup(app)

if app.state.settings.RABBIT_SETTINGS:
setup_rabbitmq(app)
setup_background_log_fetcher(app)

# also sets up mounted_volumes
setup_mounted_fs(application)
setup_directory_watcher(application)
setup_mounted_fs(app)
setup_directory_watcher(app)

# ERROR HANDLERS ------------
app.add_exception_handler(NodeNotFound, node_not_found_error_handler)
app.add_exception_handler(BaseDynamicSidecarError, http_error_handler)

# EVENTS ---------------------
async def _on_startup() -> None:
await login_registry(settings.REGISTRY_SETTINGS)
await volumes_fix_permissions(application.state.mounted_volumes)
await login_registry(app.state.settings.REGISTRY_SETTINGS)
await volumes_fix_permissions(app.state.mounted_volumes)
print(WELCOME_MSG, flush=True)

async def _on_shutdown() -> None:
logger.info("Going to remove spawned containers")
result = await remove_the_compose_spec(
shared_store=application.state.shared_store,
settings=settings,
command_timeout=settings.DYNAMIC_SIDECAR_DOCKER_COMPOSE_DOWN_TIMEOUT,
shared_store=app.state.shared_store,
settings=app.state.settings,
command_timeout=app.state.settings.DYNAMIC_SIDECAR_DOCKER_COMPOSE_DOWN_TIMEOUT,
)
logger.info("Container removal did_succeed=%s\n%s", result[0], result[1])

logger.info("shutdown cleanup completed")

application.add_event_handler("startup", _on_startup)
application.add_event_handler("shutdown", _on_shutdown)
app.add_event_handler("startup", _on_startup)
app.add_event_handler("shutdown", _on_shutdown)

return application
return app
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"""

from fastapi import FastAPI
from simcore_service_dynamic_sidecar.core.application import assemble_application
from simcore_service_dynamic_sidecar.core.application import create_app

# SINGLETON FastAPI app
app: FastAPI = assemble_application()
the_app: FastAPI = create_app()
4 changes: 2 additions & 2 deletions services/dynamic-sidecar/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from fastapi import FastAPI
from pytest_mock.plugin import MockerFixture
from simcore_service_dynamic_sidecar.core import utils
from simcore_service_dynamic_sidecar.core.application import assemble_application
from simcore_service_dynamic_sidecar.core.application import create_app
from simcore_service_dynamic_sidecar.core.docker_utils import docker_client
from simcore_service_dynamic_sidecar.core.settings import DynamicSidecarSettings
from simcore_service_dynamic_sidecar.core.shared_handlers import (
Expand Down Expand Up @@ -132,7 +132,7 @@ async def _mock_is_registry_reachable(*args, **kwargs) -> None:

@pytest.fixture(scope="module")
def app(mock_environment: None, disable_registry_check: None) -> FastAPI:
app = assemble_application()
app = create_app()
app.state.rabbitmq = AsyncMock()
return app

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from _pytest.monkeypatch import MonkeyPatch
from async_asgi_testclient import TestClient
from fastapi import FastAPI
from simcore_service_dynamic_sidecar.core.application import assemble_application
from simcore_service_dynamic_sidecar.core.application import create_app
from simcore_service_dynamic_sidecar.core.docker_logs import (
_get_background_log_fetcher,
start_log_fetching,
Expand Down Expand Up @@ -62,7 +62,7 @@ def app(
monkeypatch_module.setenv("S3_SECURE", "false")
monkeypatch_module.setenv("R_CLONE_PROVIDER", "MINIO")

yield assemble_application()
yield create_app()


@pytest.fixture
Expand Down
4 changes: 2 additions & 2 deletions services/dynamic-sidecar/tests/unit/test_core_rabbitmq.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from models_library.users import UserID
from pytest_mock.plugin import MockerFixture
from settings_library.rabbit import RabbitSettings
from simcore_service_dynamic_sidecar.core.application import assemble_application
from simcore_service_dynamic_sidecar.core.application import create_app
from simcore_service_dynamic_sidecar.core.rabbitmq import SLEEP_BETWEEN_SENDS, RabbitMQ
from simcore_service_dynamic_sidecar.modules import mounted_fs

Expand Down Expand Up @@ -114,7 +114,7 @@ def mock_environment(

@pytest.fixture
def app(mock_environment: None) -> FastAPI:
return assemble_application()
return create_app()


# UTILS
Expand Down