pysof 0.1.31__tar.gz → 0.1.32__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pysof-0.1.31 → pysof-0.1.32}/Cargo.toml +2 -2
- {pysof-0.1.31 → pysof-0.1.32}/PKG-INFO +1 -1
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhir/Cargo.toml +2 -2
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhir-macro/Cargo.toml +1 -1
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/Cargo.toml +2 -2
- {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/Cargo.toml +2 -2
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/Cargo.toml +3 -3
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/README.md +19 -19
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/src/cli.rs +40 -8
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/src/handlers.rs +58 -25
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/src/models.rs +2 -2
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/src/server.rs +2 -2
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/common/mod.rs +8 -8
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/server_tests.rs +23 -19
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/test_format_parameter_body.rs +7 -7
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/test_header_parameter_body.rs +7 -7
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/test_limit_parameter_body.rs +6 -6
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/test_parameter_validation.rs +1 -1
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/test_patient_reference_formats.rs +4 -4
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/test_query_parameter_combinations.rs +13 -13
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/test_run_operation_parameters.rs +2 -2
- pysof-0.1.31/crates/sof/operations-run.md +0 -544
- {pysof-0.1.31 → pysof-0.1.32}/README.md +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhir/README.md +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhir/build.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhir/src/lib.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhir/src/parameters.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhir/src/r4.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhir/src/r4b.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhir/src/r5.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhir/src/r6.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhir/src/r6.rs.template +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhir/tests/integer_string_integration.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhir/tests/simple_null_test.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhir/tests/test_examples.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhir/tests/test_serde.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhir-macro/README.md +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhir-macro/src/lib.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/PRECISION_LIMITATION.md +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/README.md +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/benches/cli_benches.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/benches/evaluator_benches.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/benches/parser_benches.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/benches/server_benches.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/examples/test_ucum.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/grammar/fhirpath.g4 +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/server-api.md +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/aggregate_function.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/bin/fhirpath-cli.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/bin/fhirpath-server.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/boolean_functions.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/boundary_functions.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/cli.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/collection_functions.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/collection_navigation.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/contains_function.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/conversion_functions.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/date_operation.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/datetime_impl.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/distinct_functions.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/error.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/evaluator.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/extension_function.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/fhir_type_hierarchy.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/handlers.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/json_utils.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/lib.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/long_conversion.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/models.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/not_function.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/parse_debug.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/parser.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/polymorphic_access.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/reference_key_functions.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/repeat_function.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/resource_type.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/server.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/set_operations.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/subset_functions.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/terminology_client.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/terminology_functions.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/trace_function.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/type_function.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/type_inference.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/src/ucum.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/all_function_tests.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/boundary_debug_tests.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/boundary_function_integration_tests.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/comment_test.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/common/context.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/common/mod.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/common/parser.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/common/runner.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/context_trace_test.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/data/r4/input/observation-example.json +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/data/r4/input/observation-example.xml +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/data/r4/input/patient-example.json +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/data/r4/input/patient-example.xml +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/data/r4/input/questionnaire-example.json +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/data/r4/input/questionnaire-example.xml +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/data/r4/input/valueset-example-expansion.json +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/data/r4/input/valueset-example-expansion.xml +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/data/r4/tests-fhir-r4.xml +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/data/r5/input/appointment-examplereq.json +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/data/r5/input/ccda.json +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/data/r5/input/codesystem-example.json +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/data/r5/input/conceptmap-example.json +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/data/r5/input/explanationofbenefit-example.json +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/data/r5/input/observation-example.json +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/data/r5/input/observation-example.xml +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/data/r5/input/parameters-example-types.json +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/data/r5/input/patient-container-example.json +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/data/r5/input/patient-example-name.json +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/data/r5/input/patient-example-period.json +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/data/r5/input/patient-example.json +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/data/r5/input/patient-name-extensions.json +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/data/r5/input/questionnaire-example.json +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/data/r5/input/valueset-example-expansion.json +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/data/r5/known-test-failures.json +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/data/r5/tests-fhir-r5.xml +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/data/testSchema.xsd +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/date_operation_tests.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/datetime_boundary_tests.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/debug_datetime_boundary.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/debug_string_boundary_tests.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/define_variable_test.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/enhanced_variable_tests.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/evaluator_tests.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/extension_tests.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/fhir_boundary_tests.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/is_as_method_tests.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/join_function_test.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/oftype_datetime_tests.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/parse_debug_test.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/parser_tests.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/polymorphic_r4_tests.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/polymorphic_tests.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/precision_tests.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/r4_tests.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/r5_tests.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/reference_key_debug.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/test_boundary_zero.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/trace_api_test.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/trace_tests.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/tree_navigation_tests.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/truncate_tests.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/type_operation_tests.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/type_preservation_integration_test.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/type_reflection_tests.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/uri_type_test.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath/tests/uuid_type_preservation_test.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath-support/Cargo.toml +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath-support/README.md +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath-support/src/lib.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/fhirpath-support/src/type_info.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/.gitignore +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/Cargo.lock +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/Makefile +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/PYPI_CHECKLIST.md +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/README.md +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/WHEEL_BUILDING.md +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/multithreading_example.py +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/python-tests/__init__.py +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/python-tests/test_content_types.py +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/python-tests/test_core_functions.py +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/python-tests/test_error_handling.py +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/python-tests/test_fhir_versions.py +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/python-tests/test_import.py +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/python-tests/test_package_metadata.py +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/python-tests/test_source_errors.py +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/scripts/build-wheels.py +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/src/lib.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/src/pysof/__init__.py +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/src/pysof/_pysof.pyi +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/src/pysof/py.typed +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/test_multithreading.py +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/tests/integration/content_types.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/tests/integration/error_handling.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/tests/integration/fhir_versions.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/tests/integration/mod.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/tests/integration.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/tests/lib_coverage_tests.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/tests/lib_tests.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/tests/multithreading_integration.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/tests/threading_test.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/pysof/uv.lock +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/benches/parallel_processing_bench.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/src/data_source.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/src/error.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/src/lib.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/src/mod.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/src/parquet_schema.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/src/streaming.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/src/traits.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/debug_boolean_test.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/debug_column_ordering.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/debug_datetime_instant_constants.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/debug_datetime_type_info.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/debug_enum_conversion.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/debug_evaluation_result_conversion.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/debug_extension_function.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/debug_extension_macro_fix.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/debug_extension_simple.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/debug_fhir_resource_structure.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/debug_foreach_combinations.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/debug_inequality.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/debug_instant_constant.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/debug_instant_type_info.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/debug_raw_resource.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/debug_reference_key_types.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/extension_debug_test.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/foreach_test.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/multiselect_test.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/run_foreach_tests.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/sql-on-fhir-v2/tests/basic.json +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/sql-on-fhir-v2/tests/collection.json +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/sql-on-fhir-v2/tests/combinations.json +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/sql-on-fhir-v2/tests/constant.json +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/sql-on-fhir-v2/tests/constant_types.json +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/sql-on-fhir-v2/tests/fhirpath.json +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/sql-on-fhir-v2/tests/fhirpath_numbers.json +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/sql-on-fhir-v2/tests/fn_boundary.json +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/sql-on-fhir-v2/tests/fn_empty.json +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/sql-on-fhir-v2/tests/fn_extension.json +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/sql-on-fhir-v2/tests/fn_first.json +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/sql-on-fhir-v2/tests/fn_join.json +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/sql-on-fhir-v2/tests/fn_oftype.json +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/sql-on-fhir-v2/tests/fn_reference_keys.json +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/sql-on-fhir-v2/tests/foreach.json +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/sql-on-fhir-v2/tests/logic.json +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/sql-on-fhir-v2/tests/repeat.json +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/sql-on-fhir-v2/tests/union.json +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/sql-on-fhir-v2/tests/validate.json +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/sql-on-fhir-v2/tests/view_resource.json +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/sql-on-fhir-v2/tests/where.json +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/sql_on_fhir_tests.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/test_base64_binary_constant.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/test_boolean_constant_debug.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/test_boolean_constant_debug2.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/test_boolean_constant_debug3.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/test_boolean_validation.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/test_chunked_processing.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/test_cli_file_source.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/test_csv_quote_handling.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/test_extension_fix_verification.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/test_extension_value_access.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/test_ndjson_input.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/test_parallel_working.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/test_parquet_export.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/test_parquet_large_dataset.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/test_parquet_server_options.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/test_runner_integration.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/test_shortened_format_names.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/test_where_clause_validation.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/crates/sof/tests/test_x_ndjson_support.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/pyproject.toml +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/src/lib.rs +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/src/pysof/__init__.py +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/src/pysof/_pysof.cpython-311-darwin.so +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/src/pysof/_pysof.pyi +0 -0
- {pysof-0.1.31 → pysof-0.1.32}/src/pysof/py.typed +0 -0
|
@@ -15,8 +15,8 @@ crate-type = ["cdylib"]
|
|
|
15
15
|
|
|
16
16
|
[dependencies]
|
|
17
17
|
pyo3 = { version = ">=0.24.1", features = ["extension-module", "generate-import-lib"] }
|
|
18
|
-
helios-sof = { path = "../sof", version = "0.1.
|
|
19
|
-
helios-fhir = { path = "../fhir", version = "0.1.
|
|
18
|
+
helios-sof = { path = "../sof", version = "0.1.32" }
|
|
19
|
+
helios-fhir = { path = "../fhir", version = "0.1.32" }
|
|
20
20
|
serde = { version = "=1.0.219", features = ["derive"] }
|
|
21
21
|
serde_json = { version = "=1.0.143" }
|
|
22
22
|
chrono = { version = "0.4", features = ["serde"] }
|
|
@@ -22,8 +22,8 @@ skip-r6-download = []
|
|
|
22
22
|
serde = { workspace = true }
|
|
23
23
|
serde_json = { workspace = true, features = ["raw_value"] }
|
|
24
24
|
clap = { version = "4.0", features = ["derive"] }
|
|
25
|
-
helios-fhir-macro = { path = "../fhir-macro", version = "0.1.
|
|
26
|
-
helios-fhirpath-support = { path = "../fhirpath-support", version = "0.1.
|
|
25
|
+
helios-fhir-macro = { path = "../fhir-macro", version = "0.1.32" }
|
|
26
|
+
helios-fhirpath-support = { path = "../fhirpath-support", version = "0.1.32" }
|
|
27
27
|
time = "0.3"
|
|
28
28
|
chrono = { workspace = true }
|
|
29
29
|
# Re-add serde-with-arbitrary-precision, keep macros
|
|
@@ -19,4 +19,4 @@ proc-macro2 = "1.0"
|
|
|
19
19
|
serde = { workspace = true }
|
|
20
20
|
serde_json = { workspace = true }
|
|
21
21
|
heck = "0.5" # For case conversion
|
|
22
|
-
helios-fhirpath-support = { path = "../fhirpath-support", version = "0.1.
|
|
22
|
+
helios-fhirpath-support = { path = "../fhirpath-support", version = "0.1.32" }
|
|
@@ -17,8 +17,8 @@ R5 = ["helios-fhir/R5"]
|
|
|
17
17
|
R6 = ["helios-fhir/R6"]
|
|
18
18
|
|
|
19
19
|
[dependencies]
|
|
20
|
-
helios-fhir = { path = "../fhir", version = "0.1.
|
|
21
|
-
helios-fhirpath-support = { path = "../fhirpath-support", version = "0.1.
|
|
20
|
+
helios-fhir = { path = "../fhir", version = "0.1.32" }
|
|
21
|
+
helios-fhirpath-support = { path = "../fhirpath-support", version = "0.1.32" }
|
|
22
22
|
chumsky = "0.10"
|
|
23
23
|
roxmltree = "0.20"
|
|
24
24
|
chrono = { workspace = true } # For date/time parsing and functions
|
|
@@ -16,8 +16,8 @@ crate-type = ["cdylib"]
|
|
|
16
16
|
|
|
17
17
|
[dependencies]
|
|
18
18
|
pyo3 = { version = ">=0.24.1", features = ["extension-module", "generate-import-lib"] }
|
|
19
|
-
helios-sof = { path = "../sof", version = "0.1.
|
|
20
|
-
helios-fhir = { path = "../fhir", version = "0.1.
|
|
19
|
+
helios-sof = { path = "../sof", version = "0.1.32" }
|
|
20
|
+
helios-fhir = { path = "../fhir", version = "0.1.32" }
|
|
21
21
|
serde = { version = "=1.0.219", features = ["derive"] }
|
|
22
22
|
serde_json = { version = "=1.0.143" }
|
|
23
23
|
chrono = { version = "0.4", features = ["serde"] }
|
|
@@ -27,9 +27,9 @@ R6 = ["helios-fhir/R6", "helios-fhirpath/R6"]
|
|
|
27
27
|
[dependencies]
|
|
28
28
|
clap = { version = "4.0", features = ["derive", "env"] }
|
|
29
29
|
tokio = { version = "1.0", features = ["full"] }
|
|
30
|
-
helios-fhir = { path = "../fhir", version = "0.1.
|
|
31
|
-
helios-fhirpath = { path = "../fhirpath", version = "0.1.
|
|
32
|
-
helios-fhirpath-support = { path = "../fhirpath-support", version = "0.1.
|
|
30
|
+
helios-fhir = { path = "../fhir", version = "0.1.32" }
|
|
31
|
+
helios-fhirpath = { path = "../fhirpath", version = "0.1.32" }
|
|
32
|
+
helios-fhirpath-support = { path = "../fhirpath-support", version = "0.1.32" }
|
|
33
33
|
serde = { workspace = true }
|
|
34
34
|
serde_json = { workspace = true }
|
|
35
35
|
csv = "1.3"
|
|
@@ -263,7 +263,7 @@ sof-cli -v view.json -s s3://bucket/patients.ndjson -f json
|
|
|
263
263
|
sof-cli -v view.json -s file:///data.ndjson -b additional-data.json -f csv
|
|
264
264
|
|
|
265
265
|
# Server API with NDJSON
|
|
266
|
-
curl -X POST "http://localhost:8080/ViewDefinition/$run?source=s3://bucket/data.ndjson" \
|
|
266
|
+
curl -X POST "http://localhost:8080/ViewDefinition/$viewdefinition-run?source=s3://bucket/data.ndjson" \
|
|
267
267
|
-H "Content-Type: application/json" \
|
|
268
268
|
-d '{"resourceType": "Parameters", "parameter": [{"name": "viewResource", "resource": {...}}]}'
|
|
269
269
|
```
|
|
@@ -472,12 +472,12 @@ Returns the server's CapabilityStatement describing supported operations:
|
|
|
472
472
|
curl http://localhost:8080/metadata
|
|
473
473
|
```
|
|
474
474
|
|
|
475
|
-
##### POST /ViewDefinition/$run
|
|
475
|
+
##### POST /ViewDefinition/$viewdefinition-run
|
|
476
476
|
Execute a ViewDefinition transformation:
|
|
477
477
|
|
|
478
478
|
```bash
|
|
479
479
|
# JSON output (default)
|
|
480
|
-
curl -X POST http://localhost:8080/ViewDefinition/$run \
|
|
480
|
+
curl -X POST http://localhost:8080/ViewDefinition/$viewdefinition-run \
|
|
481
481
|
-H "Content-Type: application/json" \
|
|
482
482
|
-d '{
|
|
483
483
|
"resourceType": "Parameters",
|
|
@@ -508,17 +508,17 @@ curl -X POST http://localhost:8080/ViewDefinition/$run \
|
|
|
508
508
|
}'
|
|
509
509
|
|
|
510
510
|
# CSV output (includes headers by default)
|
|
511
|
-
curl -X POST "http://localhost:8080/ViewDefinition/$run?_format=text/csv" \
|
|
511
|
+
curl -X POST "http://localhost:8080/ViewDefinition/$viewdefinition-run?_format=text/csv" \
|
|
512
512
|
-H "Content-Type: application/json" \
|
|
513
513
|
-d '{...}'
|
|
514
514
|
|
|
515
515
|
# CSV output without headers
|
|
516
|
-
curl -X POST "http://localhost:8080/ViewDefinition/$run?_format=text/csv&header=false" \
|
|
516
|
+
curl -X POST "http://localhost:8080/ViewDefinition/$viewdefinition-run?_format=text/csv&header=false" \
|
|
517
517
|
-H "Content-Type: application/json" \
|
|
518
518
|
-d '{...}'
|
|
519
519
|
|
|
520
520
|
# NDJSON output
|
|
521
|
-
curl -X POST http://localhost:8080/ViewDefinition/$run \
|
|
521
|
+
curl -X POST http://localhost:8080/ViewDefinition/$viewdefinition-run \
|
|
522
522
|
-H "Content-Type: application/json" \
|
|
523
523
|
-H "Accept: application/ndjson" \
|
|
524
524
|
-d '{...}'
|
|
@@ -526,7 +526,7 @@ curl -X POST http://localhost:8080/ViewDefinition/$run \
|
|
|
526
526
|
|
|
527
527
|
#### Parameters
|
|
528
528
|
|
|
529
|
-
The `$run` POST operation accepts parameters either as query parameters or in a FHIR Parameters resource.
|
|
529
|
+
The `$viewdefinition-run` POST operation accepts parameters either as query parameters or in a FHIR Parameters resource.
|
|
530
530
|
|
|
531
531
|
Parameter table:
|
|
532
532
|
|
|
@@ -617,17 +617,17 @@ The server automatically sets appropriate response headers based on the output f
|
|
|
617
617
|
|
|
618
618
|
```bash
|
|
619
619
|
# Limit results - first 50 records as CSV
|
|
620
|
-
curl -X POST "http://localhost:8080/ViewDefinition/$run?_limit=50&_format=text/csv" \
|
|
620
|
+
curl -X POST "http://localhost:8080/ViewDefinition/$viewdefinition-run?_limit=50&_format=text/csv" \
|
|
621
621
|
-H "Content-Type: application/json" \
|
|
622
622
|
-d '{...}'
|
|
623
623
|
|
|
624
624
|
# CSV without headers, limited to 20 results
|
|
625
|
-
curl -X POST "http://localhost:8080/ViewDefinition/$run?_format=text/csv&header=false&_limit=20" \
|
|
625
|
+
curl -X POST "http://localhost:8080/ViewDefinition/$viewdefinition-run?_format=text/csv&header=false&_limit=20" \
|
|
626
626
|
-H "Content-Type: application/json" \
|
|
627
627
|
-d '{...}'
|
|
628
628
|
|
|
629
629
|
# Using header parameter in request body (overrides query params)
|
|
630
|
-
curl -X POST "http://localhost:8080/ViewDefinition/$run?_format=text/csv" \
|
|
630
|
+
curl -X POST "http://localhost:8080/ViewDefinition/$viewdefinition-run?_format=text/csv" \
|
|
631
631
|
-H "Content-Type: application/json" \
|
|
632
632
|
-d '{
|
|
633
633
|
"resourceType": "Parameters",
|
|
@@ -641,12 +641,12 @@ curl -X POST "http://localhost:8080/ViewDefinition/$run?_format=text/csv" \
|
|
|
641
641
|
}'
|
|
642
642
|
|
|
643
643
|
# Filter by modification time (requires resources with lastUpdated metadata)
|
|
644
|
-
curl -X POST "http://localhost:8080/ViewDefinition/$run?_since=2024-01-01T00:00:00Z" \
|
|
644
|
+
curl -X POST "http://localhost:8080/ViewDefinition/$viewdefinition-run?_since=2024-01-01T00:00:00Z" \
|
|
645
645
|
-H "Content-Type: application/json" \
|
|
646
646
|
-d '{...}'
|
|
647
647
|
|
|
648
648
|
# Load data from S3 bucket
|
|
649
|
-
curl -X POST "http://localhost:8080/ViewDefinition/$run?source=s3://my-bucket/bundle.json" \
|
|
649
|
+
curl -X POST "http://localhost:8080/ViewDefinition/$viewdefinition-run?source=s3://my-bucket/bundle.json" \
|
|
650
650
|
-H "Content-Type: application/json" \
|
|
651
651
|
-d '{
|
|
652
652
|
"resourceType": "Parameters",
|
|
@@ -657,24 +657,24 @@ curl -X POST "http://localhost:8080/ViewDefinition/$run?source=s3://my-bucket/bu
|
|
|
657
657
|
}'
|
|
658
658
|
|
|
659
659
|
# Load data from Azure with filtering
|
|
660
|
-
curl -X POST "http://localhost:8080/ViewDefinition/$run?source=azure://container/data.json&_limit=100" \
|
|
660
|
+
curl -X POST "http://localhost:8080/ViewDefinition/$viewdefinition-run?source=azure://container/data.json&_limit=100" \
|
|
661
661
|
-H "Content-Type: application/json" \
|
|
662
662
|
-d '{...}'
|
|
663
663
|
|
|
664
664
|
# Generate Parquet with custom compression and row group size
|
|
665
|
-
curl -X POST "http://localhost:8080/ViewDefinition/$run?_format=application/parquet&compression=zstd&rowGroupSize=512" \
|
|
665
|
+
curl -X POST "http://localhost:8080/ViewDefinition/$viewdefinition-run?_format=application/parquet&compression=zstd&rowGroupSize=512" \
|
|
666
666
|
-H "Content-Type: application/json" \
|
|
667
667
|
-d '{...}' \
|
|
668
668
|
--output result.parquet
|
|
669
669
|
|
|
670
670
|
# Generate large Parquet with file splitting (returns ZIP if multiple files)
|
|
671
|
-
curl -X POST "http://localhost:8080/ViewDefinition/$run?_format=application/parquet&maxFileSize=100" \
|
|
671
|
+
curl -X POST "http://localhost:8080/ViewDefinition/$viewdefinition-run?_format=application/parquet&maxFileSize=100" \
|
|
672
672
|
-H "Content-Type: application/json" \
|
|
673
673
|
-d '{...}' \
|
|
674
674
|
--output result.zip
|
|
675
675
|
|
|
676
676
|
# Using Parquet parameters in request body
|
|
677
|
-
curl -X POST "http://localhost:8080/ViewDefinition/$run" \
|
|
677
|
+
curl -X POST "http://localhost:8080/ViewDefinition/$viewdefinition-run" \
|
|
678
678
|
-H "Content-Type: application/json" \
|
|
679
679
|
-d '{
|
|
680
680
|
"resourceType": "Parameters",
|
|
@@ -901,19 +901,19 @@ sof-cli --view view.json --bundle large-data.json --format parquet \
|
|
|
901
901
|
# output_003.parquet (remaining data)
|
|
902
902
|
|
|
903
903
|
# Server API - single Parquet file
|
|
904
|
-
curl -X POST "http://localhost:8080/ViewDefinition/$run?_format=application/parquet" \
|
|
904
|
+
curl -X POST "http://localhost:8080/ViewDefinition/$viewdefinition-run?_format=application/parquet" \
|
|
905
905
|
-H "Content-Type: application/json" \
|
|
906
906
|
-d '{"resourceType": "Parameters", ...}' \
|
|
907
907
|
--output result.parquet
|
|
908
908
|
|
|
909
909
|
# Server API - with file splitting (returns ZIP archive if multiple files)
|
|
910
|
-
curl -X POST "http://localhost:8080/ViewDefinition/$run?_format=application/parquet&maxFileSize=100" \
|
|
910
|
+
curl -X POST "http://localhost:8080/ViewDefinition/$viewdefinition-run?_format=application/parquet&maxFileSize=100" \
|
|
911
911
|
-H "Content-Type: application/json" \
|
|
912
912
|
-d '{"resourceType": "Parameters", ...}' \
|
|
913
913
|
--output result.zip
|
|
914
914
|
|
|
915
915
|
# Server API - optimized settings for large datasets
|
|
916
|
-
curl -X POST "http://localhost:8080/ViewDefinition/$run?_format=application/parquet&compression=zstd&rowGroupSize=512&maxFileSize=500" \
|
|
916
|
+
curl -X POST "http://localhost:8080/ViewDefinition/$viewdefinition-run?_format=application/parquet&compression=zstd&rowGroupSize=512&maxFileSize=500" \
|
|
917
917
|
-H "Content-Type: application/json" \
|
|
918
918
|
-d '{"resourceType": "Parameters", ...}' \
|
|
919
919
|
--output result.zip
|
|
@@ -276,7 +276,19 @@ fn normalize_source_path(source: &str) -> Result<String, Box<dyn std::error::Err
|
|
|
276
276
|
.unwrap_or_else(|_| absolute_path.clone());
|
|
277
277
|
|
|
278
278
|
// Convert to file:// URL
|
|
279
|
-
|
|
279
|
+
// On Windows, paths like C:\foo need to become file:///C:/foo
|
|
280
|
+
// On Unix, paths like /foo become file:///foo
|
|
281
|
+
#[cfg(windows)]
|
|
282
|
+
let url = {
|
|
283
|
+
let path_str = canonical_path.to_string_lossy();
|
|
284
|
+
// Replace backslashes with forward slashes for URL format
|
|
285
|
+
let normalized = path_str.replace('\\', "/");
|
|
286
|
+
format!("file:///{}", normalized)
|
|
287
|
+
};
|
|
288
|
+
#[cfg(not(windows))]
|
|
289
|
+
let url = format!("file://{}", canonical_path.display());
|
|
290
|
+
|
|
291
|
+
Ok(url)
|
|
280
292
|
}
|
|
281
293
|
|
|
282
294
|
/// Main entry point for the SQL-on-FHIR CLI application.
|
|
@@ -774,20 +786,40 @@ mod tests {
|
|
|
774
786
|
#[test]
|
|
775
787
|
fn test_normalize_source_path_absolute_path() {
|
|
776
788
|
// Absolute paths should be converted to file:// URLs
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
789
|
+
// Use a platform-appropriate absolute path
|
|
790
|
+
#[cfg(windows)]
|
|
791
|
+
let test_path = "C:\\tmp\\test.json";
|
|
792
|
+
#[cfg(not(windows))]
|
|
793
|
+
let test_path = "/tmp/test.json";
|
|
794
|
+
|
|
795
|
+
let result = normalize_source_path(test_path).unwrap();
|
|
796
|
+
assert!(
|
|
797
|
+
result.starts_with("file:///"),
|
|
798
|
+
"Expected file:/// prefix, got: {}",
|
|
799
|
+
result
|
|
800
|
+
);
|
|
801
|
+
// On macOS, /tmp may be symlinked to /private/tmp
|
|
802
|
+
assert!(
|
|
803
|
+
result.contains("tmp") && result.contains("test.json"),
|
|
804
|
+
"Expected path to contain tmp and test.json, got: {}",
|
|
805
|
+
result
|
|
806
|
+
);
|
|
780
807
|
}
|
|
781
808
|
|
|
782
809
|
#[test]
|
|
783
810
|
fn test_normalize_source_path_relative_path() {
|
|
784
811
|
// Relative paths should be converted to absolute file:// URLs
|
|
785
812
|
let result = normalize_source_path("./test.json").unwrap();
|
|
786
|
-
assert!(result.starts_with("file:///"));
|
|
787
|
-
// Should contain the current working directory
|
|
788
|
-
let cwd = std::env::current_dir().unwrap();
|
|
789
813
|
assert!(
|
|
790
|
-
result.
|
|
814
|
+
result.starts_with("file:///"),
|
|
815
|
+
"Expected file:/// prefix, got: {}",
|
|
816
|
+
result
|
|
817
|
+
);
|
|
818
|
+
// Should contain test.json somewhere in the path
|
|
819
|
+
assert!(
|
|
820
|
+
result.contains("test.json"),
|
|
821
|
+
"Expected path to contain test.json, got: {}",
|
|
822
|
+
result
|
|
791
823
|
);
|
|
792
824
|
}
|
|
793
825
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
//! Request handlers for the SQL-on-FHIR server
|
|
2
2
|
//!
|
|
3
3
|
//! This module implements the HTTP request handlers for all server endpoints,
|
|
4
|
-
//! including the CapabilityStatement and ViewDefinition/$run operations.
|
|
4
|
+
//! including the CapabilityStatement and ViewDefinition/$viewdefinition-run operations.
|
|
5
5
|
|
|
6
6
|
use axum::{
|
|
7
7
|
Json,
|
|
@@ -39,9 +39,9 @@ pub async fn capability_statement() -> ServerResult<impl IntoResponse> {
|
|
|
39
39
|
))
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
/// Handler for POST /ViewDefinition/$run - executes a ViewDefinition
|
|
42
|
+
/// Handler for POST /ViewDefinition/$viewdefinition-run - executes a ViewDefinition
|
|
43
43
|
///
|
|
44
|
-
/// The `$run` operation on a ViewDefinition resource applies the view definition to
|
|
44
|
+
/// The `$viewdefinition-run` operation on a ViewDefinition resource applies the view definition to
|
|
45
45
|
/// transform FHIR resources into a tabular format and returns the results synchronously.
|
|
46
46
|
///
|
|
47
47
|
/// # Arguments
|
|
@@ -78,7 +78,7 @@ pub async fn run_view_definition_handler(
|
|
|
78
78
|
headers: HeaderMap,
|
|
79
79
|
Json(body): Json<serde_json::Value>,
|
|
80
80
|
) -> ServerResult<Response> {
|
|
81
|
-
info!("Handling ViewDefinition/$run request");
|
|
81
|
+
info!("Handling ViewDefinition/$viewdefinition-run request");
|
|
82
82
|
debug!("Query params: {:?}", params);
|
|
83
83
|
|
|
84
84
|
// Validate and parse query parameters
|
|
@@ -105,8 +105,6 @@ pub async fn run_view_definition_handler(
|
|
|
105
105
|
));
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
-
// Source parameter is now handled below
|
|
109
|
-
|
|
110
108
|
// For backward compatibility, extract the legacy tuple format
|
|
111
109
|
let view_def_json = extracted_params.view_definition;
|
|
112
110
|
let resources_json = if extracted_params.resources.is_empty() {
|
|
@@ -155,9 +153,6 @@ pub async fn run_view_definition_handler(
|
|
|
155
153
|
validated_params.format = content_type;
|
|
156
154
|
}
|
|
157
155
|
|
|
158
|
-
// Create ViewDefinition
|
|
159
|
-
let view_definition = parse_view_definition(view_def_json)?;
|
|
160
|
-
|
|
161
156
|
// Apply patient and group filters from body parameters to resources if provided
|
|
162
157
|
let mut filtered_resources = resources_json.unwrap_or_default();
|
|
163
158
|
|
|
@@ -220,14 +215,23 @@ pub async fn run_view_definition_handler(
|
|
|
220
215
|
}
|
|
221
216
|
|
|
222
217
|
// Handle source parameter - load data from external source if provided
|
|
218
|
+
// IMPORTANT: We load the source bundle FIRST so we can determine its FHIR version
|
|
219
|
+
// and parse the ViewDefinition using the same version
|
|
223
220
|
let mut source_bundle = None;
|
|
221
|
+
let mut source_fhir_version = None;
|
|
224
222
|
if let Some(source) = &source_param {
|
|
225
223
|
info!("Loading data from source: {}", source);
|
|
226
224
|
let data_source = UniversalDataSource::new();
|
|
227
|
-
let
|
|
225
|
+
let loaded_bundle = data_source.load(source).await?;
|
|
226
|
+
|
|
227
|
+
// Capture the FHIR version from the loaded source bundle
|
|
228
|
+
source_fhir_version = Some(loaded_bundle.version());
|
|
228
229
|
|
|
229
230
|
// Apply filters to source bundle if needed
|
|
230
|
-
|
|
231
|
+
let loaded_bundle = if patient_filter.is_some()
|
|
232
|
+
|| group_filter.is_some()
|
|
233
|
+
|| validated_params.since.is_some()
|
|
234
|
+
{
|
|
231
235
|
// Extract resources from source bundle for filtering
|
|
232
236
|
let mut source_resources = extract_resources_from_bundle(&loaded_bundle)?;
|
|
233
237
|
|
|
@@ -244,13 +248,30 @@ pub async fn run_view_definition_handler(
|
|
|
244
248
|
source_resources = filter_resources_by_since(source_resources, since)?;
|
|
245
249
|
}
|
|
246
250
|
|
|
247
|
-
// Recreate bundle with filtered resources
|
|
248
|
-
|
|
249
|
-
|
|
251
|
+
// Recreate bundle with filtered resources using the same FHIR version
|
|
252
|
+
create_bundle_from_resources_for_version(
|
|
253
|
+
source_resources,
|
|
254
|
+
source_fhir_version.unwrap(),
|
|
255
|
+
)?
|
|
256
|
+
} else {
|
|
257
|
+
loaded_bundle
|
|
258
|
+
};
|
|
250
259
|
|
|
251
260
|
source_bundle = Some(loaded_bundle);
|
|
252
261
|
}
|
|
253
262
|
|
|
263
|
+
// Create ViewDefinition - use the source bundle's version if available,
|
|
264
|
+
// otherwise use the default (newest enabled) version
|
|
265
|
+
let view_definition = if let Some(version) = source_fhir_version {
|
|
266
|
+
info!(
|
|
267
|
+
"Parsing ViewDefinition as {:?} (matching source bundle)",
|
|
268
|
+
version
|
|
269
|
+
);
|
|
270
|
+
parse_view_definition_for_version(view_def_json, version)?
|
|
271
|
+
} else {
|
|
272
|
+
parse_view_definition(view_def_json)?
|
|
273
|
+
};
|
|
274
|
+
|
|
254
275
|
// Apply filters to provided resources
|
|
255
276
|
if patient_filter.is_some() || group_filter.is_some() {
|
|
256
277
|
filtered_resources = filter_resources_by_patient_and_group(
|
|
@@ -400,9 +421,9 @@ fn create_capability_statement() -> serde_json::Value {
|
|
|
400
421
|
"rest": [{
|
|
401
422
|
"mode": "server",
|
|
402
423
|
"operation": [{
|
|
403
|
-
"name": "run",
|
|
404
|
-
"definition": "http://sql-on-fhir.org/OperationDefinition
|
|
405
|
-
"documentation": "Execute a ViewDefinition to transform FHIR resources into tabular format. Supports CSV, JSON, and NDJSON output formats. This is a type-level operation invoked at /ViewDefinition/$run"
|
|
424
|
+
"name": "viewdefinition-run",
|
|
425
|
+
"definition": "http://sql-on-fhir.org/OperationDefinition/$viewdefinition-run",
|
|
426
|
+
"documentation": "Execute a ViewDefinition to transform FHIR resources into tabular format. Supports CSV, JSON, and NDJSON output formats. This is a type-level operation invoked at /ViewDefinition/$viewdefinition-run"
|
|
406
427
|
}]
|
|
407
428
|
}]
|
|
408
429
|
})
|
|
@@ -454,11 +475,17 @@ fn resolve_view_reference(reference: &str) -> ServerResult<SofViewDefinition> {
|
|
|
454
475
|
)))
|
|
455
476
|
}
|
|
456
477
|
|
|
457
|
-
/// Parse a ViewDefinition from JSON
|
|
478
|
+
/// Parse a ViewDefinition from JSON using the newest enabled FHIR version
|
|
458
479
|
fn parse_view_definition(json: serde_json::Value) -> ServerResult<SofViewDefinition> {
|
|
459
|
-
|
|
480
|
+
parse_view_definition_for_version(json, get_newest_enabled_fhir_version())
|
|
481
|
+
}
|
|
460
482
|
|
|
461
|
-
|
|
483
|
+
/// Parse a ViewDefinition from JSON using a specific FHIR version
|
|
484
|
+
fn parse_view_definition_for_version(
|
|
485
|
+
json: serde_json::Value,
|
|
486
|
+
version: helios_fhir::FhirVersion,
|
|
487
|
+
) -> ServerResult<SofViewDefinition> {
|
|
488
|
+
match version {
|
|
462
489
|
#[cfg(feature = "R4")]
|
|
463
490
|
helios_fhir::FhirVersion::R4 => {
|
|
464
491
|
let view_def: helios_fhir::r4::ViewDefinition =
|
|
@@ -539,10 +566,16 @@ fn parse_parameters(json: serde_json::Value) -> ServerResult<RunParameters> {
|
|
|
539
566
|
}
|
|
540
567
|
}
|
|
541
568
|
|
|
542
|
-
/// Create a Bundle from a list of resources
|
|
569
|
+
/// Create a Bundle from a list of resources using the newest enabled FHIR version
|
|
543
570
|
fn create_bundle_from_resources(resources: Vec<serde_json::Value>) -> ServerResult<SofBundle> {
|
|
544
|
-
|
|
571
|
+
create_bundle_from_resources_for_version(resources, get_newest_enabled_fhir_version())
|
|
572
|
+
}
|
|
545
573
|
|
|
574
|
+
/// Create a Bundle from a list of resources using a specific FHIR version
|
|
575
|
+
fn create_bundle_from_resources_for_version(
|
|
576
|
+
resources: Vec<serde_json::Value>,
|
|
577
|
+
version: helios_fhir::FhirVersion,
|
|
578
|
+
) -> ServerResult<SofBundle> {
|
|
546
579
|
let bundle_json = serde_json::json!({
|
|
547
580
|
"resourceType": "Bundle",
|
|
548
581
|
"type": "collection",
|
|
@@ -553,7 +586,7 @@ fn create_bundle_from_resources(resources: Vec<serde_json::Value>) -> ServerResu
|
|
|
553
586
|
}).collect::<Vec<_>>()
|
|
554
587
|
});
|
|
555
588
|
|
|
556
|
-
match
|
|
589
|
+
match version {
|
|
557
590
|
#[cfg(feature = "R4")]
|
|
558
591
|
helios_fhir::FhirVersion::R4 => {
|
|
559
592
|
let bundle: helios_fhir::r4::Bundle =
|
|
@@ -700,7 +733,7 @@ fn merge_bundles(
|
|
|
700
733
|
/// Filter resources by patient and/or group reference
|
|
701
734
|
///
|
|
702
735
|
/// This function implements the patient and group filtering as specified in the
|
|
703
|
-
/// SQL-on-FHIR $run operation:
|
|
736
|
+
/// SQL-on-FHIR $viewdefinition-run operation:
|
|
704
737
|
///
|
|
705
738
|
/// - **Patient filter**: Returns only resources in the patient compartment of specified patients
|
|
706
739
|
/// - **Group filter**: Returns only resources that are members of the specified group
|
|
@@ -868,7 +901,7 @@ mod tests {
|
|
|
868
901
|
// Check that operation is listed at rest level (type-level operation)
|
|
869
902
|
let operations = &cap_stmt["rest"][0]["operation"];
|
|
870
903
|
assert!(operations.as_array().is_some());
|
|
871
|
-
assert_eq!(operations[0]["name"], "run");
|
|
904
|
+
assert_eq!(operations[0]["name"], "viewdefinition-run");
|
|
872
905
|
}
|
|
873
906
|
|
|
874
907
|
#[test]
|
|
@@ -8,7 +8,7 @@ use helios_sof::{ContentType, SofParameters};
|
|
|
8
8
|
use serde::Deserialize;
|
|
9
9
|
use tracing::debug;
|
|
10
10
|
|
|
11
|
-
/// Query parameters for ViewDefinition/$run endpoint
|
|
11
|
+
/// Query parameters for ViewDefinition/$viewdefinition-run endpoint
|
|
12
12
|
#[derive(Debug, Deserialize)]
|
|
13
13
|
pub struct RunQueryParams {
|
|
14
14
|
/// Output format override (alternative to Accept header)
|
|
@@ -89,7 +89,7 @@ pub struct ValidatedRunParams {
|
|
|
89
89
|
pub parquet_options: Option<helios_sof::ParquetOptions>,
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
-
/// Parameters for ViewDefinition/$run operation - now using proper FHIR Parameters
|
|
92
|
+
/// Parameters for ViewDefinition/$viewdefinition-run operation - now using proper FHIR Parameters
|
|
93
93
|
pub type RunParameters = SofParameters;
|
|
94
94
|
|
|
95
95
|
/// Validate and parse query parameters into structured format
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
//! GET /metadata
|
|
27
27
|
//! Returns: CapabilityStatement
|
|
28
28
|
//!
|
|
29
|
-
//! POST /ViewDefinition/$run
|
|
29
|
+
//! POST /ViewDefinition/$viewdefinition-run
|
|
30
30
|
//! Body: Parameters resource containing ViewDefinition and data
|
|
31
31
|
//! Query Parameters (except viewReference, viewResource, patient, group, resource):
|
|
32
32
|
//! _format: Output format - application/json, application/ndjson, text/csv, application/parquet
|
|
@@ -290,7 +290,7 @@ fn create_app_with_config(config: &ServerConfig) -> Router {
|
|
|
290
290
|
// FHIR endpoints
|
|
291
291
|
.route("/metadata", get(handlers::capability_statement))
|
|
292
292
|
.route(
|
|
293
|
-
"/ViewDefinition/$run",
|
|
293
|
+
"/ViewDefinition/$viewdefinition-run",
|
|
294
294
|
post(handlers::run_view_definition_handler),
|
|
295
295
|
)
|
|
296
296
|
// Health check endpoint
|
|
@@ -30,11 +30,11 @@ fn create_test_app() -> Router {
|
|
|
30
30
|
Router::new()
|
|
31
31
|
.route("/metadata", get(capability_statement_handler))
|
|
32
32
|
.route(
|
|
33
|
-
"/ViewDefinition/$run",
|
|
33
|
+
"/ViewDefinition/$viewdefinition-run",
|
|
34
34
|
post(run_view_definition_handler).get(run_view_definition_get_handler),
|
|
35
35
|
)
|
|
36
36
|
.route(
|
|
37
|
-
"/ViewDefinition/{id}/$run",
|
|
37
|
+
"/ViewDefinition/{id}/$viewdefinition-run",
|
|
38
38
|
get(run_view_definition_by_id_handler),
|
|
39
39
|
)
|
|
40
40
|
.route("/health", get(health_check))
|
|
@@ -70,14 +70,14 @@ async fn capability_statement_handler() -> axum::response::Response {
|
|
|
70
70
|
"resource": [{
|
|
71
71
|
"type": "ViewDefinition",
|
|
72
72
|
"operation": [{
|
|
73
|
-
"name": "run",
|
|
74
|
-
"definition": "http://sql-on-fhir.org/OperationDefinition
|
|
73
|
+
"name": "viewdefinition-run",
|
|
74
|
+
"definition": "http://sql-on-fhir.org/OperationDefinition/$viewdefinition-run",
|
|
75
75
|
"documentation": "Execute a ViewDefinition to transform FHIR resources into tabular format"
|
|
76
76
|
}]
|
|
77
77
|
}],
|
|
78
78
|
"operation": [{
|
|
79
|
-
"name": "run",
|
|
80
|
-
"definition": "http://sql-on-fhir.org/OperationDefinition
|
|
79
|
+
"name": "viewdefinition-run",
|
|
80
|
+
"definition": "http://sql-on-fhir.org/OperationDefinition/$viewdefinition-run",
|
|
81
81
|
"documentation": "Execute a ViewDefinition to transform FHIR resources into tabular format. Supports CSV, JSON, and NDJSON output formats."
|
|
82
82
|
}]
|
|
83
83
|
}]
|
|
@@ -546,7 +546,7 @@ async fn run_view_definition_get_handler(
|
|
|
546
546
|
// For GET requests without a ViewDefinition, we cannot proceed
|
|
547
547
|
error_response(
|
|
548
548
|
axum::http::StatusCode::BAD_REQUEST,
|
|
549
|
-
"GET /ViewDefinition/$run requires a ViewDefinition to be provided. Since complex parameters cannot be used in GET requests, please use POST with viewResource or viewReference parameter.",
|
|
549
|
+
"GET /ViewDefinition/$viewdefinition-run requires a ViewDefinition to be provided. Since complex parameters cannot be used in GET requests, please use POST with viewResource or viewReference parameter.",
|
|
550
550
|
)
|
|
551
551
|
}
|
|
552
552
|
|
|
@@ -558,7 +558,7 @@ async fn run_view_definition_by_id_handler(
|
|
|
558
558
|
error_response(
|
|
559
559
|
axum::http::StatusCode::NOT_IMPLEMENTED,
|
|
560
560
|
&format!(
|
|
561
|
-
"ViewDefinition lookup by ID '{}' is not implemented. Use POST /ViewDefinition/$run with the ViewDefinition in the request body.",
|
|
561
|
+
"ViewDefinition lookup by ID '{}' is not implemented. Use POST /ViewDefinition/$viewdefinition-run with the ViewDefinition in the request body.",
|
|
562
562
|
id
|
|
563
563
|
),
|
|
564
564
|
)
|