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

Major/410 session update #395

Merged
merged 44 commits into from
Mar 1, 2024
Merged
Show file tree
Hide file tree
Changes from 43 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
1d35875
WIP
Feb 1, 2024
93bdde6
Add test_parser and update session delete
Treesarj Feb 2, 2024
2f9b8c5
Updated the dataresource. Removed instantiation of the download and p…
Feb 7, 2024
608b2d5
fix parser API to fetch from session
Treesarj Feb 8, 2024
c8ebc22
add checks and fix initialize in dataresource strategy
Treesarj Feb 8, 2024
203eccc
modify parser API's
Treesarj Feb 8, 2024
d50f461
Add initialize endpoint for parser
Treesarj Feb 12, 2024
f691179
rename endpoint
Treesarj Feb 19, 2024
65b03cf
fix pre-commit errors
Treesarj Feb 19, 2024
74a737d
Merge branch 'master' into major/410-session-update
Treesarj Feb 20, 2024
55cd80e
fix pre-commit
Treesarj Feb 20, 2024
89863f2
Merge branch 'master' into major/410-session-update
CasperWA Feb 21, 2024
454e17b
updated tests and new test for dataresource
Treesarj Feb 22, 2024
8ecc76a
Update app/models/session.py
Treesarj Feb 22, 2024
cedc8ef
Update app/routers/session.py
Treesarj Feb 22, 2024
9d52802
resolve comments
Treesarj Feb 22, 2024
344645f
Merge branch 'major/410-session-update' of github.com:EMMC-ASBL/oteap…
Treesarj Feb 22, 2024
1a45ab7
fix test configuration
Treesarj Feb 23, 2024
d6d6a88
fix tests
Treesarj Feb 23, 2024
ba5c771
requested changes
Treesarj Feb 23, 2024
65f9eff
Update tests/static/test_strategies/resource.py
Treesarj Feb 23, 2024
5541e93
remove test ttl file and debug.py from requirements.txt
Treesarj Feb 26, 2024
aee3cf5
requested changes
Treesarj Feb 26, 2024
e0786d7
move cache key validation
Treesarj Feb 26, 2024
5a7bc1e
requested changes
Treesarj Feb 26, 2024
759aebd
redo fetch cache key
Treesarj Feb 26, 2024
f4aa22a
requested changes
Treesarj Feb 27, 2024
24d0237
fix pylint errors
Treesarj Feb 27, 2024
94cf49c
fix pylint errors
Treesarj Feb 27, 2024
968b0f3
Remove unused imports
CasperWA Feb 27, 2024
2ae97b0
Satisfy pre-commit hooks
CasperWA Feb 27, 2024
bc04d82
Temporarily use the latest developments in oteapi-core
CasperWA Feb 28, 2024
25e8deb
Do not show coverage on failed test runs
CasperWA Feb 28, 2024
d3eb4c8
Add session merging tests to all router tests
CasperWA Feb 28, 2024
7aceaa7
Update dumping dataresouce config in test
CasperWA Feb 28, 2024
a25ae0f
Merge remote-tracking branch 'origin/master' into major/410-session-u…
CasperWA Feb 28, 2024
7181f95
Use v0.7.0.dev0 of oteapi-core
CasperWA Feb 29, 2024
3cef560
Update docker-compose_ci_plugin.yml
CasperWA Feb 29, 2024
bfb6ff0
Try avoiding running debugpy
CasperWA Feb 29, 2024
6b57b1d
Revert changed sleep in CI
CasperWA Feb 29, 2024
306c0ed
Remove logging setup in tests
CasperWA Feb 29, 2024
0e1213a
Update app/routers/session.py
Treesarj Mar 1, 2024
0ad16f0
requested changes
Treesarj Mar 1, 2024
257fe9f
Update README with important notice
CasperWA Mar 1, 2024
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
1 change: 1 addition & 0 deletions .dev/requirements_dev.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
dulwich~=0.21.7
debugpy>=1.8.0
fakeredis~=2.21
httpx~=0.27.0
invoke~=2.2
Expand Down
2 changes: 1 addition & 1 deletion .github/utils/direct_requirements.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
fastapi>=0.110.0
hypercorn>=0.14.4
oteapi-core>=0.6.1
oteapi-core>=0.7.0.dev0
pydantic>=2.6.2
pydantic-settings>=2.2.1
redis>=5.0.1
Expand Down
9 changes: 7 additions & 2 deletions .github/utils/docker-compose_ci_plugins.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version: "3"
version: "3.3"

services:
oteapi:
Expand All @@ -7,13 +7,18 @@ services:
target: "${DOCKER_OTEAPI_TARGET:-development}"
ports:
- "${PORT:-8080}:8080"
- "5678:5678" # Debug port
environment:
OTEAPI_REDIS_TYPE: redis
OTEAPI_REDIS_HOST: redis
OTEAPI_REDIS_PORT: 6379
OTEAPI_prefix: "${OTEAPI_prefix:-/api/v1}"
OTEAPI_PLUGIN_PACKAGES:
OTEAPI_INCLUDE_REDISADMIN: "${OTEAPI_INCLUDE_REDISADMIN:-True}"
OTEAPI_EXPOSE_SECRETS: "${OTEAPI_EXPOSE_SECRETS:-True}"
PATH_TO_OTEAPI_CORE: "${PATH_TO_OTEAPI_CORE:-/dev/null}"
OTEAPI_PLUGIN_PACKAGES:
OTEAPI_AUTHENTICATION_DEPENDENCIES:
CI:
depends_on:
- redis
networks:
Expand Down
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ repos:
- id: pylint-tests
name: pylint - tests
entry: pylint
args: ["--rcfile=pyproject.toml", "--extension-pkg-whitelist='pydantic'", "--disable=C0415,W0621"]
args: ["--rcfile=pyproject.toml", "--extension-pkg-whitelist='pydantic'", "--disable=C0415,W0621,E1101"]
language: python
types: [python]
require_serial: true
Expand Down
20 changes: 20 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Python: Remote Attach",
"type": "debugpy",
"request": "attach",
"connect": {
"host": "localhost",
"port": 5678
},
"pathMappings": [
{
"localRoot": "${workspaceFolder}",
"remoteRoot": "/app"
}
]
}
]
}
11 changes: 3 additions & 8 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,10 @@ COPY .git .git/
COPY .dev/requirements_dev.txt .pre-commit-config.yaml pyproject.toml ./

# Run static security check, linters, and pytest with code coverage
RUN pip install --trusted-host pypi.org --trusted-host files.pythonhosted.org -r requirements_dev.txt \
# Ignore ID 44715 for now.
# See this NumPy issue for more information: https://github.com/numpy/numpy/issues/19038
&& pre-commit run --all-files \
&& safety check -r requirements.txt -r requirements_dev.txt --ignore 44715 \
&& pytest --cov app

RUN pip install --trusted-host pypi.org --trusted-host files.pythonhosted.org -r requirements_dev.txt
Treesarj marked this conversation as resolved.
Show resolved Hide resolved
ENV DEV_ENV=1
# Run app with reload option
EXPOSE 8080
EXPOSE 8080 5678
CMD if [ "${PATH_TO_OTEAPI_CORE}" != "/dev/null" ] && [ -n "${PATH_TO_OTEAPI_CORE}" ]; then \
pip install -U --force-reinstall -e /oteapi_core; fi \
&& ./entrypoint.sh --reload --debug --log-level debug
Expand Down
68 changes: 68 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,74 @@ networks:
otenet:
```

## Debugging OTEAPI Service in Visual Studio

### Prerequisites
* Ensure you have `docker` and `docker-compose` installed on your system.
* Install Visual Studio Code along with the Python extension and the Remote - Containers extension.
* Have the docker-compose_dev.yml file configured for your OTEAPI Service.
* Ensure `debugpy` is installed in your virtual environment

### Configuring Visual Studio Code:

* Open your project in Visual Studio Code.
* Go to the Run and Debug view (Ctrl+Shift+D or ⌘+Shift+D on macOS).
* Create a launch.json file in the .vscode folder at the root of your project (if not already present). This file should contain something like this:

```json
{
"version": "0.2.0",
"configurations": [
{
"name": "Python: Remote Attach",
"type": "python",
"request": "attach",
"connect": {
"host": "localhost",
"port": 5678
},
"pathMappings": [
{
"localRoot": "${workspaceFolder}",
"remoteRoot": "/app"
}
]
}
]
}
```

### Update the entrypoint.sh
In order to enable remote debugging, update the file `entrypoint.sh` such that the oteapi is started using the following command:

```
python -m debugpy --wait-for-client --listen 0.0.0.0:5678 -m hypercorn --bind 0.0.0.0:8080 --reload asgi:app "$@"
```

This will run the OTEAPI service in remote debug mode. The debugpy debugger will wait until a remote debuggin client is attached to port 5678. This happens when activating the "Run and Debug | Python: Remote Attach" from Visual Studio Code. For other IDEs please follow the relevant documentation.



### Starting the docker-compose
* Open a terminal and navigate to the directory containing your docker-compose_dev.yml file.
* Start the service using the command:

```sh
docker-compose -f docker-compose_dev.yml up -d
```

The `-d` option starts the OTEAPI sevice in detached mode. In order to access and follow the logs output you can run `docker-compose logs -f`.

### Attaching to the Remote Process:

* With the `launch.json` configured, go to the Run and Debug view in Visual Studio Code.
* Select the "Python: Remote Attach" configuration from the dropdown menu.* Click the green play button or press F5 to start the debugging session.
* Visual Studio Code will attach to the remote debugging session running inside the Docker container.

### Debugging the Application:

Set breakpoints in your code as needed. Interact with your FastAPI application as you normally would. Visual Studio Code will pause execution when a breakpoint is hit, allowing you to inspect variables, step through code, and debug your application.

## Acknowledgment

OTEAPI Core has been supported by the following projects:
Expand Down
4 changes: 3 additions & 1 deletion app/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
dataresource,
function,
mapping,
parser,
redisadmin,
session,
transformation,
Expand Down Expand Up @@ -82,9 +83,10 @@ def create_app() -> FastAPI:
available_routers = [
session,
dataresource,
parser,
mapping,
datafilter,
function,
mapping,
transformation,
triplestore,
]
Expand Down
2 changes: 1 addition & 1 deletion app/models/error.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def httpexception_422_resource_id_is_unprocessable(resource_id: str) -> HTTPExce
detail=[
{
"loc": ["resource_id"],
"msg": "Missing downloadUrl/mediaType or "
"msg": "Missing resourceType or downloadUrl/mediaType or "
f"accessUrl/accessService identifier in {resource_id=}",
"type": "Error",
}
Expand Down
43 changes: 43 additions & 0 deletions app/models/parser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
"""Parser specific pydantic response models."""

from typing import Annotated
from uuid import uuid4

from pydantic import Field

from app.models.response import CreateResponse, GetResponse, InitializeResponse

IDPREFIX = "parser"


class CreateParserResponse(CreateResponse):
"""Create a response resource

Router: `POST /parser`
"""

parser_id: Annotated[
str,
Field(
default_factory=lambda: f"{IDPREFIX}-{uuid4()}",
description="The parser id.",
pattern=(
rf"^{IDPREFIX}-[0-9a-f]{{8}}-[0-9a-f]{{4}}-[0-9a-f]{{4}}-[0-9a-f]{{4}}-"
r"[0-9a-f]{12}$"
),
),
]


class GetParserResponse(GetResponse):
"""Get a parser resource

Router: `GET /parser/{parser_id}`
"""


class InitializeParserResponse(InitializeResponse):
"""Initialize a parser resource

Router: `POST /parser/{parser_id}/initialize`
"""
8 changes: 7 additions & 1 deletion app/models/session.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""Session-specific pydantic response models."""

from typing import Annotated
from typing import Annotated, Optional
from uuid import uuid4

from pydantic import Field
Expand Down Expand Up @@ -57,6 +57,12 @@ class DeleteAllSessionsResponse(Session):
number_of_deleted_sessions: Annotated[
int, Field(description="The number of deleted sessions in the Redis cache.")
]
message: Annotated[
Optional[str],
Field(
description="Optional message indicating the result of the operation.",
),
] = "All session keys deleted."


class DeleteSessionResponse(Session):
Expand Down
27 changes: 27 additions & 0 deletions app/redis_cache/_cache.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
"""Cache operations."""

from typing import Any

from app.models.error import httpexception_404_item_id_does_not_exist
from app.redis_cache import TRedisPlugin


async def _fetch_cache_value(cache: TRedisPlugin, key: str, key_type: str) -> Any:
"""Fetch key value from Cache and check if its of expected type (str or bytes)."""
await _validate_cache_key(cache, key, key_type)

cache_value = await cache.get(key)
if cache_value is None:
raise ValueError(f"Cache value for key '{key}' is None.")

Check warning on line 15 in app/redis_cache/_cache.py

View check run for this annotation

Codecov / codecov/patch

app/redis_cache/_cache.py#L15

Added line #L15 was not covered by tests
if not isinstance(cache_value, (str, bytes)):
raise TypeError(

Check warning on line 17 in app/redis_cache/_cache.py

View check run for this annotation

Codecov / codecov/patch

app/redis_cache/_cache.py#L17

Added line #L17 was not covered by tests
f"Expected cache value of {key} to be a string or bytes, "
f"found it to be of type: `{type(cache_value)!r}`."
)
return cache_value


async def _validate_cache_key(cache: TRedisPlugin, key: str, key_type: str) -> None:
"""Validate if a key exists in cache and is of expected type (str or bytes)."""
if not await cache.exists(key):
raise httpexception_404_item_id_does_not_exist(key, key_type)

Check warning on line 27 in app/redis_cache/_cache.py

View check run for this annotation

Codecov / codecov/patch

app/redis_cache/_cache.py#L27

Added line #L27 was not covered by tests
Loading