diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 69552ec..d62254c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,13 +24,15 @@ jobs: - name: Install Dependencies run: | python -m pip install --upgrade pip - pip install yapf pylint pydicom + pip install yapf pylint pydicom ariadne - name: Check format with yapf (Google Style) run: yapf --diff --style google --recursive orthanc/python/ - name: Run pylint - run: pylint orthanc/python/ + run: | + pylint orthanc/python/ \ + --msg-template="::error file={path},line={line},col={column},title=Pylint ({msg_id})::{category}: {msg}" build: name: Build Docker Image @@ -41,3 +43,23 @@ jobs: - name: Build with docker compose run: docker compose build + + - name: Start docker compose + run: docker compose up -d + + - name: Wait for Orthanc to be ready + run: | + echo "Waiting for Orthanc to start..." + timeout 30 bash -c 'while ! curl -s -f -u demo:demo http://localhost:8000/system; do sleep 2; done' + echo "Orthanc is ready!" + + - name: Test GraphQL Endpoint + run: | + response=$(curl -s -X POST -u demo:demo -H "Content-Type: application/json" -d '{"query": "{ hello }"}' http://localhost:8000/graphql) + echo "Response: $response" + # Check if the output contains the expected "Hello from Orthanc GraphQL!" string + if [[ "$response" != *"Hello from Orthanc GraphQL!"* ]]; then + echo "GraphQL test failed. Unexpected response." + exit 1 + fi + echo "GraphQL test passed!" diff --git a/docker-compose.yml b/docker-compose.yml index 32f1458..bfd0807 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -8,7 +8,7 @@ services: VERBOSE_ENABLED: "true" VERBOSE_STARTUP: "true" - ORTHANC__PYTHON_SCRIPT: "/python/graphql.py" + ORTHANC__PYTHON_SCRIPT: "/python/orthanc-graphql.py" ORTHANC__PYTHON_VERBOSE: "true" ORTHANC__REGISTERED_USERS: | diff --git a/orthanc/Dockerfile b/orthanc/Dockerfile index f210e67..a4987a0 100644 --- a/orthanc/Dockerfile +++ b/orthanc/Dockerfile @@ -6,8 +6,8 @@ FROM orthancteam/orthanc RUN apt-get update && apt install -y python3-venv RUN python3 -m venv /.venv -RUN /.venv/bin/pip install pydicom -ENV PYTHONPATH=/.venv/lib64/python3.12/site-packages/ +RUN /.venv/bin/pip install pydicom ariadne +ENV PYTHONPATH=/.venv/lib/python3.14/site-packages/ RUN mkdir /python COPY * /python/ \ No newline at end of file diff --git a/orthanc/python/graphql.py b/orthanc/python/graphql.py deleted file mode 100644 index e69de29..0000000 diff --git a/orthanc/python/orthanc-graphql.py b/orthanc/python/orthanc-graphql.py new file mode 100644 index 0000000..dc6542a --- /dev/null +++ b/orthanc/python/orthanc-graphql.py @@ -0,0 +1,55 @@ +# pylint: disable=invalid-name,import-error +""" +Orthanc GraphQL endpoint implementation using Ariadne. +""" +import json + +from ariadne import QueryType, graphql_sync, make_executable_schema + +import orthanc + +# 1. Define a simple GraphQL schema +TYPE_DEFS = """ + type Query { + hello: String! + } +""" + +query = QueryType() + + +@query.field("hello") +def resolve_hello(_, _info): + """Resolver for the 'hello' query.""" + return "Hello from Orthanc GraphQL!" + + +schema = make_executable_schema(TYPE_DEFS, query) + + +def graphql_endpoint(output, _url, **request): + """REST callback injected into Orthanc for GraphQL endpoints.""" + if request['method'] != 'POST': + output.SendMethodNotAllowed('POST') + return + + try: + # Parse the JSON body from the request + data = json.loads(request['body']) + + # 2. Execute GraphQL query + _, response = graphql_sync(schema, + data, + context_value=request, + debug=True) + + # 3. Use AnswerBuffer to return HTTP 200 JSON response + output.AnswerBuffer(json.dumps(response), 'application/json') + + except Exception as e: # pylint: disable=broad-exception-caught + # Fallback for parsing errors or other exceptions + error_response = {"errors": [{"message": str(e)}]} + output.AnswerBuffer(json.dumps(error_response), 'application/json') + + +orthanc.RegisterRestCallback('/graphql', graphql_endpoint)