Skip to content

Commit

Permalink
✨ defines openapi specs for new studies resources (#4250)
Browse files Browse the repository at this point in the history
  • Loading branch information
pcrespov authored May 30, 2023
1 parent b004ab1 commit 51e48c3
Show file tree
Hide file tree
Showing 17 changed files with 2,981 additions and 94 deletions.
63 changes: 32 additions & 31 deletions packages/service-library/src/servicelib/fastapi/openapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,24 +73,18 @@ def redefine_operation_id_in_router(router: APIRouter, operation_id_prefix: str)
)


def patch_openapi_specs(app_openapi: dict[str, Any]):
"""Patches app.openapi with some fixes and osparc conventions
Modifies fastapi auto-generated OAS to pass our openapi validation.
"""

def _remove_named_groups(regex: str) -> str:
# Fixes structure error produce by named groups like
# ^simcore/services/comp/(?P<subdir>[a-z0-9][a-z0-9_.-]*/)*(?P<name>[a-z0-9-_]+[a-z0-9])$
# into
# ^simcore/services/comp/([a-z0-9][a-z0-9_.-]*/)*([a-z0-9-_]+[a-z0-9])$
return re.sub(r"\(\?P<[^>]+>", "(", regex)

def _patch_node(key, node):
# SEE fastapi ISSUE: https://github.com/tiangolo/fastapi/issues/240 (test_openap.py::test_exclusive_min_openapi_issue )
# SEE openapi-standard: https://swagger.io/docs/specification/data-models/data-types/#range
node_type = node.get("type")

def _remove_named_groups(regex: str) -> str:
# Fixes structure error produced by named groups like
# ^simcore/services/comp/(?P<subdir>[a-z0-9][a-z0-9_.-]*/)*(?P<name>[a-z0-9-_]+[a-z0-9])$
# into
# ^simcore/services/comp/([a-z0-9][a-z0-9_.-]*/)*([a-z0-9-_]+[a-z0-9])$
return re.sub(r"\(\?P<[^>]+>", "(", regex)


def _patch_node_properties(key: str, node: dict):
# SEE fastapi ISSUE: https://github.com/tiangolo/fastapi/issues/240 (test_openap.py::test_exclusive_min_openapi_issue )
# SEE openapi-standard: https://swagger.io/docs/specification/data-models/data-types/#range
if node_type := node.get("type"):
if key == "exclusiveMinimum":
cast_to_python = _SCHEMA_TO_PYTHON_TYPES[node_type]
node["minimum"] = cast_to_python(node[key])
Expand All @@ -111,22 +105,29 @@ def _patch_node(key, node):
elif key == "pattern" and node_type == "string":
node[key] = _remove_named_groups(regex=node[key])

def _patch(node):
if isinstance(node, dict):
for key in list(node.keys()):
if key in _SKIP:
node.pop(key)
continue
_patch_node(key, node)

# recursive
_patch(node[key])
def _patch(node: Any):
if isinstance(node, dict):
for key in list(node.keys()):
if key in _SKIP:
node.pop(key)
continue
_patch_node_properties(key, node)

elif isinstance(node, list):
for value in node:
# recursive
_patch(value)
# recursive
_patch(node[key])

elif isinstance(node, list):
for value in node:
# recursive
_patch(value)


def patch_openapi_specs(app_openapi: dict[str, Any]):
"""Patches app.openapi with some fixes and osparc conventions
Modifies fastapi auto-generated OAS to pass our openapi validation.
"""
_patch(app_openapi)


Expand Down
1 change: 1 addition & 0 deletions services/api-server/.env-devel
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#

API_SERVER_DEV_FEATURES_ENABLED=1
LOG_FORMAT_LOCAL_DEV_ENABLED=1
DEBUG=0

# SEE services/api-server/src/simcore_service_api_server/auth_security.py
Expand Down
3 changes: 3 additions & 0 deletions services/api-server/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
# outputs from makefile
client

# openapi for development mode
# openapi-dev.json TODO: activate before merging in master
17 changes: 13 additions & 4 deletions services/api-server/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -84,20 +84,29 @@ run-fake-devel: # starts a fake server in a dev-container

# BUILD ###########################################################################

.PHONY: openapi-specs openapi.json
openapi-specs: openapi.json
openapi.json: .env
define create_and_validate_openapi
# generating openapi specs file under $< (NOTE: Skips DEV FEATURES since this OAS is the 'offically released'!)
@set -o allexport; \
source .env; \
set +o allexport; \
export API_SERVER_DEV_FEATURES_ENABLED=0; \
export API_SERVER_DEV_FEATURES_ENABLED=$1; \
python3 -c "import json; from $(APP_PACKAGE_NAME).main import *; print( json.dumps(the_app.openapi(), indent=2) )" > $@

# validates OAS file: $@
@cd $(CURDIR); \
$(SCRIPTS_DIR)/openapi-generator-cli.bash validate --input-spec /local/$@
endef


.PHONY: openapi-specs openapi.json openapi-dev.json

openapi-specs: openapi.json

openapi.json: .env
@$(call create_and_validate_openapi,0)

openapi-dev.json: .env
@$(call create_and_validate_openapi,1)


# GENERATION python client ###########################################################################
Expand Down
Empty file removed services/api-server/None
Empty file.
Loading

0 comments on commit 51e48c3

Please sign in to comment.