pysof 0.2.0__tar.gz → 0.2.1__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.2.0 → pysof-0.2.1}/Cargo.toml +5 -2
- {pysof-0.2.0 → pysof-0.2.1}/PKG-INFO +39 -1
- {pysof-0.2.0 → pysof-0.2.1}/README.md +38 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhir/Cargo.toml +3 -3
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhir-macro/Cargo.toml +1 -1
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/Cargo.toml +2 -2
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/evaluator.rs +19 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/Cargo.toml +5 -2
- {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/README.md +38 -0
- pysof-0.2.1/crates/pysof/python-tests/test_remote_resolve.py +141 -0
- {pysof-0.2.0 → pysof-0.2.1/crates/pysof}/src/lib.rs +333 -2
- {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/src/pysof/__init__.py +131 -0
- {pysof-0.2.0 → pysof-0.2.1/crates/pysof}/src/pysof/_pysof.pyi +42 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/Cargo.toml +13 -3
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/src/cli.rs +91 -17
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/src/handlers.rs +21 -6
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/src/lib.rs +533 -157
- pysof-0.2.1/crates/sof/src/reference_collector.rs +185 -0
- pysof-0.2.1/crates/sof/src/remote_fetch.rs +369 -0
- pysof-0.2.1/crates/sof/src/remote_resolver.rs +856 -0
- pysof-0.2.1/crates/sof/tests/resolve_remote_tests.rs +417 -0
- pysof-0.2.1/crates/sof/tests/resolve_tests.rs +304 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/run_foreach_tests.rs +9 -3
- pysof-0.2.1/crates/sof/tests/sql-on-fhir-v2/README.md +60 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/sql-on-fhir-v2/tests/constant_types.json +12 -9
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/sql-on-fhir-v2/tests/fhirpath.json +5 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/sql-on-fhir-v2/tests/fn_boundary.json +3 -2
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/sql-on-fhir-v2/tests/fn_extension.json +1 -2
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/sql-on-fhir-v2/tests/fn_reference_keys.json +2 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/sql-on-fhir-v2/tests/repeat.json +2 -0
- pysof-0.2.1/crates/sof/tests/sql-on-fhir-v2/tests/row_index.json +700 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/sql-on-fhir-v2/tests/where.json +4 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/sql_on_fhir_tests.rs +26 -8
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/test_base64_binary_constant.rs +4 -2
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/test_runner_integration.rs +22 -7
- {pysof-0.2.0/crates/pysof → pysof-0.2.1}/src/lib.rs +333 -2
- {pysof-0.2.0 → pysof-0.2.1}/src/pysof/__init__.py +131 -0
- {pysof-0.2.0/crates/pysof → pysof-0.2.1}/src/pysof/_pysof.pyi +42 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhir/README.md +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhir/build.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhir/src/compartment_expressions/mod.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhir/src/compartment_expressions/r4.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhir/src/compartment_expressions/r4b.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhir/src/compartment_expressions/r5.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhir/src/compartment_expressions/r6.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhir/src/lib.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhir/src/parameters.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhir/src/r4.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhir/src/r4b.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhir/src/r5.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhir/src/r6.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhir/src/r6.rs.template +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhir/src/search/errors.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhir/src/search/loader.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhir/src/search/mod.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhir/src/search/registry.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhir/src/search/types.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhir/tests/integer_string_integration.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhir/tests/simple_null_test.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhir/tests/test_contained_stack.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhir-macro/README.md +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhir-macro/src/lib.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/PRECISION_LIMITATION.md +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/README.md +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/benches/cli_benches.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/benches/evaluator_benches.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/benches/parser_benches.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/benches/server_benches.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/examples/test_ucum.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/grammar/fhirpath.g4 +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/server-api.md +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/aggregate_function.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/aggregate_math_functions.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/bin/fhirpath-cli.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/bin/fhirpath-server.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/boolean_functions.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/boundary_functions.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/cli.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/collection_functions.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/collection_navigation.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/contains_function.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/conversion_functions.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/date_operation.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/datetime_impl.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/debug_trace.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/distinct_functions.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/error.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/extension_function.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/fhir_type_hierarchy.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/format_functions.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/handlers.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/interval_functions.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/json_utils.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/lib.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/long_conversion.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/models.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/not_function.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/parse_debug.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/parser.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/polymorphic_access.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/reference_key_functions.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/repeat_all_function.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/repeat_function.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/resolve_function.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/resource_type.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/server.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/set_operations.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/subset_functions.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/terminology_client.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/terminology_functions.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/trace_function.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/type_function.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/type_inference.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/ucum.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/all_function_tests.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/boundary_debug_tests.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/boundary_function_integration_tests.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/comment_test.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/common/context.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/common/mod.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/common/parser.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/common/runner.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/context_trace_test.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/data/r4/input/observation-example.json +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/data/r4/input/observation-example.xml +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/data/r4/input/patient-example.json +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/data/r4/input/patient-example.xml +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/data/r4/input/questionnaire-example.json +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/data/r4/input/questionnaire-example.xml +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/data/r4/input/valueset-example-expansion.json +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/data/r4/input/valueset-example-expansion.xml +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/data/r4/tests-fhir-r4.xml +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/data/r5/input/appointment-examplereq.json +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/data/r5/input/ccda.json +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/data/r5/input/codesystem-example.json +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/data/r5/input/conceptmap-example.json +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/data/r5/input/diagnosticreport-eric.json +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/data/r5/input/explanationofbenefit-example.json +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/data/r5/input/observation-example.json +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/data/r5/input/observation-example.xml +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/data/r5/input/parameters-example-types.json +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/data/r5/input/patient-container-example.json +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/data/r5/input/patient-example-name.json +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/data/r5/input/patient-example-period.json +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/data/r5/input/patient-example.json +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/data/r5/input/patient-name-extensions.json +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/data/r5/input/questionnaire-example.json +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/data/r5/input/valueset-example-expansion.json +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/data/r5/known-test-failures.json +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/data/r5/tests-fhir-r5.xml +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/data/testSchema.xsd +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/date_operation_tests.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/datetime_boundary_tests.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/debug_datetime_boundary.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/debug_string_boundary_tests.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/define_variable_test.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/enhanced_variable_tests.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/evaluator_tests.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/extension_tests.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/fhir_boundary_tests.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/http_compression.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/is_as_method_tests.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/join_function_test.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/oftype_datetime_tests.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/parse_debug_test.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/parser_tests.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/polymorphic_r4_tests.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/polymorphic_tests.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/precision_tests.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/primitive_extension_tests.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/r4_tests.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/r5_tests.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/reference_key_debug.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/test_boundary_zero.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/trace_api_test.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/trace_tests.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/tree_navigation_tests.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/truncate_tests.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/type_operation_tests.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/type_preservation_integration_test.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/type_reflection_tests.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/unicode_scalar_value_tests.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/uri_type_test.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/uuid_type_preservation_test.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath-support/Cargo.toml +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath-support/README.md +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath-support/src/lib.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath-support/src/type_info.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/.gitignore +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/Cargo.lock +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/Makefile +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/PYPI_CHECKLIST.md +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/WHEEL_BUILDING.md +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/multithreading_example.py +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/python-tests/__init__.py +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/python-tests/test_content_types.py +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/python-tests/test_core_functions.py +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/python-tests/test_error_handling.py +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/python-tests/test_fhir_versions.py +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/python-tests/test_import.py +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/python-tests/test_package_metadata.py +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/python-tests/test_source_errors.py +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/scripts/build-wheels.py +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/src/pysof/py.typed +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/test_multithreading.py +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/tests/integration/content_types.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/tests/integration/error_handling.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/tests/integration/fhir_versions.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/tests/integration/mod.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/tests/integration.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/tests/lib_coverage_tests.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/tests/lib_tests.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/tests/multithreading_integration.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/tests/threading_test.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/uv.lock +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/serde-support/Cargo.toml +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/serde-support/src/lib.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/README.md +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/benches/parallel_processing_bench.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/src/compartment.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/src/constants.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/src/data_source.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/src/error.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/src/fhir_format.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/src/mod.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/src/models.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/src/params.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/src/parquet_schema.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/src/parquet_zip.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/src/server.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/src/sqlquery/bind.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/src/sqlquery/engine.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/src/sqlquery/library.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/src/sqlquery/mod.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/src/sqlquery/output.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/src/sqlquery/params.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/src/traits.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/common/mod.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/debug_boolean_test.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/debug_column_ordering.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/debug_datetime_instant_constants.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/debug_datetime_type_info.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/debug_enum_conversion.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/debug_evaluation_result_conversion.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/debug_extension_function.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/debug_extension_macro_fix.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/debug_extension_simple.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/debug_fhir_resource_structure.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/debug_foreach_combinations.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/debug_inequality.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/debug_instant_constant.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/debug_instant_type_info.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/debug_raw_resource.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/debug_reference_key_types.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/extension_debug_test.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/foreach_test.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/multiselect_test.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/server_tests.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/sql-on-fhir-v2/tests/basic.json +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/sql-on-fhir-v2/tests/collection.json +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/sql-on-fhir-v2/tests/combinations.json +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/sql-on-fhir-v2/tests/constant.json +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/sql-on-fhir-v2/tests/fhirpath_numbers.json +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/sql-on-fhir-v2/tests/fn_empty.json +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/sql-on-fhir-v2/tests/fn_first.json +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/sql-on-fhir-v2/tests/fn_join.json +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/sql-on-fhir-v2/tests/fn_oftype.json +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/sql-on-fhir-v2/tests/foreach.json +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/sql-on-fhir-v2/tests/logic.json +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/sql-on-fhir-v2/tests/union.json +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/sql-on-fhir-v2/tests/validate.json +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/sql-on-fhir-v2/tests/view_resource.json +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/test_boolean_constant_debug.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/test_boolean_constant_debug2.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/test_boolean_constant_debug3.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/test_boolean_validation.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/test_chunked_processing.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/test_cli_file_source.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/test_csv_quote_handling.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/test_extension_fix_verification.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/test_extension_value_access.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/test_format_parameter_body.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/test_header_parameter_body.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/test_limit_parameter_body.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/test_ndjson_input.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/test_parallel_working.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/test_parameter_validation.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/test_parquet_export.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/test_parquet_large_dataset.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/test_parquet_server_options.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/test_patient_reference_formats.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/test_query_parameter_combinations.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/test_run_operation_parameters.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/test_shortened_format_names.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/test_where_clause_validation.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/test_x_ndjson_support.rs +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/pyproject.toml +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/src/pysof/_pysof.cpython-311-darwin.so +0 -0
- {pysof-0.2.0 → pysof-0.2.1}/src/pysof/py.typed +0 -0
|
@@ -17,13 +17,16 @@ crate-type = ["cdylib"]
|
|
|
17
17
|
|
|
18
18
|
[dependencies]
|
|
19
19
|
pyo3 = { version = ">=0.29", features = ["extension-module", "generate-import-lib"] }
|
|
20
|
-
helios-sof = { path = "../sof", version = "0.2.
|
|
21
|
-
helios-fhir = { path = "../fhir", version = "0.2.
|
|
20
|
+
helios-sof = { path = "../sof", version = "0.2.1", default-features = false }
|
|
21
|
+
helios-fhir = { path = "../fhir", version = "0.2.1", default-features = false }
|
|
22
22
|
serde = { workspace = true }
|
|
23
23
|
serde_json = { workspace = true }
|
|
24
24
|
chrono = { version = "0.4", features = ["serde"] }
|
|
25
25
|
pythonize = "0.29"
|
|
26
26
|
csv = "1.3"
|
|
27
|
+
# Drives helios-sof's async remote-resolve functions from the synchronous
|
|
28
|
+
# PyO3 entry points via a current-thread runtime.
|
|
29
|
+
tokio = { version = "1", default-features = false, features = ["rt", "net", "time"] }
|
|
27
30
|
|
|
28
31
|
[features]
|
|
29
32
|
default = ["R4"]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pysof
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Classifier: Programming Language :: Python :: 3
|
|
5
5
|
Classifier: Programming Language :: Python :: 3.10
|
|
6
6
|
Classifier: Programming Language :: Python :: 3.11
|
|
@@ -176,6 +176,44 @@ result = pysof.run_view_definition_with_options(
|
|
|
176
176
|
)
|
|
177
177
|
```
|
|
178
178
|
|
|
179
|
+
### Remote `resolve()` (Trusted Servers)
|
|
180
|
+
|
|
181
|
+
`resolve()` dereferences references against the input bundle by default. You can
|
|
182
|
+
optionally let it fetch references that point at **explicitly trusted** FHIR
|
|
183
|
+
servers and fold them into the resolution pool before rows are generated. This is
|
|
184
|
+
**off by default** and gated by a strict allowlist (matching scheme + host + port
|
|
185
|
+
+ path-prefix; private/loopback addresses are blocked unless opted in).
|
|
186
|
+
|
|
187
|
+
```python
|
|
188
|
+
import pysof
|
|
189
|
+
|
|
190
|
+
config = pysof.RemoteResolveConfig(
|
|
191
|
+
["https://fhir.example.org/r4"], # trusted base URLs (allowlist)
|
|
192
|
+
max_fetches=256, # per-run/-stream fetch cap
|
|
193
|
+
max_depth=1, # chained-reference rounds
|
|
194
|
+
allow_private_addresses=False, # allow internal LBs (e.g. Traefik) by hostname
|
|
195
|
+
bearer_tokens={"fhir.example.org": "TOKEN"}, # optional per-host auth
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
# Or build it from SOF_RESOLVE_* environment variables:
|
|
199
|
+
# config = pysof.RemoteResolveConfig.from_env()
|
|
200
|
+
|
|
201
|
+
result = pysof.run_view_definition_remote(
|
|
202
|
+
view_definition, bundle, "json", config, fhir_version="R4"
|
|
203
|
+
)
|
|
204
|
+
|
|
205
|
+
# Streaming NDJSON with remote resolve() (one shared cache across chunks):
|
|
206
|
+
stats = pysof.process_ndjson_to_file_remote(
|
|
207
|
+
view_definition, "input.ndjson", "output.json", "ndjson", config, chunk_size=1000
|
|
208
|
+
)
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
When `config.is_active()` is `False` (disabled or empty allowlist) these behave
|
|
212
|
+
exactly like their non-remote counterparts. Enabling remote resolution makes
|
|
213
|
+
output depend on remote server state at run time. See the
|
|
214
|
+
[SQL-on-FHIR guide](../../book/src/ch06-sql-on-fhir.md) for the full security
|
|
215
|
+
model and configuration reference.
|
|
216
|
+
|
|
179
217
|
### Utility Functions
|
|
180
218
|
|
|
181
219
|
```python
|
|
@@ -147,6 +147,44 @@ result = pysof.run_view_definition_with_options(
|
|
|
147
147
|
)
|
|
148
148
|
```
|
|
149
149
|
|
|
150
|
+
### Remote `resolve()` (Trusted Servers)
|
|
151
|
+
|
|
152
|
+
`resolve()` dereferences references against the input bundle by default. You can
|
|
153
|
+
optionally let it fetch references that point at **explicitly trusted** FHIR
|
|
154
|
+
servers and fold them into the resolution pool before rows are generated. This is
|
|
155
|
+
**off by default** and gated by a strict allowlist (matching scheme + host + port
|
|
156
|
+
+ path-prefix; private/loopback addresses are blocked unless opted in).
|
|
157
|
+
|
|
158
|
+
```python
|
|
159
|
+
import pysof
|
|
160
|
+
|
|
161
|
+
config = pysof.RemoteResolveConfig(
|
|
162
|
+
["https://fhir.example.org/r4"], # trusted base URLs (allowlist)
|
|
163
|
+
max_fetches=256, # per-run/-stream fetch cap
|
|
164
|
+
max_depth=1, # chained-reference rounds
|
|
165
|
+
allow_private_addresses=False, # allow internal LBs (e.g. Traefik) by hostname
|
|
166
|
+
bearer_tokens={"fhir.example.org": "TOKEN"}, # optional per-host auth
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
# Or build it from SOF_RESOLVE_* environment variables:
|
|
170
|
+
# config = pysof.RemoteResolveConfig.from_env()
|
|
171
|
+
|
|
172
|
+
result = pysof.run_view_definition_remote(
|
|
173
|
+
view_definition, bundle, "json", config, fhir_version="R4"
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
# Streaming NDJSON with remote resolve() (one shared cache across chunks):
|
|
177
|
+
stats = pysof.process_ndjson_to_file_remote(
|
|
178
|
+
view_definition, "input.ndjson", "output.json", "ndjson", config, chunk_size=1000
|
|
179
|
+
)
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
When `config.is_active()` is `False` (disabled or empty allowlist) these behave
|
|
183
|
+
exactly like their non-remote counterparts. Enabling remote resolution makes
|
|
184
|
+
output depend on remote server state at run time. See the
|
|
185
|
+
[SQL-on-FHIR guide](../../book/src/ch06-sql-on-fhir.md) for the full security
|
|
186
|
+
model and configuration reference.
|
|
187
|
+
|
|
150
188
|
### Utility Functions
|
|
151
189
|
|
|
152
190
|
```python
|
|
@@ -24,9 +24,9 @@ xml = ["helios-serde-support/xml"]
|
|
|
24
24
|
serde = { workspace = true }
|
|
25
25
|
serde_json = { workspace = true, features = ["raw_value"] }
|
|
26
26
|
clap = { version = "4.0", features = ["derive"] }
|
|
27
|
-
helios-fhir-macro = { path = "../fhir-macro", version = "0.2.
|
|
28
|
-
helios-serde-support = { path = "../serde-support", version = "0.2.
|
|
29
|
-
helios-fhirpath-support = { path = "../fhirpath-support", version = "0.2.
|
|
27
|
+
helios-fhir-macro = { path = "../fhir-macro", version = "0.2.1" }
|
|
28
|
+
helios-serde-support = { path = "../serde-support", version = "0.2.1" }
|
|
29
|
+
helios-fhirpath-support = { path = "../fhirpath-support", version = "0.2.1" }
|
|
30
30
|
time = "0.3"
|
|
31
31
|
chrono = { workspace = true }
|
|
32
32
|
# Re-add serde-with-arbitrary-precision, keep macros
|
|
@@ -20,4 +20,4 @@ proc-macro2 = "1.0"
|
|
|
20
20
|
serde = { workspace = true }
|
|
21
21
|
serde_json = { workspace = true }
|
|
22
22
|
heck = "0.5" # For case conversion
|
|
23
|
-
helios-fhirpath-support = { path = "../fhirpath-support", version = "0.2.
|
|
23
|
+
helios-fhirpath-support = { path = "../fhirpath-support", version = "0.2.1" }
|
|
@@ -18,8 +18,8 @@ R5 = ["helios-fhir/R5"]
|
|
|
18
18
|
R6 = ["helios-fhir/R6"]
|
|
19
19
|
|
|
20
20
|
[dependencies]
|
|
21
|
-
helios-fhir = { path = "../fhir", version = "0.2.
|
|
22
|
-
helios-fhirpath-support = { path = "../fhirpath-support", version = "0.2.
|
|
21
|
+
helios-fhir = { path = "../fhir", version = "0.2.1", default-features = false }
|
|
22
|
+
helios-fhirpath-support = { path = "../fhirpath-support", version = "0.2.1" }
|
|
23
23
|
chumsky = "0.10"
|
|
24
24
|
roxmltree = "0.20"
|
|
25
25
|
chrono = { workspace = true } # For date/time parsing and functions
|
|
@@ -423,6 +423,25 @@ impl EvaluationContext {
|
|
|
423
423
|
.push(resource);
|
|
424
424
|
}
|
|
425
425
|
|
|
426
|
+
/// Replaces the pool of resources available for resolution.
|
|
427
|
+
///
|
|
428
|
+
/// This swaps the (`Arc`-shared) set of resources that `resolve()` searches —
|
|
429
|
+
/// see [`crate::resolve_function`] — **without** changing `this`, the FHIR
|
|
430
|
+
/// version, or `%context` / `%resource` / `%rootResource` semantics. Those all
|
|
431
|
+
/// derive from `this` (with `resources[0]` used only as a fallback when `this`
|
|
432
|
+
/// is `None`), so callers that have already set `this` to the resource under
|
|
433
|
+
/// evaluation can widen the resolution pool freely.
|
|
434
|
+
///
|
|
435
|
+
/// SQL-on-FHIR uses this to expose the *entire input bundle* so that
|
|
436
|
+
/// `Reference.resolve()` can reach sibling resources elsewhere in the bundle,
|
|
437
|
+
/// not just the resource currently being processed and its `contained`
|
|
438
|
+
/// children. Sharing via `Arc` keeps this cheap across the many per-resource
|
|
439
|
+
/// (and per-iteration) contexts SOF creates, and it survives `Clone` into
|
|
440
|
+
/// lambda/child contexts.
|
|
441
|
+
pub fn set_resolution_scope(&mut self, resources: Arc<Vec<FhirResource>>) {
|
|
442
|
+
self.resources = resources;
|
|
443
|
+
}
|
|
444
|
+
|
|
426
445
|
/// Sets a variable in the context to a string value
|
|
427
446
|
///
|
|
428
447
|
/// This method is provided for backward compatibility with code that expects
|
|
@@ -18,13 +18,16 @@ crate-type = ["cdylib"]
|
|
|
18
18
|
|
|
19
19
|
[dependencies]
|
|
20
20
|
pyo3 = { version = ">=0.29", features = ["extension-module", "generate-import-lib"] }
|
|
21
|
-
helios-sof = { path = "../sof", version = "0.2.
|
|
22
|
-
helios-fhir = { path = "../fhir", version = "0.2.
|
|
21
|
+
helios-sof = { path = "../sof", version = "0.2.1", default-features = false }
|
|
22
|
+
helios-fhir = { path = "../fhir", version = "0.2.1", default-features = false }
|
|
23
23
|
serde = { workspace = true }
|
|
24
24
|
serde_json = { workspace = true }
|
|
25
25
|
chrono = { version = "0.4", features = ["serde"] }
|
|
26
26
|
pythonize = "0.29"
|
|
27
27
|
csv = "1.3"
|
|
28
|
+
# Drives helios-sof's async remote-resolve functions from the synchronous
|
|
29
|
+
# PyO3 entry points via a current-thread runtime.
|
|
30
|
+
tokio = { version = "1", default-features = false, features = ["rt", "net", "time"] }
|
|
28
31
|
|
|
29
32
|
[features]
|
|
30
33
|
default = ["R4"]
|
|
@@ -147,6 +147,44 @@ result = pysof.run_view_definition_with_options(
|
|
|
147
147
|
)
|
|
148
148
|
```
|
|
149
149
|
|
|
150
|
+
### Remote `resolve()` (Trusted Servers)
|
|
151
|
+
|
|
152
|
+
`resolve()` dereferences references against the input bundle by default. You can
|
|
153
|
+
optionally let it fetch references that point at **explicitly trusted** FHIR
|
|
154
|
+
servers and fold them into the resolution pool before rows are generated. This is
|
|
155
|
+
**off by default** and gated by a strict allowlist (matching scheme + host + port
|
|
156
|
+
+ path-prefix; private/loopback addresses are blocked unless opted in).
|
|
157
|
+
|
|
158
|
+
```python
|
|
159
|
+
import pysof
|
|
160
|
+
|
|
161
|
+
config = pysof.RemoteResolveConfig(
|
|
162
|
+
["https://fhir.example.org/r4"], # trusted base URLs (allowlist)
|
|
163
|
+
max_fetches=256, # per-run/-stream fetch cap
|
|
164
|
+
max_depth=1, # chained-reference rounds
|
|
165
|
+
allow_private_addresses=False, # allow internal LBs (e.g. Traefik) by hostname
|
|
166
|
+
bearer_tokens={"fhir.example.org": "TOKEN"}, # optional per-host auth
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
# Or build it from SOF_RESOLVE_* environment variables:
|
|
170
|
+
# config = pysof.RemoteResolveConfig.from_env()
|
|
171
|
+
|
|
172
|
+
result = pysof.run_view_definition_remote(
|
|
173
|
+
view_definition, bundle, "json", config, fhir_version="R4"
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
# Streaming NDJSON with remote resolve() (one shared cache across chunks):
|
|
177
|
+
stats = pysof.process_ndjson_to_file_remote(
|
|
178
|
+
view_definition, "input.ndjson", "output.json", "ndjson", config, chunk_size=1000
|
|
179
|
+
)
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
When `config.is_active()` is `False` (disabled or empty allowlist) these behave
|
|
183
|
+
exactly like their non-remote counterparts. Enabling remote resolution makes
|
|
184
|
+
output depend on remote server state at run time. See the
|
|
185
|
+
[SQL-on-FHIR guide](../../book/src/ch06-sql-on-fhir.md) for the full security
|
|
186
|
+
model and configuration reference.
|
|
187
|
+
|
|
150
188
|
### Utility Functions
|
|
151
189
|
|
|
152
190
|
```python
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
"""Tests for the remote resolve() Python bindings.
|
|
2
|
+
|
|
3
|
+
These exercise the RemoteResolveConfig class and the *_remote entry points
|
|
4
|
+
without requiring network access: an *inactive* config (no allowlist) drives the
|
|
5
|
+
same async pipeline as the active one but performs no fetches, so it still does
|
|
6
|
+
bundle-level (in-scope) resolution. End-to-end remote fetching against a server is
|
|
7
|
+
covered by the Rust integration tests (crates/sof/tests/resolve_remote_tests.rs).
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import json
|
|
11
|
+
from typing import Any, Dict
|
|
12
|
+
|
|
13
|
+
import pysof
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def encounter_with_subject_view() -> Dict[str, Any]:
|
|
17
|
+
return {
|
|
18
|
+
"resourceType": "ViewDefinition",
|
|
19
|
+
"status": "active",
|
|
20
|
+
"resource": "Encounter",
|
|
21
|
+
"select": [
|
|
22
|
+
{"column": [{"name": "encounter_id", "path": "id"}]},
|
|
23
|
+
{
|
|
24
|
+
"forEach": "subject.resolve()",
|
|
25
|
+
"column": [
|
|
26
|
+
{"name": "patient_id", "path": "id"},
|
|
27
|
+
{"name": "patient_family", "path": "name.family"},
|
|
28
|
+
],
|
|
29
|
+
},
|
|
30
|
+
],
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def bundle_with_sibling_patient() -> Dict[str, Any]:
|
|
35
|
+
return {
|
|
36
|
+
"resourceType": "Bundle",
|
|
37
|
+
"type": "collection",
|
|
38
|
+
"entry": [
|
|
39
|
+
{
|
|
40
|
+
"resource": {
|
|
41
|
+
"resourceType": "Patient",
|
|
42
|
+
"id": "pat-1",
|
|
43
|
+
"name": [{"family": "Sibling"}],
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"resource": {
|
|
48
|
+
"resourceType": "Encounter",
|
|
49
|
+
"id": "enc-1",
|
|
50
|
+
"status": "finished",
|
|
51
|
+
"subject": {"reference": "Patient/pat-1"},
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
],
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def test_remote_symbols_exported() -> None:
|
|
59
|
+
for name in [
|
|
60
|
+
"RemoteResolveConfig",
|
|
61
|
+
"run_view_definition_remote",
|
|
62
|
+
"process_ndjson_to_file_remote",
|
|
63
|
+
]:
|
|
64
|
+
assert name in pysof.__all__
|
|
65
|
+
assert hasattr(pysof, name)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def test_remote_resolve_config_construction() -> None:
|
|
69
|
+
cfg = pysof.RemoteResolveConfig(
|
|
70
|
+
["https://fhir.example.org/r4"],
|
|
71
|
+
max_fetches=10,
|
|
72
|
+
max_depth=2,
|
|
73
|
+
allow_private_addresses=True,
|
|
74
|
+
bearer_tokens={"fhir.example.org": "tok"},
|
|
75
|
+
)
|
|
76
|
+
assert cfg.is_active() is True # enabled (default) + non-empty allowlist
|
|
77
|
+
|
|
78
|
+
# Disabled or empty allowlist => inactive.
|
|
79
|
+
assert pysof.RemoteResolveConfig([]).is_active() is False
|
|
80
|
+
assert (
|
|
81
|
+
pysof.RemoteResolveConfig(
|
|
82
|
+
["https://fhir.example.org/r4"], enabled=False
|
|
83
|
+
).is_active()
|
|
84
|
+
is False
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
# from_env() is constructible and inactive by default (no env set).
|
|
88
|
+
assert isinstance(pysof.RemoteResolveConfig.from_env(), pysof.RemoteResolveConfig)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def test_run_view_definition_remote_inactive_does_in_bundle_resolution() -> None:
|
|
92
|
+
# With an inactive remote config (no allowlist), no fetch happens, but the
|
|
93
|
+
# bundle-level resolution pool still resolves Encounter.subject to the sibling
|
|
94
|
+
# Patient in the same bundle.
|
|
95
|
+
cfg = pysof.RemoteResolveConfig([]) # inactive
|
|
96
|
+
result = pysof.run_view_definition_remote(
|
|
97
|
+
encounter_with_subject_view(),
|
|
98
|
+
bundle_with_sibling_patient(),
|
|
99
|
+
"json",
|
|
100
|
+
cfg,
|
|
101
|
+
)
|
|
102
|
+
rows = json.loads(result)
|
|
103
|
+
assert len(rows) == 1
|
|
104
|
+
assert rows[0]["encounter_id"] == "enc-1"
|
|
105
|
+
assert rows[0]["patient_id"] == "pat-1"
|
|
106
|
+
assert rows[0]["patient_family"] == "Sibling"
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def test_process_ndjson_to_file_remote_inactive(tmp_path: Any) -> None:
|
|
110
|
+
# Two Encounters referencing patients that are not in the stream; with an
|
|
111
|
+
# inactive config nothing is fetched, so the resolved columns are null, but
|
|
112
|
+
# the call succeeds and returns stats.
|
|
113
|
+
input_path = tmp_path / "in.ndjson"
|
|
114
|
+
output_path = tmp_path / "out.json"
|
|
115
|
+
lines = [
|
|
116
|
+
json.dumps(
|
|
117
|
+
{
|
|
118
|
+
"resourceType": "Encounter",
|
|
119
|
+
"id": f"enc-{i}",
|
|
120
|
+
"status": "finished",
|
|
121
|
+
"subject": {"reference": f"Patient/p{i}"},
|
|
122
|
+
}
|
|
123
|
+
)
|
|
124
|
+
for i in range(2)
|
|
125
|
+
]
|
|
126
|
+
input_path.write_text("\n".join(lines))
|
|
127
|
+
|
|
128
|
+
cfg = pysof.RemoteResolveConfig([]) # inactive
|
|
129
|
+
stats = pysof.process_ndjson_to_file_remote(
|
|
130
|
+
encounter_with_subject_view(),
|
|
131
|
+
str(input_path),
|
|
132
|
+
str(output_path),
|
|
133
|
+
"json",
|
|
134
|
+
cfg,
|
|
135
|
+
chunk_size=1,
|
|
136
|
+
)
|
|
137
|
+
assert stats["resources_processed"] == 2
|
|
138
|
+
rows = json.loads(output_path.read_text())
|
|
139
|
+
assert len(rows) == 2
|
|
140
|
+
for row in rows:
|
|
141
|
+
assert row["patient_family"] is None
|