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.
Files changed (299) hide show
  1. {pysof-0.2.0 → pysof-0.2.1}/Cargo.toml +5 -2
  2. {pysof-0.2.0 → pysof-0.2.1}/PKG-INFO +39 -1
  3. {pysof-0.2.0 → pysof-0.2.1}/README.md +38 -0
  4. {pysof-0.2.0 → pysof-0.2.1}/crates/fhir/Cargo.toml +3 -3
  5. {pysof-0.2.0 → pysof-0.2.1}/crates/fhir-macro/Cargo.toml +1 -1
  6. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/Cargo.toml +2 -2
  7. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/evaluator.rs +19 -0
  8. {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/Cargo.toml +5 -2
  9. {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/README.md +38 -0
  10. pysof-0.2.1/crates/pysof/python-tests/test_remote_resolve.py +141 -0
  11. {pysof-0.2.0 → pysof-0.2.1/crates/pysof}/src/lib.rs +333 -2
  12. {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/src/pysof/__init__.py +131 -0
  13. {pysof-0.2.0 → pysof-0.2.1/crates/pysof}/src/pysof/_pysof.pyi +42 -0
  14. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/Cargo.toml +13 -3
  15. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/src/cli.rs +91 -17
  16. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/src/handlers.rs +21 -6
  17. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/src/lib.rs +533 -157
  18. pysof-0.2.1/crates/sof/src/reference_collector.rs +185 -0
  19. pysof-0.2.1/crates/sof/src/remote_fetch.rs +369 -0
  20. pysof-0.2.1/crates/sof/src/remote_resolver.rs +856 -0
  21. pysof-0.2.1/crates/sof/tests/resolve_remote_tests.rs +417 -0
  22. pysof-0.2.1/crates/sof/tests/resolve_tests.rs +304 -0
  23. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/run_foreach_tests.rs +9 -3
  24. pysof-0.2.1/crates/sof/tests/sql-on-fhir-v2/README.md +60 -0
  25. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/sql-on-fhir-v2/tests/constant_types.json +12 -9
  26. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/sql-on-fhir-v2/tests/fhirpath.json +5 -0
  27. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/sql-on-fhir-v2/tests/fn_boundary.json +3 -2
  28. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/sql-on-fhir-v2/tests/fn_extension.json +1 -2
  29. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/sql-on-fhir-v2/tests/fn_reference_keys.json +2 -0
  30. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/sql-on-fhir-v2/tests/repeat.json +2 -0
  31. pysof-0.2.1/crates/sof/tests/sql-on-fhir-v2/tests/row_index.json +700 -0
  32. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/sql-on-fhir-v2/tests/where.json +4 -0
  33. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/sql_on_fhir_tests.rs +26 -8
  34. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/test_base64_binary_constant.rs +4 -2
  35. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/test_runner_integration.rs +22 -7
  36. {pysof-0.2.0/crates/pysof → pysof-0.2.1}/src/lib.rs +333 -2
  37. {pysof-0.2.0 → pysof-0.2.1}/src/pysof/__init__.py +131 -0
  38. {pysof-0.2.0/crates/pysof → pysof-0.2.1}/src/pysof/_pysof.pyi +42 -0
  39. {pysof-0.2.0 → pysof-0.2.1}/crates/fhir/README.md +0 -0
  40. {pysof-0.2.0 → pysof-0.2.1}/crates/fhir/build.rs +0 -0
  41. {pysof-0.2.0 → pysof-0.2.1}/crates/fhir/src/compartment_expressions/mod.rs +0 -0
  42. {pysof-0.2.0 → pysof-0.2.1}/crates/fhir/src/compartment_expressions/r4.rs +0 -0
  43. {pysof-0.2.0 → pysof-0.2.1}/crates/fhir/src/compartment_expressions/r4b.rs +0 -0
  44. {pysof-0.2.0 → pysof-0.2.1}/crates/fhir/src/compartment_expressions/r5.rs +0 -0
  45. {pysof-0.2.0 → pysof-0.2.1}/crates/fhir/src/compartment_expressions/r6.rs +0 -0
  46. {pysof-0.2.0 → pysof-0.2.1}/crates/fhir/src/lib.rs +0 -0
  47. {pysof-0.2.0 → pysof-0.2.1}/crates/fhir/src/parameters.rs +0 -0
  48. {pysof-0.2.0 → pysof-0.2.1}/crates/fhir/src/r4.rs +0 -0
  49. {pysof-0.2.0 → pysof-0.2.1}/crates/fhir/src/r4b.rs +0 -0
  50. {pysof-0.2.0 → pysof-0.2.1}/crates/fhir/src/r5.rs +0 -0
  51. {pysof-0.2.0 → pysof-0.2.1}/crates/fhir/src/r6.rs +0 -0
  52. {pysof-0.2.0 → pysof-0.2.1}/crates/fhir/src/r6.rs.template +0 -0
  53. {pysof-0.2.0 → pysof-0.2.1}/crates/fhir/src/search/errors.rs +0 -0
  54. {pysof-0.2.0 → pysof-0.2.1}/crates/fhir/src/search/loader.rs +0 -0
  55. {pysof-0.2.0 → pysof-0.2.1}/crates/fhir/src/search/mod.rs +0 -0
  56. {pysof-0.2.0 → pysof-0.2.1}/crates/fhir/src/search/registry.rs +0 -0
  57. {pysof-0.2.0 → pysof-0.2.1}/crates/fhir/src/search/types.rs +0 -0
  58. {pysof-0.2.0 → pysof-0.2.1}/crates/fhir/tests/integer_string_integration.rs +0 -0
  59. {pysof-0.2.0 → pysof-0.2.1}/crates/fhir/tests/simple_null_test.rs +0 -0
  60. {pysof-0.2.0 → pysof-0.2.1}/crates/fhir/tests/test_contained_stack.rs +0 -0
  61. {pysof-0.2.0 → pysof-0.2.1}/crates/fhir-macro/README.md +0 -0
  62. {pysof-0.2.0 → pysof-0.2.1}/crates/fhir-macro/src/lib.rs +0 -0
  63. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/PRECISION_LIMITATION.md +0 -0
  64. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/README.md +0 -0
  65. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/benches/cli_benches.rs +0 -0
  66. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/benches/evaluator_benches.rs +0 -0
  67. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/benches/parser_benches.rs +0 -0
  68. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/benches/server_benches.rs +0 -0
  69. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/examples/test_ucum.rs +0 -0
  70. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/grammar/fhirpath.g4 +0 -0
  71. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/server-api.md +0 -0
  72. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/aggregate_function.rs +0 -0
  73. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/aggregate_math_functions.rs +0 -0
  74. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/bin/fhirpath-cli.rs +0 -0
  75. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/bin/fhirpath-server.rs +0 -0
  76. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/boolean_functions.rs +0 -0
  77. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/boundary_functions.rs +0 -0
  78. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/cli.rs +0 -0
  79. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/collection_functions.rs +0 -0
  80. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/collection_navigation.rs +0 -0
  81. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/contains_function.rs +0 -0
  82. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/conversion_functions.rs +0 -0
  83. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/date_operation.rs +0 -0
  84. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/datetime_impl.rs +0 -0
  85. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/debug_trace.rs +0 -0
  86. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/distinct_functions.rs +0 -0
  87. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/error.rs +0 -0
  88. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/extension_function.rs +0 -0
  89. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/fhir_type_hierarchy.rs +0 -0
  90. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/format_functions.rs +0 -0
  91. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/handlers.rs +0 -0
  92. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/interval_functions.rs +0 -0
  93. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/json_utils.rs +0 -0
  94. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/lib.rs +0 -0
  95. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/long_conversion.rs +0 -0
  96. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/models.rs +0 -0
  97. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/not_function.rs +0 -0
  98. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/parse_debug.rs +0 -0
  99. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/parser.rs +0 -0
  100. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/polymorphic_access.rs +0 -0
  101. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/reference_key_functions.rs +0 -0
  102. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/repeat_all_function.rs +0 -0
  103. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/repeat_function.rs +0 -0
  104. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/resolve_function.rs +0 -0
  105. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/resource_type.rs +0 -0
  106. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/server.rs +0 -0
  107. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/set_operations.rs +0 -0
  108. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/subset_functions.rs +0 -0
  109. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/terminology_client.rs +0 -0
  110. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/terminology_functions.rs +0 -0
  111. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/trace_function.rs +0 -0
  112. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/type_function.rs +0 -0
  113. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/type_inference.rs +0 -0
  114. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/src/ucum.rs +0 -0
  115. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/all_function_tests.rs +0 -0
  116. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/boundary_debug_tests.rs +0 -0
  117. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/boundary_function_integration_tests.rs +0 -0
  118. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/comment_test.rs +0 -0
  119. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/common/context.rs +0 -0
  120. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/common/mod.rs +0 -0
  121. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/common/parser.rs +0 -0
  122. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/common/runner.rs +0 -0
  123. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/context_trace_test.rs +0 -0
  124. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/data/r4/input/observation-example.json +0 -0
  125. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/data/r4/input/observation-example.xml +0 -0
  126. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/data/r4/input/patient-example.json +0 -0
  127. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/data/r4/input/patient-example.xml +0 -0
  128. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/data/r4/input/questionnaire-example.json +0 -0
  129. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/data/r4/input/questionnaire-example.xml +0 -0
  130. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/data/r4/input/valueset-example-expansion.json +0 -0
  131. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/data/r4/input/valueset-example-expansion.xml +0 -0
  132. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/data/r4/tests-fhir-r4.xml +0 -0
  133. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/data/r5/input/appointment-examplereq.json +0 -0
  134. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/data/r5/input/ccda.json +0 -0
  135. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/data/r5/input/codesystem-example.json +0 -0
  136. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/data/r5/input/conceptmap-example.json +0 -0
  137. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/data/r5/input/diagnosticreport-eric.json +0 -0
  138. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/data/r5/input/explanationofbenefit-example.json +0 -0
  139. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/data/r5/input/observation-example.json +0 -0
  140. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/data/r5/input/observation-example.xml +0 -0
  141. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/data/r5/input/parameters-example-types.json +0 -0
  142. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/data/r5/input/patient-container-example.json +0 -0
  143. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/data/r5/input/patient-example-name.json +0 -0
  144. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/data/r5/input/patient-example-period.json +0 -0
  145. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/data/r5/input/patient-example.json +0 -0
  146. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/data/r5/input/patient-name-extensions.json +0 -0
  147. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/data/r5/input/questionnaire-example.json +0 -0
  148. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/data/r5/input/valueset-example-expansion.json +0 -0
  149. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/data/r5/known-test-failures.json +0 -0
  150. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/data/r5/tests-fhir-r5.xml +0 -0
  151. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/data/testSchema.xsd +0 -0
  152. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/date_operation_tests.rs +0 -0
  153. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/datetime_boundary_tests.rs +0 -0
  154. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/debug_datetime_boundary.rs +0 -0
  155. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/debug_string_boundary_tests.rs +0 -0
  156. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/define_variable_test.rs +0 -0
  157. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/enhanced_variable_tests.rs +0 -0
  158. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/evaluator_tests.rs +0 -0
  159. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/extension_tests.rs +0 -0
  160. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/fhir_boundary_tests.rs +0 -0
  161. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/http_compression.rs +0 -0
  162. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/is_as_method_tests.rs +0 -0
  163. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/join_function_test.rs +0 -0
  164. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/oftype_datetime_tests.rs +0 -0
  165. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/parse_debug_test.rs +0 -0
  166. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/parser_tests.rs +0 -0
  167. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/polymorphic_r4_tests.rs +0 -0
  168. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/polymorphic_tests.rs +0 -0
  169. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/precision_tests.rs +0 -0
  170. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/primitive_extension_tests.rs +0 -0
  171. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/r4_tests.rs +0 -0
  172. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/r5_tests.rs +0 -0
  173. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/reference_key_debug.rs +0 -0
  174. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/test_boundary_zero.rs +0 -0
  175. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/trace_api_test.rs +0 -0
  176. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/trace_tests.rs +0 -0
  177. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/tree_navigation_tests.rs +0 -0
  178. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/truncate_tests.rs +0 -0
  179. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/type_operation_tests.rs +0 -0
  180. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/type_preservation_integration_test.rs +0 -0
  181. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/type_reflection_tests.rs +0 -0
  182. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/unicode_scalar_value_tests.rs +0 -0
  183. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/uri_type_test.rs +0 -0
  184. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath/tests/uuid_type_preservation_test.rs +0 -0
  185. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath-support/Cargo.toml +0 -0
  186. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath-support/README.md +0 -0
  187. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath-support/src/lib.rs +0 -0
  188. {pysof-0.2.0 → pysof-0.2.1}/crates/fhirpath-support/src/type_info.rs +0 -0
  189. {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/.gitignore +0 -0
  190. {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/Cargo.lock +0 -0
  191. {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/Makefile +0 -0
  192. {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/PYPI_CHECKLIST.md +0 -0
  193. {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/WHEEL_BUILDING.md +0 -0
  194. {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/multithreading_example.py +0 -0
  195. {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/python-tests/__init__.py +0 -0
  196. {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/python-tests/test_content_types.py +0 -0
  197. {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/python-tests/test_core_functions.py +0 -0
  198. {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/python-tests/test_error_handling.py +0 -0
  199. {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/python-tests/test_fhir_versions.py +0 -0
  200. {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/python-tests/test_import.py +0 -0
  201. {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/python-tests/test_package_metadata.py +0 -0
  202. {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/python-tests/test_source_errors.py +0 -0
  203. {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/scripts/build-wheels.py +0 -0
  204. {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/src/pysof/py.typed +0 -0
  205. {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/test_multithreading.py +0 -0
  206. {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/tests/integration/content_types.rs +0 -0
  207. {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/tests/integration/error_handling.rs +0 -0
  208. {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/tests/integration/fhir_versions.rs +0 -0
  209. {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/tests/integration/mod.rs +0 -0
  210. {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/tests/integration.rs +0 -0
  211. {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/tests/lib_coverage_tests.rs +0 -0
  212. {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/tests/lib_tests.rs +0 -0
  213. {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/tests/multithreading_integration.rs +0 -0
  214. {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/tests/threading_test.rs +0 -0
  215. {pysof-0.2.0 → pysof-0.2.1}/crates/pysof/uv.lock +0 -0
  216. {pysof-0.2.0 → pysof-0.2.1}/crates/serde-support/Cargo.toml +0 -0
  217. {pysof-0.2.0 → pysof-0.2.1}/crates/serde-support/src/lib.rs +0 -0
  218. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/README.md +0 -0
  219. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/benches/parallel_processing_bench.rs +0 -0
  220. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/src/compartment.rs +0 -0
  221. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/src/constants.rs +0 -0
  222. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/src/data_source.rs +0 -0
  223. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/src/error.rs +0 -0
  224. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/src/fhir_format.rs +0 -0
  225. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/src/mod.rs +0 -0
  226. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/src/models.rs +0 -0
  227. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/src/params.rs +0 -0
  228. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/src/parquet_schema.rs +0 -0
  229. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/src/parquet_zip.rs +0 -0
  230. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/src/server.rs +0 -0
  231. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/src/sqlquery/bind.rs +0 -0
  232. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/src/sqlquery/engine.rs +0 -0
  233. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/src/sqlquery/library.rs +0 -0
  234. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/src/sqlquery/mod.rs +0 -0
  235. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/src/sqlquery/output.rs +0 -0
  236. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/src/sqlquery/params.rs +0 -0
  237. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/src/traits.rs +0 -0
  238. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/common/mod.rs +0 -0
  239. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/debug_boolean_test.rs +0 -0
  240. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/debug_column_ordering.rs +0 -0
  241. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/debug_datetime_instant_constants.rs +0 -0
  242. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/debug_datetime_type_info.rs +0 -0
  243. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/debug_enum_conversion.rs +0 -0
  244. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/debug_evaluation_result_conversion.rs +0 -0
  245. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/debug_extension_function.rs +0 -0
  246. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/debug_extension_macro_fix.rs +0 -0
  247. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/debug_extension_simple.rs +0 -0
  248. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/debug_fhir_resource_structure.rs +0 -0
  249. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/debug_foreach_combinations.rs +0 -0
  250. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/debug_inequality.rs +0 -0
  251. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/debug_instant_constant.rs +0 -0
  252. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/debug_instant_type_info.rs +0 -0
  253. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/debug_raw_resource.rs +0 -0
  254. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/debug_reference_key_types.rs +0 -0
  255. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/extension_debug_test.rs +0 -0
  256. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/foreach_test.rs +0 -0
  257. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/multiselect_test.rs +0 -0
  258. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/server_tests.rs +0 -0
  259. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/sql-on-fhir-v2/tests/basic.json +0 -0
  260. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/sql-on-fhir-v2/tests/collection.json +0 -0
  261. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/sql-on-fhir-v2/tests/combinations.json +0 -0
  262. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/sql-on-fhir-v2/tests/constant.json +0 -0
  263. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/sql-on-fhir-v2/tests/fhirpath_numbers.json +0 -0
  264. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/sql-on-fhir-v2/tests/fn_empty.json +0 -0
  265. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/sql-on-fhir-v2/tests/fn_first.json +0 -0
  266. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/sql-on-fhir-v2/tests/fn_join.json +0 -0
  267. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/sql-on-fhir-v2/tests/fn_oftype.json +0 -0
  268. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/sql-on-fhir-v2/tests/foreach.json +0 -0
  269. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/sql-on-fhir-v2/tests/logic.json +0 -0
  270. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/sql-on-fhir-v2/tests/union.json +0 -0
  271. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/sql-on-fhir-v2/tests/validate.json +0 -0
  272. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/sql-on-fhir-v2/tests/view_resource.json +0 -0
  273. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/test_boolean_constant_debug.rs +0 -0
  274. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/test_boolean_constant_debug2.rs +0 -0
  275. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/test_boolean_constant_debug3.rs +0 -0
  276. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/test_boolean_validation.rs +0 -0
  277. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/test_chunked_processing.rs +0 -0
  278. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/test_cli_file_source.rs +0 -0
  279. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/test_csv_quote_handling.rs +0 -0
  280. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/test_extension_fix_verification.rs +0 -0
  281. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/test_extension_value_access.rs +0 -0
  282. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/test_format_parameter_body.rs +0 -0
  283. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/test_header_parameter_body.rs +0 -0
  284. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/test_limit_parameter_body.rs +0 -0
  285. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/test_ndjson_input.rs +0 -0
  286. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/test_parallel_working.rs +0 -0
  287. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/test_parameter_validation.rs +0 -0
  288. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/test_parquet_export.rs +0 -0
  289. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/test_parquet_large_dataset.rs +0 -0
  290. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/test_parquet_server_options.rs +0 -0
  291. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/test_patient_reference_formats.rs +0 -0
  292. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/test_query_parameter_combinations.rs +0 -0
  293. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/test_run_operation_parameters.rs +0 -0
  294. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/test_shortened_format_names.rs +0 -0
  295. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/test_where_clause_validation.rs +0 -0
  296. {pysof-0.2.0 → pysof-0.2.1}/crates/sof/tests/test_x_ndjson_support.rs +0 -0
  297. {pysof-0.2.0 → pysof-0.2.1}/pyproject.toml +0 -0
  298. {pysof-0.2.0 → pysof-0.2.1}/src/pysof/_pysof.cpython-311-darwin.so +0 -0
  299. {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.0", default-features = false }
21
- helios-fhir = { path = "../fhir", version = "0.2.0", default-features = false }
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.0
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.0" }
28
- helios-serde-support = { path = "../serde-support", version = "0.2.0" }
29
- helios-fhirpath-support = { path = "../fhirpath-support", version = "0.2.0" }
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.0" }
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.0", default-features = false }
22
- helios-fhirpath-support = { path = "../fhirpath-support", version = "0.2.0" }
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.0", default-features = false }
22
- helios-fhir = { path = "../fhir", version = "0.2.0", default-features = false }
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