Skip to content
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
19 changes: 18 additions & 1 deletion .github/workflows/ci_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -140,11 +140,28 @@ jobs:

- name: Start the Docker services
run: |
docker-compose -f docker-compose_dev.yml --verbose -- up &
docker-compose -f docker-compose_dev.yml --verbose -- up &
.github/utils/wait_for_it.sh localhost:${{ env.PORT }} -t 120
sleep 5
curl -X "GET" -i "http://localhost:${{ env.PORT }}${{ env.OTEAPI_prefix }}/session"
env:
PORT: 8123
OTEAPI_prefix: /api/ci/v1
DOCKER_OTEAPI_TARGET: ${{ matrix.docker-target }}

- name: Start the Docker services with local `oteapi-core`
if: matrix.docker-target == 'development'
run: |
git clone https://github.com/EMMC-ASBL/oteapi-core ${PATH_TO_OTEAPI_CORE}
docker-compose -f docker-compose_dev.yml down
docker-compose -f docker-compose_dev.yml --verbose -- up &
.github/utils/wait_for_it.sh localhost:${{ env.PORT }} -t 120
# Sleep for longer, since it takes a while to install `oteapi-core`
# And the port will be available as soon as the CMD is reached in the Dockerfile.
sleep 40
curl -X "GET" -i "http://localhost:${{ env.PORT }}${{ env.OTEAPI_prefix }}/session"
env:
PORT: 8123
OTEAPI_prefix: /api/ci/v1
DOCKER_OTEAPI_TARGET: ${{ matrix.docker-target }}
PATH_TO_OTEAPI_CORE: /tmp/oteapi-core
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ RUN pip install --trusted-host pypi.org --trusted-host files.pythonhosted.org -r

# Run app with reload option
EXPOSE 8080
CMD hypercorn asgi:app --bind 0.0.0.0:8080 --reload --debug --log-level debug
CMD if [ "${PATH_TO_OTEAPI_CORE}" != "/dev/null" ] && [ -n "${PATH_TO_OTEAPI_CORE}" ]; then pip install -U --force-reinstall -e /oteapi_core; fi && hypercorn asgi:app --bind 0.0.0.0:8080 --reload --debug --log-level debug

################# PRODUCTION ####################################
################# PRODUCTION #####################################
FROM base as production

# Run app
Expand Down
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,22 @@ docker run \

Open the following URL in a browser [http://localhost:8080/redoc](http://localhost:8080/redoc).

One can also use a local `oteapi-core` repository by specifying the `PATH_TO_OTEAPI_CORE` environment variable:

```shell
export PATH_TO_OTEAPI_CORE=/local/path/to/oteapi-core
docker run \
--rm \
--network otenet \
--detach \
--volume ${PWD}:/app \
--publish 8080:8080 \
--env OTEAPI_REDIS_TYPE=redis \
--env OTEAPI_REDIS_HOST=redis \
--env OTEAPI_REDIS_PORT=6379 \
ontotrans/oteapi-development:latest
```

### Run oteapi (production)

Run the services by attaching to the otenet network and set the environmental variables for connecting to Redis.
Expand Down Expand Up @@ -112,6 +128,12 @@ Note that default values will be used if certain environment variables are not p
To inspect which environment variables can be specified, please inspect the [Docker Compose file](docker-compose_dev.yml).

This Docker Compose file will use your local files for the application, meaning updates in your local files (under `app/`) should be reflected in the running application after hypercorn reloads.
You can go one step further and use your local files also for the `oteapi-core` repository by specifying the `PATH_TO_OTEAPI_CORE` environment variable:

```shell
export PATH_TO_OTEAPI_CORE=/local/path/to/oteapi-core
docker-compose -f docker-compose_dev.yml up --build -d # Run the OTE Services detached, build if necessary
```

To see the logs (in real time) from the server, run:

Expand Down
10 changes: 2 additions & 8 deletions app/routers/datafilter.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,7 @@ async def get_filter(
if session_id and not await cache.exists(session_id):
raise httpexception_404_item_id_does_not_exist(session_id, "session_id")

# Using `.construct` here to avoid validation of already validated data.
# This is a slight speed up.
# https://pydantic-docs.helpmanual.io/usage/models/#creating-models-without-validation
config = FilterConfig.construct(**json.loads(await cache.get(filter_id)))
config = FilterConfig(**json.loads(await cache.get(filter_id)))

strategy = create_strategy("filter", config)
session_data = None if not session_id else json.loads(await cache.get(session_id))
Expand Down Expand Up @@ -103,10 +100,7 @@ async def initialize_filter(
if session_id and not await cache.exists(session_id):
raise httpexception_404_item_id_does_not_exist(session_id, "session_id")

# Using `.construct` here to avoid validation of already validated data.
# This is a slight speed up.
# https://pydantic-docs.helpmanual.io/usage/models/#creating-models-without-validation
config = FilterConfig.construct(**json.loads(await cache.get(filter_id)))
config = FilterConfig(**json.loads(await cache.get(filter_id)))

strategy = create_strategy("filter", config)
session_data = None if not session_id else json.loads(await cache.get(session_id))
Expand Down
15 changes: 3 additions & 12 deletions app/routers/dataresource.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,7 @@ async def info_dataresource(
if not await cache.exists(resource_id):
raise httpexception_404_item_id_does_not_exist(resource_id, "resource_id")

# Using `.construct` here to avoid validation of already validated data.
# This is a slight speed up.
# https://pydantic-docs.helpmanual.io/usage/models/#creating-models-without-validation
return ResourceConfig.construct(**json.loads(await cache.get(resource_id)))
return ResourceConfig(**json.loads(await cache.get(resource_id)))


@ROUTER.get(
Expand All @@ -114,10 +111,7 @@ async def read_dataresource(
if session_id and not await cache.exists(session_id):
raise httpexception_404_item_id_does_not_exist(session_id, "session_id")

# Using `.construct` here to avoid validation of already validated data.
# This is a slight speed up.
# https://pydantic-docs.helpmanual.io/usage/models/#creating-models-without-validation
config = ResourceConfig.construct(**json.loads(await cache.get(resource_id)))
config = ResourceConfig(**json.loads(await cache.get(resource_id)))

session_data: "Optional[Dict[str, Any]]" = (
None if not session_id else json.loads(await cache.get(session_id))
Expand Down Expand Up @@ -165,10 +159,7 @@ async def initialize_dataresource(
if session_id and not await cache.exists(session_id):
raise httpexception_404_item_id_does_not_exist(session_id, "session_id")

# Using `.construct` here to avoid validation of already validated data.
# This is a slight speed up.
# https://pydantic-docs.helpmanual.io/usage/models/#creating-models-without-validation
config = ResourceConfig.construct(**json.loads(await cache.get(resource_id)))
config = ResourceConfig(**json.loads(await cache.get(resource_id)))

session_data: "Optional[Dict[str, Any]]" = (
None if not session_id else json.loads(await cache.get(session_id))
Expand Down
10 changes: 2 additions & 8 deletions app/routers/mapping.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,7 @@ async def get_mapping(
if session_id and not await cache.exists(session_id):
raise httpexception_404_item_id_does_not_exist(session_id, "session_id")

# Using `.construct` here to avoid validation of already validated data.
# This is a slight speed up.
# https://pydantic-docs.helpmanual.io/usage/models/#creating-models-without-validation
config = MappingConfig.construct(**json.loads(await cache.get(mapping_id)))
config = MappingConfig(**json.loads(await cache.get(mapping_id)))

mapping_strategy = create_strategy("mapping", config)
session_data: "Optional[Dict[str, Any]]" = (
Expand Down Expand Up @@ -109,10 +106,7 @@ async def initialize_mapping(
if session_id and not await cache.exists(session_id):
raise httpexception_404_item_id_does_not_exist(session_id, "session_id")

# Using `.construct` here to avoid validation of already validated data.
# This is a slight speed up.
# https://pydantic-docs.helpmanual.io/usage/models/#creating-models-without-validation
config = MappingConfig.construct(**json.loads(await cache.get(mapping_id)))
config = MappingConfig(**json.loads(await cache.get(mapping_id)))

mapping_strategy = create_strategy("mapping", config)
session_data: "Optional[Dict[str, Any]]" = (
Expand Down
10 changes: 2 additions & 8 deletions app/routers/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,10 +159,7 @@ async def update_session(
if not await cache.exists(session_id):
raise httpexception_404_item_id_does_not_exist(session_id, "session_id")

# Using `.construct` here to avoid validation of already validated data.
# This is a slight speed up.
# https://pydantic-docs.helpmanual.io/usage/models/#creating-models-without-validation
session = Session.construct(**json.loads(await cache.get(session_id)))
session = Session(**json.loads(await cache.get(session_id)))
session.update(updated_session)
await cache.set(session_id, session.json().encode("utf-8"))
return session
Expand All @@ -183,10 +180,7 @@ async def get_session(
if not await cache.exists(session_id):
raise httpexception_404_item_id_does_not_exist(session_id, "session_id")

# Using `.construct` here to avoid validation of already validated data.
# This is a slight speed up.
# https://pydantic-docs.helpmanual.io/usage/models/#creating-models-without-validation
return Session.construct(**json.loads(await cache.get(session_id)))
return Session(**json.loads(await cache.get(session_id)))


@ROUTER.delete(
Expand Down
28 changes: 4 additions & 24 deletions app/routers/transformation.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,7 @@ async def get_transformation_status(
transformation_id, "transformation_id"
)

# Using `.construct` here to avoid validation of already validated data.
# This is a slight speed up.
# https://pydantic-docs.helpmanual.io/usage/models/#creating-models-without-validation
config = TransformationConfig.construct(
**json.loads(await cache.get(transformation_id))
)
config = TransformationConfig(**json.loads(await cache.get(transformation_id)))

strategy: "ITransformationStrategy" = create_strategy("transformation", config)
return strategy.status(task_id=task_id)
Expand All @@ -105,12 +100,7 @@ async def get_transformation(
if session_id and not await cache.exists(session_id):
raise httpexception_404_item_id_does_not_exist(session_id, "session_id")

# Using `.construct` here to avoid validation of already validated data.
# This is a slight speed up.
# https://pydantic-docs.helpmanual.io/usage/models/#creating-models-without-validation
config = TransformationConfig.construct(
**json.loads(await cache.get(transformation_id))
)
config = TransformationConfig(**json.loads(await cache.get(transformation_id)))

strategy: "ITransformationStrategy" = create_strategy("transformation", config)
session_data: "Optional[Dict[str, Any]]" = (
Expand Down Expand Up @@ -147,12 +137,7 @@ async def execute_transformation(
if session_id and not await cache.exists(session_id):
raise httpexception_404_item_id_does_not_exist(session_id, "session_id")

# Using `.construct` here to avoid validation of already validated data.
# This is a slight speed up.
# https://pydantic-docs.helpmanual.io/usage/models/#creating-models-without-validation
config = TransformationConfig.construct(
**json.loads(await cache.get(transformation_id))
)
config = TransformationConfig(**json.loads(await cache.get(transformation_id)))

strategy: "ITransformationStrategy" = create_strategy("transformation", config)
session_data: "Optional[Dict[str, Any]]" = (
Expand Down Expand Up @@ -189,12 +174,7 @@ async def initialize_transformation(
if session_id and not await cache.exists(session_id):
raise httpexception_404_item_id_does_not_exist(session_id, "session_id")

# Using `.construct` here to avoid validation of already validated data.
# This is a slight speed up.
# https://pydantic-docs.helpmanual.io/usage/models/#creating-models-without-validation
config = TransformationConfig.construct(
**json.loads(await cache.get(transformation_id))
)
config = TransformationConfig(**json.loads(await cache.get(transformation_id)))

strategy: "ITransformationStrategy" = create_strategy("transformation", config)
session_data: "Optional[Dict[str, Any]]" = (
Expand Down
4 changes: 3 additions & 1 deletion docker-compose_dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@ services:
OTEAPI_REDIS_HOST: redis
OTEAPI_REDIS_PORT: 6379
OTEAPI_prefix: "${OTEAPI_prefix:-/api/v1}"
PATH_TO_OTEAPI_CORE: "${PATH_TO_OTEAPI_CORE:-/dev/null}"
depends_on:
- redis
networks:
- otenet
volumes:
- ${PWD}:/app
- "${PWD}:/app"
- "${PATH_TO_OTEAPI_CORE:-/dev/null}:/oteapi_core"

redis:
image: redis:latest
Expand Down