ms-cql-sdk 0.1.0__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 (78) hide show
  1. ms_cql_sdk-0.1.0/.gitignore +45 -0
  2. ms_cql_sdk-0.1.0/LICENSE +17 -0
  3. ms_cql_sdk-0.1.0/PKG-INFO +185 -0
  4. ms_cql_sdk-0.1.0/README.md +127 -0
  5. ms_cql_sdk-0.1.0/pyproject.toml +137 -0
  6. ms_cql_sdk-0.1.0/src/cql_sdk/__init__.py +10 -0
  7. ms_cql_sdk-0.1.0/src/cql_sdk/abstractions/__init__.py +21 -0
  8. ms_cql_sdk-0.1.0/src/cql_sdk/abstractions/data_source.py +27 -0
  9. ms_cql_sdk-0.1.0/src/cql_sdk/abstractions/invocation.py +20 -0
  10. ms_cql_sdk-0.1.0/src/cql_sdk/abstractions/operators.py +31 -0
  11. ms_cql_sdk-0.1.0/src/cql_sdk/abstractions/packaging.py +14 -0
  12. ms_cql_sdk-0.1.0/src/cql_sdk/abstractions/terminology.py +31 -0
  13. ms_cql_sdk-0.1.0/src/cql_sdk/abstractions/type_conversion.py +16 -0
  14. ms_cql_sdk-0.1.0/src/cql_sdk/api.py +80 -0
  15. ms_cql_sdk-0.1.0/src/cql_sdk/cli/__init__.py +5 -0
  16. ms_cql_sdk-0.1.0/src/cql_sdk/cli/commands/__init__.py +1 -0
  17. ms_cql_sdk-0.1.0/src/cql_sdk/cli/commands/inspect.py +32 -0
  18. ms_cql_sdk-0.1.0/src/cql_sdk/cli/commands/package.py +20 -0
  19. ms_cql_sdk-0.1.0/src/cql_sdk/cli/commands/run.py +47 -0
  20. ms_cql_sdk-0.1.0/src/cql_sdk/cli/commands/validate.py +28 -0
  21. ms_cql_sdk-0.1.0/src/cql_sdk/cli/main.py +38 -0
  22. ms_cql_sdk-0.1.0/src/cql_sdk/compiler/__init__.py +7 -0
  23. ms_cql_sdk-0.1.0/src/cql_sdk/compiler/bindings.py +14 -0
  24. ms_cql_sdk-0.1.0/src/cql_sdk/compiler/expression_builder.py +23 -0
  25. ms_cql_sdk-0.1.0/src/cql_sdk/compiler/planner.py +37 -0
  26. ms_cql_sdk-0.1.0/src/cql_sdk/compiler/type_manager.py +18 -0
  27. ms_cql_sdk-0.1.0/src/cql_sdk/elm/__init__.py +5 -0
  28. ms_cql_sdk-0.1.0/src/cql_sdk/elm/models/__init__.py +1 -0
  29. ms_cql_sdk-0.1.0/src/cql_sdk/elm/models/base.py +35 -0
  30. ms_cql_sdk-0.1.0/src/cql_sdk/elm/models/expressions.py +17 -0
  31. ms_cql_sdk-0.1.0/src/cql_sdk/elm/models/library.py +52 -0
  32. ms_cql_sdk-0.1.0/src/cql_sdk/elm/models/types.py +17 -0
  33. ms_cql_sdk-0.1.0/src/cql_sdk/elm/serialization/__init__.py +8 -0
  34. ms_cql_sdk-0.1.0/src/cql_sdk/elm/serialization/compatibility.py +45 -0
  35. ms_cql_sdk-0.1.0/src/cql_sdk/elm/serialization/json_codec.py +30 -0
  36. ms_cql_sdk-0.1.0/src/cql_sdk/elm/serialization/loader.py +89 -0
  37. ms_cql_sdk-0.1.0/src/cql_sdk/fhir/__init__.py +6 -0
  38. ms_cql_sdk-0.1.0/src/cql_sdk/fhir/adapters.py +18 -0
  39. ms_cql_sdk-0.1.0/src/cql_sdk/fhir/context.py +15 -0
  40. ms_cql_sdk-0.1.0/src/cql_sdk/fhir/retrieve.py +34 -0
  41. ms_cql_sdk-0.1.0/src/cql_sdk/fhir/terminology.py +18 -0
  42. ms_cql_sdk-0.1.0/src/cql_sdk/fhir/type_conversion.py +18 -0
  43. ms_cql_sdk-0.1.0/src/cql_sdk/invocation/__init__.py +5 -0
  44. ms_cql_sdk-0.1.0/src/cql_sdk/invocation/cache.py +25 -0
  45. ms_cql_sdk-0.1.0/src/cql_sdk/invocation/invoker.py +24 -0
  46. ms_cql_sdk-0.1.0/src/cql_sdk/invocation/library_registry.py +38 -0
  47. ms_cql_sdk-0.1.0/src/cql_sdk/invocation/toolkit.py +91 -0
  48. ms_cql_sdk-0.1.0/src/cql_sdk/packaging/__init__.py +6 -0
  49. ms_cql_sdk-0.1.0/src/cql_sdk/packaging/bundle_writer.py +17 -0
  50. ms_cql_sdk-0.1.0/src/cql_sdk/packaging/library_package.py +53 -0
  51. ms_cql_sdk-0.1.0/src/cql_sdk/packaging/manifest.py +24 -0
  52. ms_cql_sdk-0.1.0/src/cql_sdk/packaging/resource_writer.py +12 -0
  53. ms_cql_sdk-0.1.0/src/cql_sdk/runtime/__init__.py +1 -0
  54. ms_cql_sdk-0.1.0/src/cql_sdk/runtime/comparers.py +27 -0
  55. ms_cql_sdk-0.1.0/src/cql_sdk/runtime/context.py +79 -0
  56. ms_cql_sdk-0.1.0/src/cql_sdk/runtime/datetime_types.py +15 -0
  57. ms_cql_sdk-0.1.0/src/cql_sdk/runtime/definitions.py +13 -0
  58. ms_cql_sdk-0.1.0/src/cql_sdk/runtime/intervals.py +19 -0
  59. ms_cql_sdk-0.1.0/src/cql_sdk/runtime/operators.py +250 -0
  60. ms_cql_sdk-0.1.0/src/cql_sdk/runtime/quantities.py +15 -0
  61. ms_cql_sdk-0.1.0/src/cql_sdk/spark/__init__.py +12 -0
  62. ms_cql_sdk-0.1.0/src/cql_sdk/spark/adapters.py +12 -0
  63. ms_cql_sdk-0.1.0/src/cql_sdk/spark/execution.py +36 -0
  64. ms_cql_sdk-0.1.0/src/cql_sdk/spark/session.py +51 -0
  65. ms_cql_sdk-0.1.0/src/cql_sdk/spark/udf.py +35 -0
  66. ms_cql_sdk-0.1.0/src/cql_sdk/version.py +5 -0
  67. ms_cql_sdk-0.1.0/tests/__init__.py +0 -0
  68. ms_cql_sdk-0.1.0/tests/conftest.py +18 -0
  69. ms_cql_sdk-0.1.0/tests/fixtures/__init__.py +0 -0
  70. ms_cql_sdk-0.1.0/tests/fixtures/elm/__init__.py +0 -0
  71. ms_cql_sdk-0.1.0/tests/fixtures/elm/hello_world.py +59 -0
  72. ms_cql_sdk-0.1.0/tests/integration/__init__.py +0 -0
  73. ms_cql_sdk-0.1.0/tests/integration/test_api_end_to_end.py +10 -0
  74. ms_cql_sdk-0.1.0/tests/integration/test_spark_smoke.py +20 -0
  75. ms_cql_sdk-0.1.0/tests/unit/__init__.py +0 -0
  76. ms_cql_sdk-0.1.0/tests/unit/test_invocation.py +30 -0
  77. ms_cql_sdk-0.1.0/tests/unit/test_loader.py +14 -0
  78. ms_cql_sdk-0.1.0/tests/unit/test_runtime_operators.py +36 -0
@@ -0,0 +1,45 @@
1
+ # Byte-compiled / cache
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ .token
7
+ # Build artifacts
8
+ build/
9
+ dist/
10
+ *.egg-info/
11
+ .eggs/
12
+ .wheels/
13
+
14
+ # Virtual envs
15
+ .venv/
16
+ venv/
17
+ env/
18
+
19
+ # uv / pip
20
+ .uv/
21
+ pip-wheel-metadata/
22
+
23
+ # Tests / coverage
24
+ .pytest_cache/
25
+ .coverage
26
+ .coverage.*
27
+ htmlcov/
28
+ coverage.xml
29
+ .mypy_cache/
30
+ .ruff_cache/
31
+
32
+ # IDEs
33
+ .idea/
34
+ .vscode/
35
+ *.swp
36
+ .DS_Store
37
+
38
+ # Docs build
39
+ site/
40
+
41
+ # Local data
42
+ *.log
43
+ .cache/
44
+ .tmp/
45
+ .history
@@ -0,0 +1,17 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ Copyright (c) 2026 cql-sdk authors
6
+
7
+ Licensed under the Apache License, Version 2.0 (the "License");
8
+ you may not use this file except in compliance with the License.
9
+ You may obtain a copy of the License at
10
+
11
+ http://www.apache.org/licenses/LICENSE-2.0
12
+
13
+ Unless required by applicable law or agreed to in writing, software
14
+ distributed under the License is distributed on an "AS IS" BASIS,
15
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ See the License for the specific language governing permissions and
17
+ limitations under the License.
@@ -0,0 +1,185 @@
1
+ Metadata-Version: 2.4
2
+ Name: ms-cql-sdk
3
+ Version: 0.1.0
4
+ Summary: Modular Python CQL SDK (ELM loading, runtime, invocation, FHIR and Spark adapters).
5
+ Project-URL: Homepage, https://github.com/ctava-msft/azure-healthcare-digital-quality-cql-sdk
6
+ Project-URL: Documentation, https://github.com/ctava-msft/azure-healthcare-digital-quality-cql-sdk#readme
7
+ Project-URL: Source, https://github.com/ctava-msft/azure-healthcare-digital-quality-cql-sdk
8
+ Project-URL: Issues, https://github.com/ctava-msft/azure-healthcare-digital-quality-cql-sdk/issues
9
+ Author: cql-sdk authors
10
+ License: Apache License
11
+ Version 2.0, January 2004
12
+ http://www.apache.org/licenses/
13
+
14
+ Copyright (c) 2026 cql-sdk authors
15
+
16
+ Licensed under the Apache License, Version 2.0 (the "License");
17
+ you may not use this file except in compliance with the License.
18
+ You may obtain a copy of the License at
19
+
20
+ http://www.apache.org/licenses/LICENSE-2.0
21
+
22
+ Unless required by applicable law or agreed to in writing, software
23
+ distributed under the License is distributed on an "AS IS" BASIS,
24
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
25
+ See the License for the specific language governing permissions and
26
+ limitations under the License.
27
+ License-File: LICENSE
28
+ Keywords: cql,elm,fhir,healthcare,quality-measures
29
+ Classifier: Development Status :: 3 - Alpha
30
+ Classifier: Intended Audience :: Developers
31
+ Classifier: Intended Audience :: Healthcare Industry
32
+ Classifier: License :: OSI Approved :: Apache Software License
33
+ Classifier: Programming Language :: Python :: 3
34
+ Classifier: Programming Language :: Python :: 3.12
35
+ Classifier: Topic :: Scientific/Engineering :: Medical Science Apps.
36
+ Requires-Python: >=3.12
37
+ Requires-Dist: pydantic>=2.7
38
+ Requires-Dist: python-dateutil>=2.9
39
+ Requires-Dist: rich>=13.7
40
+ Requires-Dist: typer>=0.12
41
+ Provides-Extra: dev
42
+ Requires-Dist: build>=1.2; extra == 'dev'
43
+ Requires-Dist: mypy>=1.11; extra == 'dev'
44
+ Requires-Dist: pre-commit>=3.7; extra == 'dev'
45
+ Requires-Dist: ruff>=0.6; extra == 'dev'
46
+ Provides-Extra: docs
47
+ Requires-Dist: mkdocs-material>=9.5; extra == 'docs'
48
+ Requires-Dist: mkdocs>=1.6; extra == 'docs'
49
+ Provides-Extra: fhir
50
+ Requires-Dist: fhir-resources>=7.1; extra == 'fhir'
51
+ Provides-Extra: spark
52
+ Requires-Dist: pyspark>=3.5; extra == 'spark'
53
+ Provides-Extra: test
54
+ Requires-Dist: pytest-cov>=5.0; extra == 'test'
55
+ Requires-Dist: pytest-xdist>=3.6; extra == 'test'
56
+ Requires-Dist: pytest>=8.2; extra == 'test'
57
+ Description-Content-Type: text/markdown
58
+
59
+ # cql-sdk
60
+
61
+ A modular Python SDK for working with **Clinical Quality Language (CQL)** and
62
+ its compiled form **ELM** (Expression Logical Model). Inspired by the layering
63
+ of the Firely C# CQL SDK, but designed idiomatically for Python and for modern
64
+ data platforms (standalone, containers, PySpark, Microsoft Fabric).
65
+
66
+ > Status: early scaffold. The architecture, public API surface and extension
67
+ > points are deliberately sketched so they can grow toward a fuller CQL
68
+ > engine without breaking consumers.
69
+
70
+ ## Why this SDK
71
+
72
+ - Pure-Python core for ELM loading, runtime context, operators, invocation.
73
+ - Optional FHIR integration (retrieval, type conversion, terminology).
74
+ - Optional Spark / Microsoft Fabric integration (the *same* core package
75
+ runs unchanged in both environments).
76
+ - A Typer-based CLI for inspecting, validating, packaging and running ELM.
77
+ - Designed around *pre-generated ELM artifacts* as a first-class workflow —
78
+ no Java/CQL-to-ELM toolchain is required for normal execution.
79
+
80
+ ## Package layering
81
+
82
+ ```
83
+ cql_sdk
84
+ ├── abstractions/ # Protocols / ABCs for operators, terminology, data, packaging
85
+ ├── elm/ # ELM model + (de)serialization
86
+ ├── runtime/ # RuntimeContext, operators, comparers, intervals, datetime
87
+ ├── compiler/ # Expression planner, bindings, type manager
88
+ ├── invocation/ # High-level toolkit / invoker / library registry (PUBLIC API)
89
+ ├── fhir/ # Optional FHIR adapters
90
+ ├── spark/ # Optional Spark / Fabric adapters
91
+ ├── packaging/ # Library + resource packaging primitives
92
+ ├── cli/ # Typer CLI (`cql-sdk`)
93
+ └── api.py # Top-level convenience facade (PUBLIC API)
94
+ ```
95
+
96
+ The **invocation toolkit** and [`cql_sdk.api`](src/cql_sdk/api.py) are the
97
+ preferred entry points. Internal modules (`compiler`, low-level runtime) are
98
+ available but not the recommended consumption path.
99
+
100
+ ## Quick start
101
+
102
+ ### Install (base)
103
+
104
+ ```bash
105
+ uv sync
106
+ ```
107
+
108
+ ### Install with optional extras
109
+
110
+ ```bash
111
+ uv sync --extra fhir
112
+ uv sync --extra spark # pulls pyspark; not required for base install
113
+ uv sync --extra dev --extra test
114
+ ```
115
+
116
+ ### Run the local hello-world example
117
+
118
+ ```bash
119
+ uv run python examples/hello_world/run.py
120
+ ```
121
+
122
+ ### Load ELM and invoke a definition (Python)
123
+
124
+ ```python
125
+ from cql_sdk.api import load_library, invoke
126
+
127
+ library = load_library("examples/hello_world/HelloWorld.elm.json")
128
+ result = invoke(library, definition="Greeting")
129
+ print(result)
130
+ ```
131
+
132
+ ### Use the CLI
133
+
134
+ ```bash
135
+ uv run cql-sdk inspect examples/hello_world/HelloWorld.elm.json
136
+ uv run cql-sdk validate examples/hello_world/HelloWorld.elm.json
137
+ uv run cql-sdk run examples/hello_world/HelloWorld.elm.json --definition Greeting
138
+ uv run cql-sdk package examples/hello_world --output dist/packages
139
+ ```
140
+
141
+ ### Spark / Fabric usage
142
+
143
+ Spark support is *opt-in*:
144
+
145
+ ```bash
146
+ uv sync --extra spark
147
+ ```
148
+
149
+ ```python
150
+ from pyspark.sql import SparkSession
151
+ from cql_sdk.spark import SparkInvocation
152
+
153
+ spark = SparkSession.builder.getOrCreate()
154
+ invocation = SparkInvocation.from_elm_path(
155
+ "examples/hello_world/HelloWorld.elm.json", spark=spark
156
+ )
157
+ df = invocation.run(definition="Greeting")
158
+ df.show()
159
+ ```
160
+
161
+ Core modules never import `pyspark` — importing `cql_sdk.spark` is the only
162
+ place Spark is required.
163
+
164
+ ## Development
165
+
166
+ ```bash
167
+ uv sync --extra dev --extra test
168
+ uv run ruff check .
169
+ uv run mypy
170
+ uv run pytest -m "not spark"
171
+ uv run pytest -m spark # requires `--extra spark`
172
+ ```
173
+
174
+ See [docs/development.md](docs/development.md) for more.
175
+
176
+ ## Documentation
177
+
178
+ - [Architecture](docs/architecture.md)
179
+ - [Public API](docs/public-api.md)
180
+ - [Packaging](docs/packaging.md)
181
+ - [Development](docs/development.md)
182
+
183
+ ## License
184
+
185
+ Apache-2.0. See [LICENSE](LICENSE).
@@ -0,0 +1,127 @@
1
+ # cql-sdk
2
+
3
+ A modular Python SDK for working with **Clinical Quality Language (CQL)** and
4
+ its compiled form **ELM** (Expression Logical Model). Inspired by the layering
5
+ of the Firely C# CQL SDK, but designed idiomatically for Python and for modern
6
+ data platforms (standalone, containers, PySpark, Microsoft Fabric).
7
+
8
+ > Status: early scaffold. The architecture, public API surface and extension
9
+ > points are deliberately sketched so they can grow toward a fuller CQL
10
+ > engine without breaking consumers.
11
+
12
+ ## Why this SDK
13
+
14
+ - Pure-Python core for ELM loading, runtime context, operators, invocation.
15
+ - Optional FHIR integration (retrieval, type conversion, terminology).
16
+ - Optional Spark / Microsoft Fabric integration (the *same* core package
17
+ runs unchanged in both environments).
18
+ - A Typer-based CLI for inspecting, validating, packaging and running ELM.
19
+ - Designed around *pre-generated ELM artifacts* as a first-class workflow —
20
+ no Java/CQL-to-ELM toolchain is required for normal execution.
21
+
22
+ ## Package layering
23
+
24
+ ```
25
+ cql_sdk
26
+ ├── abstractions/ # Protocols / ABCs for operators, terminology, data, packaging
27
+ ├── elm/ # ELM model + (de)serialization
28
+ ├── runtime/ # RuntimeContext, operators, comparers, intervals, datetime
29
+ ├── compiler/ # Expression planner, bindings, type manager
30
+ ├── invocation/ # High-level toolkit / invoker / library registry (PUBLIC API)
31
+ ├── fhir/ # Optional FHIR adapters
32
+ ├── spark/ # Optional Spark / Fabric adapters
33
+ ├── packaging/ # Library + resource packaging primitives
34
+ ├── cli/ # Typer CLI (`cql-sdk`)
35
+ └── api.py # Top-level convenience facade (PUBLIC API)
36
+ ```
37
+
38
+ The **invocation toolkit** and [`cql_sdk.api`](src/cql_sdk/api.py) are the
39
+ preferred entry points. Internal modules (`compiler`, low-level runtime) are
40
+ available but not the recommended consumption path.
41
+
42
+ ## Quick start
43
+
44
+ ### Install (base)
45
+
46
+ ```bash
47
+ uv sync
48
+ ```
49
+
50
+ ### Install with optional extras
51
+
52
+ ```bash
53
+ uv sync --extra fhir
54
+ uv sync --extra spark # pulls pyspark; not required for base install
55
+ uv sync --extra dev --extra test
56
+ ```
57
+
58
+ ### Run the local hello-world example
59
+
60
+ ```bash
61
+ uv run python examples/hello_world/run.py
62
+ ```
63
+
64
+ ### Load ELM and invoke a definition (Python)
65
+
66
+ ```python
67
+ from cql_sdk.api import load_library, invoke
68
+
69
+ library = load_library("examples/hello_world/HelloWorld.elm.json")
70
+ result = invoke(library, definition="Greeting")
71
+ print(result)
72
+ ```
73
+
74
+ ### Use the CLI
75
+
76
+ ```bash
77
+ uv run cql-sdk inspect examples/hello_world/HelloWorld.elm.json
78
+ uv run cql-sdk validate examples/hello_world/HelloWorld.elm.json
79
+ uv run cql-sdk run examples/hello_world/HelloWorld.elm.json --definition Greeting
80
+ uv run cql-sdk package examples/hello_world --output dist/packages
81
+ ```
82
+
83
+ ### Spark / Fabric usage
84
+
85
+ Spark support is *opt-in*:
86
+
87
+ ```bash
88
+ uv sync --extra spark
89
+ ```
90
+
91
+ ```python
92
+ from pyspark.sql import SparkSession
93
+ from cql_sdk.spark import SparkInvocation
94
+
95
+ spark = SparkSession.builder.getOrCreate()
96
+ invocation = SparkInvocation.from_elm_path(
97
+ "examples/hello_world/HelloWorld.elm.json", spark=spark
98
+ )
99
+ df = invocation.run(definition="Greeting")
100
+ df.show()
101
+ ```
102
+
103
+ Core modules never import `pyspark` — importing `cql_sdk.spark` is the only
104
+ place Spark is required.
105
+
106
+ ## Development
107
+
108
+ ```bash
109
+ uv sync --extra dev --extra test
110
+ uv run ruff check .
111
+ uv run mypy
112
+ uv run pytest -m "not spark"
113
+ uv run pytest -m spark # requires `--extra spark`
114
+ ```
115
+
116
+ See [docs/development.md](docs/development.md) for more.
117
+
118
+ ## Documentation
119
+
120
+ - [Architecture](docs/architecture.md)
121
+ - [Public API](docs/public-api.md)
122
+ - [Packaging](docs/packaging.md)
123
+ - [Development](docs/development.md)
124
+
125
+ ## License
126
+
127
+ Apache-2.0. See [LICENSE](LICENSE).
@@ -0,0 +1,137 @@
1
+ [build-system]
2
+ requires = ["hatchling>=1.25"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "ms-cql-sdk"
7
+ version = "0.1.0"
8
+ description = "Modular Python CQL SDK (ELM loading, runtime, invocation, FHIR and Spark adapters)."
9
+ readme = "README.md"
10
+ license = { file = "LICENSE" }
11
+ requires-python = ">=3.12"
12
+ authors = [{ name = "cql-sdk authors" }]
13
+ keywords = ["cql", "elm", "fhir", "healthcare", "quality-measures"]
14
+ classifiers = [
15
+ "Development Status :: 3 - Alpha",
16
+ "Intended Audience :: Developers",
17
+ "Intended Audience :: Healthcare Industry",
18
+ "License :: OSI Approved :: Apache Software License",
19
+ "Programming Language :: Python :: 3",
20
+ "Programming Language :: Python :: 3.12",
21
+ "Topic :: Scientific/Engineering :: Medical Science Apps.",
22
+ ]
23
+ dependencies = [
24
+ "typer>=0.12",
25
+ "rich>=13.7",
26
+ "pydantic>=2.7",
27
+ "python-dateutil>=2.9",
28
+ ]
29
+
30
+ [project.optional-dependencies]
31
+ fhir = [
32
+ "fhir.resources>=7.1",
33
+ ]
34
+ spark = [
35
+ "pyspark>=3.5",
36
+ ]
37
+ dev = [
38
+ "ruff>=0.6",
39
+ "mypy>=1.11",
40
+ "build>=1.2",
41
+ "pre-commit>=3.7",
42
+ ]
43
+ test = [
44
+ "pytest>=8.2",
45
+ "pytest-cov>=5.0",
46
+ "pytest-xdist>=3.6",
47
+ ]
48
+ docs = [
49
+ "mkdocs>=1.6",
50
+ "mkdocs-material>=9.5",
51
+ ]
52
+
53
+ [project.scripts]
54
+ cql-sdk = "cql_sdk.cli.main:app"
55
+
56
+ [project.urls]
57
+ Homepage = "https://github.com/ctava-msft/azure-healthcare-digital-quality-cql-sdk"
58
+ Documentation = "https://github.com/ctava-msft/azure-healthcare-digital-quality-cql-sdk#readme"
59
+ Source = "https://github.com/ctava-msft/azure-healthcare-digital-quality-cql-sdk"
60
+ Issues = "https://github.com/ctava-msft/azure-healthcare-digital-quality-cql-sdk/issues"
61
+
62
+ [tool.hatch.build.targets.wheel]
63
+ packages = ["src/cql_sdk"]
64
+
65
+ [tool.hatch.build.targets.sdist]
66
+ include = ["src", "tests", "README.md", "LICENSE", "pyproject.toml"]
67
+
68
+ # -------- Tooling --------
69
+
70
+ [tool.ruff]
71
+ line-length = 100
72
+ target-version = "py312"
73
+ src = ["src", "tests"]
74
+
75
+ [tool.ruff.lint]
76
+ select = [
77
+ "E", "F", "W", # pycodestyle + pyflakes
78
+ "I", # isort
79
+ "B", # bugbear
80
+ "UP", # pyupgrade
81
+ "SIM", # simplify
82
+ "RUF", # ruff rules
83
+ "D", # pydocstyle
84
+ "TID", # tidy-imports
85
+ ]
86
+ ignore = [
87
+ "D100", "D101", "D102", "D103", "D104", "D105", "D106", "D107",
88
+ "D203", "D213",
89
+ "B008", # Typer uses call-in-default as its canonical pattern
90
+ ]
91
+
92
+ [tool.ruff.lint.per-file-ignores]
93
+ "tests/**" = ["D", "E501"]
94
+ "examples/**" = ["D"]
95
+ "src/cql_sdk/elm/serialization/loader.py" = ["E501"]
96
+ "src/cql_sdk/packaging/library_package.py" = ["E501"]
97
+ "src/cql_sdk/spark/session.py" = ["E501"]
98
+ "src/cql_sdk/runtime/context.py" = ["E501"]
99
+
100
+ [tool.ruff.lint.pydocstyle]
101
+ convention = "google"
102
+
103
+ [tool.mypy]
104
+ python_version = "3.12"
105
+ strict = true
106
+ warn_unused_ignores = true
107
+ warn_redundant_casts = true
108
+ warn_unreachable = true
109
+ disallow_untyped_defs = true
110
+ no_implicit_optional = true
111
+ files = ["src"]
112
+
113
+ [[tool.mypy.overrides]]
114
+ module = ["pyspark.*", "fhir.resources.*"]
115
+ ignore_missing_imports = true
116
+
117
+ [tool.pytest.ini_options]
118
+ minversion = "8.0"
119
+ addopts = "-ra --strict-markers --strict-config"
120
+ testpaths = ["tests"]
121
+ markers = [
122
+ "unit: fast, isolated unit tests",
123
+ "integration: end-to-end ELM loading / invocation tests",
124
+ "spark: requires pyspark (install with `uv sync --extra spark`)",
125
+ ]
126
+ filterwarnings = [
127
+ "error",
128
+ "ignore::DeprecationWarning:pyspark.*",
129
+ ]
130
+
131
+ [tool.coverage.run]
132
+ branch = true
133
+ source = ["cql_sdk"]
134
+
135
+ [tool.coverage.report]
136
+ show_missing = true
137
+ skip_empty = true
@@ -0,0 +1,10 @@
1
+ """cql-sdk: a modular Python SDK for CQL/ELM execution.
2
+
3
+ Public entry points live in :mod:`cql_sdk.api` and
4
+ :mod:`cql_sdk.invocation.toolkit`. Everything else is considered internal
5
+ and may evolve without notice.
6
+ """
7
+
8
+ from cql_sdk.version import __version__
9
+
10
+ __all__ = ["__version__"]
@@ -0,0 +1,21 @@
1
+ """Abstractions: protocols and ABCs describing stable SDK seams.
2
+
3
+ Concrete implementations live under :mod:`cql_sdk.runtime`,
4
+ :mod:`cql_sdk.fhir`, :mod:`cql_sdk.spark`, and :mod:`cql_sdk.packaging`.
5
+ """
6
+
7
+ from cql_sdk.abstractions.data_source import DataSource
8
+ from cql_sdk.abstractions.invocation import Invoker
9
+ from cql_sdk.abstractions.operators import OperatorRegistry
10
+ from cql_sdk.abstractions.packaging import PackageWriter
11
+ from cql_sdk.abstractions.terminology import TerminologyProvider
12
+ from cql_sdk.abstractions.type_conversion import TypeConverter
13
+
14
+ __all__ = [
15
+ "DataSource",
16
+ "Invoker",
17
+ "OperatorRegistry",
18
+ "PackageWriter",
19
+ "TerminologyProvider",
20
+ "TypeConverter",
21
+ ]
@@ -0,0 +1,27 @@
1
+ """Data source protocol used by retrieve-style ELM nodes."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from collections.abc import Iterable
6
+ from typing import Any, Protocol, runtime_checkable
7
+
8
+
9
+ @runtime_checkable
10
+ class DataSource(Protocol):
11
+ """Abstract source of clinical/patient data.
12
+
13
+ Implementations may be backed by in-memory FHIR bundles, file-based
14
+ fixtures, REST FHIR servers, or Spark DataFrames.
15
+ """
16
+
17
+ def retrieve(
18
+ self,
19
+ *,
20
+ data_type: str,
21
+ code_property: str | None = None,
22
+ codes: Iterable[Any] | None = None,
23
+ date_property: str | None = None,
24
+ date_range: Any | None = None,
25
+ context: Any | None = None,
26
+ ) -> Iterable[Any]:
27
+ """Retrieve resources/records matching the given criteria."""
@@ -0,0 +1,20 @@
1
+ """Invocation protocol — the top-level user-facing seam."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any, Protocol, runtime_checkable
6
+
7
+
8
+ @runtime_checkable
9
+ class Invoker(Protocol):
10
+ """Executes a named definition on a registered library."""
11
+
12
+ def invoke(
13
+ self,
14
+ *,
15
+ library_identifier: str,
16
+ definition: str,
17
+ parameters: dict[str, Any] | None = None,
18
+ context: Any | None = None,
19
+ ) -> Any:
20
+ """Evaluate ``definition`` in the given library and return its value."""
@@ -0,0 +1,31 @@
1
+ """Operator registry protocol.
2
+
3
+ An operator registry maps ELM operator/expression node *type names* to
4
+ executable Python callables. Keeping this behind a Protocol lets the runtime,
5
+ FHIR, and Spark layers swap or extend operator behavior without touching
6
+ core planner/invoker code.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ from typing import Any, Protocol, runtime_checkable
12
+
13
+ OperatorFn = Any # Callable[[RuntimeContext, ElmNode, ...], Any] — kept loose to avoid cycles
14
+
15
+
16
+ @runtime_checkable
17
+ class OperatorRegistry(Protocol):
18
+ """Maps ELM node type names to executable operator callables."""
19
+
20
+ def register(self, elm_type: str, fn: OperatorFn) -> None:
21
+ """Register (or replace) an operator implementation."""
22
+
23
+ def get(self, elm_type: str) -> OperatorFn:
24
+ """Return the operator callable for ``elm_type``.
25
+
26
+ Raises:
27
+ KeyError: if no operator is registered for ``elm_type``.
28
+ """
29
+
30
+ def has(self, elm_type: str) -> bool:
31
+ """Return whether an operator is registered for ``elm_type``."""
@@ -0,0 +1,14 @@
1
+ """Packaging seam for emitting library/manifest/resource artifacts."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from pathlib import Path
6
+ from typing import Any, Protocol, runtime_checkable
7
+
8
+
9
+ @runtime_checkable
10
+ class PackageWriter(Protocol):
11
+ """Writes a logical package (ELM + resources + manifest) to disk."""
12
+
13
+ def write(self, *, output_dir: Path, manifest: Any, resources: list[Any]) -> Path:
14
+ """Persist the package and return the root output path."""
@@ -0,0 +1,31 @@
1
+ """Terminology provider protocol (value sets, code systems, concepts)."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass
6
+ from typing import Protocol, runtime_checkable
7
+
8
+
9
+ @dataclass(frozen=True, slots=True)
10
+ class Code:
11
+ code: str
12
+ system: str | None = None
13
+ display: str | None = None
14
+ version: str | None = None
15
+
16
+
17
+ @dataclass(frozen=True, slots=True)
18
+ class ValueSetRef:
19
+ id: str
20
+ version: str | None = None
21
+
22
+
23
+ @runtime_checkable
24
+ class TerminologyProvider(Protocol):
25
+ """Resolves value set membership and code system lookups."""
26
+
27
+ def expand(self, value_set: ValueSetRef) -> list[Code]:
28
+ """Return the expansion (list of codes) for a value set."""
29
+
30
+ def in_value_set(self, code: Code, value_set: ValueSetRef) -> bool:
31
+ """Return whether ``code`` is a member of ``value_set``."""
@@ -0,0 +1,16 @@
1
+ """Type conversion seam between ELM/CQL types and host Python values."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any, Protocol, runtime_checkable
6
+
7
+
8
+ @runtime_checkable
9
+ class TypeConverter(Protocol):
10
+ """Bidirectional conversion between CQL/ELM values and Python values."""
11
+
12
+ def to_python(self, cql_value: Any, *, cql_type: str | None = None) -> Any:
13
+ """Convert a CQL/ELM value to an idiomatic Python value."""
14
+
15
+ def to_cql(self, py_value: Any, *, cql_type: str | None = None) -> Any:
16
+ """Convert a Python value into the representation expected by ELM."""