Skip to content

Conversation

@adamkells
Copy link
Contributor

@adamkells adamkells commented Nov 28, 2025

Description

This PR adds functionality for python 3.12

Address #127

This is achieved by removing Spyne as a dependency for SOAP servers.

In particular, we add a FastAPI server and a WSDL file while removing spyne and associated files.

Changes Made

Python 3.12 is added as an acceptable python version. The ci/cd will now additionally run on 3.12 as a test version. The publishing of the package will also be done on 3.12

Testing

Vibe coded tests were run, existing tests were modified to run on new code.

Additionally the Cookbook example for connecting to Medplum was confirmed to run and give the same output before and after.

Checklist

  • I have read the contributing guidelines
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

@adamkells adamkells self-assigned this Nov 28, 2025
@adamkells adamkells marked this pull request as draft December 1, 2025 19:47
@jenniferjiangkells jenniferjiangkells linked an issue Dec 2, 2025 that may be closed by this pull request
@adamkells adamkells marked this pull request as ready for review December 10, 2025 18:12
Copy link
Member

@jenniferjiangkells jenniferjiangkells left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The approach looks sound to me. The most important thing is that it's backward compatible with the cookbook examples and sets up a solid foundation for future improvements, and this ticks the box.

I've made some general comments, but tbh the only change absolutely needed is removing spyne as a dependency in the pyproject.toml.

endpoints_registry[service_name].add(f"WSGI:{mount_path}")
logger.debug(f"Registered WSGI service {service_name} at {mount_path}")
logger.info(f"🔧 Registering {service_name} at: {mount_path}")
logger.info(f" Router type: {type(router_or_app)}")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe make these logs debug instead of info

# Use include_router for APIRouter instances
if isinstance(router_or_app, APIRouter):
if hasattr(router_or_app, "routes"):
logger.info(f" Routes in router: {len(router_or_app.routes)}")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

# For FastAPI apps, use mount
self.mount(mount_path, router_or_app)
endpoints_registry[service_name].add(f"MOUNTED:{mount_path}")
logger.info(f"✅ Mounted app {service_name} at {mount_path}")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logs

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

filename convention is with no underscore

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

preferred convention for tests is flat structure without classes

"starlette>=0.40.0,<0.42.0",
"uvicorn>=0.24.0,<0.25",
"httpx>=0.27.0,<0.28",
"spyne>=2.14.0,<3",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the spyne dependency here



@dataclass
class ServerFault(Exception):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fault models defined here are not actually used (built manually in fastapi_server.py). Consider removing or using them in the router - just keep consistent.

actual_location = f"{base_url}{path}"

# Replace the location in WSDL
wsdl_content = wsdl_content.replace(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are hardcoded - consider using a template variable like {{SERVICE_LOCATION}} in WSDL and replace that

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Migrate from Spyne to FastAPI + lxml for SOAP Services

4 participants