feat: Add docker support

This commit is contained in:
vimukthiRajapaksha
2025-06-26 23:39:16 +05:30
parent e8eb11624e
commit bb2a7ab571
5 changed files with 79 additions and 13 deletions

40
.choreo/component.yaml Normal file
View File

@@ -0,0 +1,40 @@
# Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com/) All Rights Reserved.
#
# WSO2 LLC. licenses this file to you under the Apache License,
# Version 2.0 (the "License"); you may not use this file except
# in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
# +required The configuration file schema version
schemaVersion: 1.2
# +optional Incoming connection details for the component
endpoints:
# +required Unique name for the endpoint.
# This name will be used when generating the managed API
- name: fhir_mcp_server
# +optional Display name for the endpoint.
displayName: FHIR MCP Server
# +required Service section has the user service endpoint details
service:
# +optional Base path of the API that gets exposed via the endpoint.
# This is mandatory if the endpoint type is set to REST or GraphQL.
basePath: /
# +required Numeric port value that gets exposed via the endpoint
port: 8000
# +required Type of traffic that the endpoint is accepting.
# Allowed values: REST, GraphQL, GRPC, TCP, UDP.
type: REST
# +optional Network level visibilities of the endpoint.
# Accepted values: Project|Organization|Public(Default).
networkVisibilities:
- Public

View File

@@ -1,14 +1,14 @@
FROM python:3.11-slim
# Install uv (for fast dependency management)
RUN pip install --upgrade pip && pip install uv
RUN pip install --upgrade pip
# Set workdir
WORKDIR /app
# Copy only requirements first for better caching
COPY requirements.txt ./
RUN uv pip sync --system requirements.txt
RUN pip install -r requirements.txt
# Copy the rest of the code
COPY . .
@@ -22,6 +22,7 @@ EXPOSE 8000
# Set environment variables (can be overridden at runtime)
ENV PYTHONUNBUFFERED=1
ENV PYTHONPATH=/app/src
# Default command to run the server (can be overridden)
CMD ["uv", "run", "fhir-mcp-server", "--disable-mcp-auth"]
CMD ["python", "-m", "fhir_mcp_server", "--disable-mcp-auth"]

View File

@@ -10,9 +10,9 @@ classifiers = [
"Operating System :: OS Independent",
]
dependencies = [
"mcp[cli]>=1.9.1",
"aiohttp>=3.12.13",
"fhirpy>=2.0.15",
"mcp[cli]==1.9.1",
"aiohttp==3.12.13",
"fhirpy==2.0.15",
]
description = "A Model Context Protocol (MCP) server that provides seamless, standardized access to Fast Healthcare Interoperability Resources (FHIR) data from any compatible FHIR server. Designed for easy integration with AI tools, developer workflows, and healthcare applications, it enables natural language and programmatic search, retrieval, and analysis of clinical data."
keywords = [
@@ -28,7 +28,7 @@ license-files = ["LICEN[CS]E*"]
name = "fhir-mcp-server"
readme = {file = "README.md", content-type = "text/markdown"}
requires-python = ">=3.12"
version = "0.1.10"
version = "0.1.11"
[build-system]
build-backend = "hatchling.build"

View File

@@ -140,11 +140,11 @@ class FHIRClientProvider(httpx.Auth):
return
# Try refreshing existing token
if await self._refresh_access_token(token_id):
return
# if await self._refresh_access_token(token_id):
# return
# Fall back to full OAuth flow
await self._perform_oauth_flow(token_id)
# Fall back to full OAuth token flow
await self._perform_token_flow(token_id)
async def _perform_oauth_flow(self, token_id: str) -> None:
"""Execute OAuth2 authorization code flow with PKCE."""
@@ -188,6 +188,30 @@ class FHIRClientProvider(httpx.Auth):
# Redirect user for authorization
await self.redirect_handler(auth_url)
async def _perform_token_flow(self, token_id: str) -> None:
"""Execute OAuth2 client credentials flow."""
logger.debug("Starting client credentials flow.")
access_token_payload: dict = {
"grant_type": "client_credentials",
"scope": self.configs.scope,
"client_id": self.configs.client_id,
"client_secret": self.configs.client_secret,
"resource": "https://ohfhirrepositorypoc-ohfhirrepositorypoc.fhir.azurehealthcareapis.com",
}
try:
token: OAuthToken = await perform_token_flow(
url=self._get_token_endpoint(),
data=access_token_payload,
timeout=self.configs.timeout,
)
self.token_mapping[token_id] = token
except Exception as ex:
logger.exception("Access token request failed. Caused by, ", exc_info=ex)
raise ValueError("Access token request failed")
async def handle_fhir_oauth_callback(self, code: str, state: str) -> None:
state_mapping: Dict[str, str] | None = self.state_mapping.get(state)
@@ -235,7 +259,8 @@ class FHIRClientProvider(httpx.Auth):
def _get_token_endpoint(self) -> str:
"""Get token endpoint."""
return get_endpoint(self._metadata, "token_endpoint")
return "https://login.microsoftonline.com/da76d684-740f-4d94-8717-9d5fb21dd1f9/oauth2/token"
# return get_endpoint(self._metadata, "token_endpoint")
async def _refresh_access_token(self, token_id: str) -> None:
"""Refresh access token using refresh token."""

View File

@@ -501,7 +501,7 @@ def register_mcp_tools(mcp: FastMCP) -> None:
bundle: dict = await client.resource(resource_type=type, id=id).execute(
operation=operation or "",
method="PUT",
data={id: id, **payload},
data={**payload, "id": id},
params=searchParam,
)
return await get_bundle_entries(bundle=bundle)