uptimely-core 0.1.0__tar.gz → 0.2.0.dev0__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.
- {uptimely_core-0.1.0 → uptimely_core-0.2.0.dev0}/PKG-INFO +20 -9
- {uptimely_core-0.1.0 → uptimely_core-0.2.0.dev0}/pyproject.toml +3 -3
- {uptimely_core-0.1.0 → uptimely_core-0.2.0.dev0}/readme.md +17 -6
- uptimely_core-0.2.0.dev0/src/uptimely/__init__.py +40 -0
- uptimely_core-0.2.0.dev0/src/uptimely/analytics/__init__.py +65 -0
- uptimely_core-0.2.0.dev0/src/uptimely/analytics/api.py +82 -0
- uptimely_core-0.2.0.dev0/src/uptimely/analytics/catalog.py +41 -0
- uptimely_core-0.2.0.dev0/src/uptimely/analytics/feature_graph/__init__.py +14 -0
- uptimely_core-0.1.0/src/uptimely/analytics/feature_graph.py → uptimely_core-0.2.0.dev0/src/uptimely/analytics/feature_graph/graph.py +22 -24
- {uptimely_core-0.1.0/src/uptimely/analytics → uptimely_core-0.2.0.dev0/src/uptimely/analytics/feature_graph}/models.py +7 -10
- uptimely_core-0.2.0.dev0/src/uptimely/analytics/json/__init__.py +1 -0
- uptimely_core-0.2.0.dev0/src/uptimely/analytics/json/codec.py +42 -0
- uptimely_core-0.2.0.dev0/src/uptimely/analytics/model/__init__.py +48 -0
- uptimely_core-0.2.0.dev0/src/uptimely/analytics/model/analytics.py +86 -0
- {uptimely_core-0.1.0/src/uptimely/spec/json_spec/json_model → uptimely_core-0.2.0.dev0/src/uptimely/analytics/model}/common.py +4 -4
- {uptimely_core-0.1.0/src/uptimely/spec/json_spec/json_model → uptimely_core-0.2.0.dev0/src/uptimely/analytics/model}/dataset.py +21 -9
- uptimely_core-0.2.0.dev0/src/uptimely/analytics/model/functions.py +57 -0
- uptimely_core-0.2.0.dev0/src/uptimely/analytics/python/__init__.py +7 -0
- uptimely_core-0.2.0.dev0/src/uptimely/analytics/python/analytics.py +60 -0
- {uptimely_core-0.1.0/src/uptimely/spec/python_spec → uptimely_core-0.2.0.dev0/src/uptimely/analytics/python}/bind.py +29 -21
- uptimely_core-0.2.0.dev0/src/uptimely/analytics/python/conversion.py +159 -0
- uptimely_core-0.2.0.dev0/src/uptimely/analytics/python/dataset.py +142 -0
- {uptimely_core-0.1.0/src/uptimely/spec/python_spec → uptimely_core-0.2.0.dev0/src/uptimely/analytics/python}/dimension.py +3 -3
- uptimely_core-0.2.0.dev0/src/uptimely/analytics/python/entity.py +35 -0
- {uptimely_core-0.1.0/src/uptimely/spec/python_spec → uptimely_core-0.2.0.dev0/src/uptimely/analytics/python}/feature.py +3 -3
- uptimely_core-0.2.0.dev0/src/uptimely/analytics/python/mappings.py +87 -0
- uptimely_core-0.2.0.dev0/src/uptimely/analytics/python/ref.py +139 -0
- {uptimely_core-0.1.0/src/uptimely/spec/python_spec → uptimely_core-0.2.0.dev0/src/uptimely/analytics/python}/row_context.py +1 -1
- uptimely_core-0.1.0/src/uptimely/spec/json_spec/bindings.py → uptimely_core-0.2.0.dev0/src/uptimely/analytics/references.py +40 -27
- uptimely_core-0.2.0.dev0/src/uptimely/analytics/resolution.py +78 -0
- {uptimely_core-0.1.0/src/uptimely/spec/json_spec/json_model → uptimely_core-0.2.0.dev0/src/uptimely/analytics}/resolved.py +15 -2
- uptimely_core-0.2.0.dev0/src/uptimely/analytics/validation/__init__.py +20 -0
- uptimely_core-0.2.0.dev0/src/uptimely/analytics/validation/analytics.py +40 -0
- uptimely_core-0.2.0.dev0/src/uptimely/analytics/validation/context.py +174 -0
- uptimely_core-0.2.0.dev0/src/uptimely/analytics/validation/dependencies.py +23 -0
- uptimely_core-0.2.0.dev0/src/uptimely/analytics/validation/dimensions.py +111 -0
- uptimely_core-0.2.0.dev0/src/uptimely/analytics/validation/errors.py +13 -0
- uptimely_core-0.2.0.dev0/src/uptimely/analytics/validation/functions.py +150 -0
- uptimely_core-0.2.0.dev0/src/uptimely/analytics/validation/mappings.py +434 -0
- uptimely_core-0.2.0.dev0/src/uptimely/analytics/validation/prepared.py +155 -0
- uptimely_core-0.2.0.dev0/src/uptimely/cli/analytics.py +97 -0
- uptimely_core-0.2.0.dev0/src/uptimely/cli/cli.py +39 -0
- uptimely_core-0.2.0.dev0/src/uptimely/cli/common.py +49 -0
- uptimely_core-0.2.0.dev0/src/uptimely/cli/engine.py +99 -0
- uptimely_core-0.1.0/src/uptimely/cli/cli.py → uptimely_core-0.2.0.dev0/src/uptimely/cli/examples.py +8 -147
- uptimely_core-0.2.0.dev0/src/uptimely/cli/explorer.py +192 -0
- uptimely_core-0.2.0.dev0/src/uptimely/cli/plan.py +64 -0
- uptimely_core-0.2.0.dev0/src/uptimely/compiler/__init__.py +12 -0
- uptimely_core-0.1.0/src/uptimely/compile/node.py → uptimely_core-0.2.0.dev0/src/uptimely/compiler/callable_node.py +9 -30
- uptimely_core-0.2.0.dev0/src/uptimely/compiler/compiler.py +201 -0
- {uptimely_core-0.1.0/src/uptimely/compile → uptimely_core-0.2.0.dev0/src/uptimely/compiler}/execution_graph.py +67 -52
- uptimely_core-0.2.0.dev0/src/uptimely/compiler/plan/__init__.py +6 -0
- {uptimely_core-0.1.0/src/uptimely → uptimely_core-0.2.0.dev0/src/uptimely/compiler}/plan/models.py +65 -56
- uptimely_core-0.2.0.dev0/src/uptimely/contracts.py +56 -0
- {uptimely_core-0.1.0 → uptimely_core-0.2.0.dev0}/src/uptimely/engine/__init__.py +2 -1
- {uptimely_core-0.1.0 → uptimely_core-0.2.0.dev0}/src/uptimely/engine/backend.py +1 -1
- uptimely_core-0.2.0.dev0/src/uptimely/engine/bindings.py +80 -0
- uptimely_core-0.2.0.dev0/src/uptimely/engine/config.py +35 -0
- uptimely_core-0.2.0.dev0/src/uptimely/engine/dataframe.py +119 -0
- uptimely_core-0.2.0.dev0/src/uptimely/engine/engine.py +178 -0
- {uptimely_core-0.1.0 → uptimely_core-0.2.0.dev0}/src/uptimely/engine/result.py +4 -1
- uptimely_core-0.2.0.dev0/src/uptimely/engine/state.py +33 -0
- uptimely_core-0.2.0.dev0/src/uptimely/entrypoint.py +172 -0
- uptimely_core-0.1.0/src/uptimely/spec/render.py → uptimely_core-0.2.0.dev0/src/uptimely/explorer/analytics_render.py +89 -73
- uptimely_core-0.2.0.dev0/src/uptimely/explorer/explorer.py +127 -0
- uptimely_core-0.1.0/src/uptimely/analytics/render.py → uptimely_core-0.2.0.dev0/src/uptimely/explorer/graph_render.py +4 -4
- {uptimely_core-0.1.0/src/uptimely/docs → uptimely_core-0.2.0.dev0/src/uptimely/explorer}/lineage.py +37 -37
- uptimely_core-0.1.0/src/uptimely/compile/render.py → uptimely_core-0.2.0.dev0/src/uptimely/explorer/plan_render.py +68 -67
- uptimely_core-0.2.0.dev0/src/uptimely/mcp/__init__.py +5 -0
- {uptimely_core-0.1.0 → uptimely_core-0.2.0.dev0}/src/uptimely/mcp/server.py +90 -74
- {uptimely_core-0.1.0 → uptimely_core-0.2.0.dev0}/src/uptimely/render.py +9 -4
- {uptimely_core-0.1.0 → uptimely_core-0.2.0.dev0}/src/uptimely/row_context.py +6 -2
- {uptimely_core-0.1.0/src/uptimely/spec → uptimely_core-0.2.0.dev0/src/uptimely}/storage.py +6 -1
- uptimely_core-0.2.0.dev0/src/uptimely/templates/analytics/datasets.html.j2 +5 -0
- uptimely_core-0.2.0.dev0/src/uptimely/templates/analytics/dimensions.html.j2 +5 -0
- uptimely_core-0.2.0.dev0/src/uptimely/templates/analytics/entities.html.j2 +5 -0
- uptimely_core-0.2.0.dev0/src/uptimely/templates/analytics/features.html.j2 +5 -0
- uptimely_core-0.2.0.dev0/src/uptimely/templates/analytics/functions.html.j2 +5 -0
- {uptimely_core-0.1.0/src/uptimely/templates/spec → uptimely_core-0.2.0.dev0/src/uptimely/templates/analytics}/index.html.j2 +7 -7
- uptimely_core-0.2.0.dev0/src/uptimely/templates/analytics/overview.html.j2 +5 -0
- {uptimely_core-0.1.0/src/uptimely/templates/spec → uptimely_core-0.2.0.dev0/src/uptimely/templates/analytics}/section_header.html.j2 +1 -1
- {uptimely_core-0.1.0/src/uptimely/templates/spec → uptimely_core-0.2.0.dev0/src/uptimely/templates/analytics}/sections/dataset_list.html.j2 +9 -11
- {uptimely_core-0.1.0/src/uptimely/templates/spec → uptimely_core-0.2.0.dev0/src/uptimely/templates/analytics}/sections/dimensions.html.j2 +1 -1
- {uptimely_core-0.1.0/src/uptimely/templates/spec → uptimely_core-0.2.0.dev0/src/uptimely/templates/analytics}/sections/entities.html.j2 +5 -7
- {uptimely_core-0.1.0/src/uptimely/templates/spec → uptimely_core-0.2.0.dev0/src/uptimely/templates/analytics}/sections/entity_list.html.j2 +1 -1
- {uptimely_core-0.1.0/src/uptimely/templates/spec → uptimely_core-0.2.0.dev0/src/uptimely/templates/analytics}/sections/functions.html.j2 +2 -2
- {uptimely_core-0.1.0/src/uptimely/templates/spec → uptimely_core-0.2.0.dev0/src/uptimely/templates/analytics}/sections/overview.html.j2 +4 -4
- {uptimely_core-0.1.0 → uptimely_core-0.2.0.dev0}/src/uptimely/templates/base.html.j2 +8 -8
- {uptimely_core-0.1.0 → uptimely_core-0.2.0.dev0}/src/uptimely/templates/execution/data_lineage.html.j2 +15 -15
- {uptimely_core-0.1.0 → uptimely_core-0.2.0.dev0}/src/uptimely/templates/icons.html.j2 +1 -1
- {uptimely_core-0.1.0 → uptimely_core-0.2.0.dev0}/src/uptimely/templates/index.html.j2 +11 -13
- {uptimely_core-0.1.0 → uptimely_core-0.2.0.dev0}/src/uptimely/templates/plan/callable_graph.html.j2 +4 -5
- {uptimely_core-0.1.0 → uptimely_core-0.2.0.dev0}/src/uptimely/templates/plan/callable_renderer_2d.js.j2 +1 -1
- {uptimely_core-0.1.0 → uptimely_core-0.2.0.dev0}/src/uptimely/templates/plan/index.html.j2 +12 -12
- uptimely_core-0.1.0/src/uptimely/__init__.py +0 -27
- uptimely_core-0.1.0/src/uptimely/analytics/__init__.py +0 -18
- uptimely_core-0.1.0/src/uptimely/compile/__init__.py +0 -16
- uptimely_core-0.1.0/src/uptimely/compile/compiler.py +0 -196
- uptimely_core-0.1.0/src/uptimely/compile/entrypoint.py +0 -89
- uptimely_core-0.1.0/src/uptimely/docs/docs.py +0 -120
- uptimely_core-0.1.0/src/uptimely/engine/engine.py +0 -405
- uptimely_core-0.1.0/src/uptimely/mcp/__init__.py +0 -5
- uptimely_core-0.1.0/src/uptimely/plan/__init__.py +0 -6
- uptimely_core-0.1.0/src/uptimely/spec/__init__.py +0 -50
- uptimely_core-0.1.0/src/uptimely/spec/json_spec/__init__.py +0 -1
- uptimely_core-0.1.0/src/uptimely/spec/json_spec/json_functions.py +0 -294
- uptimely_core-0.1.0/src/uptimely/spec/json_spec/json_model/__init__.py +0 -63
- uptimely_core-0.1.0/src/uptimely/spec/json_spec/json_model/functions.py +0 -65
- uptimely_core-0.1.0/src/uptimely/spec/json_spec/json_model/specification.py +0 -116
- uptimely_core-0.1.0/src/uptimely/spec/json_spec/json_parser.py +0 -341
- uptimely_core-0.1.0/src/uptimely/spec/json_spec/json_serializer.py +0 -32
- uptimely_core-0.1.0/src/uptimely/spec/python_spec/__init__.py +0 -7
- uptimely_core-0.1.0/src/uptimely/spec/python_spec/dataset.py +0 -195
- uptimely_core-0.1.0/src/uptimely/spec/python_spec/entity.py +0 -45
- uptimely_core-0.1.0/src/uptimely/spec/python_spec/mappings.py +0 -112
- uptimely_core-0.1.0/src/uptimely/spec/python_spec/ref.py +0 -69
- uptimely_core-0.1.0/src/uptimely/spec/python_spec/spec.py +0 -74
- uptimely_core-0.1.0/src/uptimely/spec/validation.py +0 -488
- uptimely_core-0.1.0/src/uptimely/templates/spec/datasets.html.j2 +0 -5
- uptimely_core-0.1.0/src/uptimely/templates/spec/dimensions.html.j2 +0 -5
- uptimely_core-0.1.0/src/uptimely/templates/spec/entities.html.j2 +0 -5
- uptimely_core-0.1.0/src/uptimely/templates/spec/features.html.j2 +0 -5
- uptimely_core-0.1.0/src/uptimely/templates/spec/functions.html.j2 +0 -5
- uptimely_core-0.1.0/src/uptimely/templates/spec/overview.html.j2 +0 -5
- {uptimely_core-0.1.0 → uptimely_core-0.2.0.dev0}/LICENSE +0 -0
- {uptimely_core-0.1.0 → uptimely_core-0.2.0.dev0}/src/uptimely/cli/__init__.py +0 -0
- {uptimely_core-0.1.0/src/uptimely → uptimely_core-0.2.0.dev0/src/uptimely/compiler}/plan/serialization.py +0 -0
- {uptimely_core-0.1.0/src/uptimely/docs → uptimely_core-0.2.0.dev0/src/uptimely/explorer}/__init__.py +0 -0
- {uptimely_core-0.1.0 → uptimely_core-0.2.0.dev0}/src/uptimely/py.typed +0 -0
- {uptimely_core-0.1.0 → uptimely_core-0.2.0.dev0}/src/uptimely/templates/graph/base.html.j2 +0 -0
- {uptimely_core-0.1.0 → uptimely_core-0.2.0.dev0}/src/uptimely/templates/graph/feature_graph.html.j2 +0 -0
- {uptimely_core-0.1.0 → uptimely_core-0.2.0.dev0}/src/uptimely/templates/graph/feature_graph_shared.html.j2 +0 -0
- {uptimely_core-0.1.0 → uptimely_core-0.2.0.dev0}/src/uptimely/templates/graph/feature_renderer_2d.js.j2 +0 -0
- {uptimely_core-0.1.0 → uptimely_core-0.2.0.dev0}/src/uptimely/templates/graph/feature_renderer_3d.js.j2 +0 -0
- {uptimely_core-0.1.0 → uptimely_core-0.2.0.dev0}/src/uptimely/templates/graph/view_controller.js.j2 +0 -0
- {uptimely_core-0.1.0 → uptimely_core-0.2.0.dev0}/src/uptimely/templates/graph/view_controls.html.j2 +0 -0
- {uptimely_core-0.1.0 → uptimely_core-0.2.0.dev0}/src/uptimely/templates/plan/graph.html.j2 +0 -0
- {uptimely_core-0.1.0 → uptimely_core-0.2.0.dev0}/src/uptimely/templates/plan/overview.html.j2 +0 -0
- {uptimely_core-0.1.0 → uptimely_core-0.2.0.dev0}/src/uptimely/templates/plan/stages.html.j2 +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: uptimely-core
|
|
3
|
-
Version: 0.
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 0.2.0.dev0
|
|
4
|
+
Summary: Manage data-driven numerical analytics with complex dependencies at scale
|
|
5
5
|
License-Expression: MIT
|
|
6
6
|
License-File: LICENSE
|
|
7
7
|
Keywords: analytics,declarative,industrial,feature-engineering,polars
|
|
@@ -24,15 +24,18 @@ Requires-Dist: numpy (>=1.26,<3.0)
|
|
|
24
24
|
Requires-Dist: polars (>=1.0,<2.0)
|
|
25
25
|
Requires-Dist: pydantic (>=2.10,<3.0)
|
|
26
26
|
Project-URL: Documentation, https://uptimely-ai.github.io/uptimely-core
|
|
27
|
-
Project-URL: Homepage,
|
|
27
|
+
Project-URL: Homepage, http://uptimely.ai/core/
|
|
28
28
|
Project-URL: Repository, https://github.com/uptimely-ai/uptimely-core
|
|
29
29
|
Description-Content-Type: text/markdown
|
|
30
30
|
|
|
31
31
|
# Uptimely Core
|
|
32
32
|
|
|
33
|
-
Uptimely Core is an open source Python package for declarative numerical
|
|
33
|
+
Uptimely Core is an open source Python package for declarative numerical
|
|
34
|
+
analytics with complex dependencies at scale.
|
|
34
35
|
|
|
35
|
-
|
|
36
|
+
Analytics definitions describe workflows in JSON, using a declarative model
|
|
37
|
+
inspired by OpenAPI and Kubernetes. The compiler generates plans from the
|
|
38
|
+
analytics; the package can also render dependency graphs and documentation.
|
|
36
39
|
|
|
37
40
|
Ships with simple engine and plans to integrate to common execution backends.
|
|
38
41
|
|
|
@@ -56,15 +59,23 @@ Read more at [uptimely.ai website](https://uptimely.ai).
|
|
|
56
59
|
Python 3.13 or newer is required. Install the package, download the examples
|
|
57
60
|
and run.
|
|
58
61
|
|
|
62
|
+
With pip:
|
|
63
|
+
|
|
59
64
|
```sh
|
|
60
65
|
pip install uptimely-core
|
|
61
66
|
uptimely examples download
|
|
62
|
-
|
|
67
|
+
uptimely explorer serve --project-root examples/pump_analytics
|
|
63
68
|
```
|
|
64
69
|
|
|
65
|
-
|
|
70
|
+
With Poetry, from your Poetry project:
|
|
71
|
+
|
|
72
|
+
```sh
|
|
73
|
+
poetry add uptimely-core
|
|
74
|
+
poetry run uptimely examples download
|
|
75
|
+
poetry run uptimely explorer serve --project-root examples/pump_analytics
|
|
76
|
+
```
|
|
66
77
|
|
|
67
|
-
Explore the examples files, generated resources and modify for the needs of your own project.
|
|
78
|
+
More use cases in [examples](examples/README.md). Explore the examples files, generated resources and modify for the needs of your own project.
|
|
68
79
|
|
|
69
80
|
## Documentation
|
|
70
81
|
|
|
@@ -77,7 +88,7 @@ Explore the [documentation site](https://uptimely-ai.github.io/uptimely-core/).
|
|
|
77
88
|
| [`docs/`](docs/index.md) | Architecture, specification, and development documentation. |
|
|
78
89
|
| [`examples/`](examples/README.md) | Runnable examples and generated artifacts. |
|
|
79
90
|
| [`scripts/`](scripts) | Code snippets for repository management |
|
|
80
|
-
| [`src/uptimely/`](src/uptimely/) | Package implementation for
|
|
91
|
+
| [`src/uptimely/`](src/uptimely/) | Package implementation for analytics, compilation, dependencies, documentation, and execution. |
|
|
81
92
|
| [`tests/`](tests/) | Automated tests for the package and examples. |
|
|
82
93
|
|
|
83
94
|
## Development
|
|
@@ -4,8 +4,8 @@ build-backend = "poetry.core.masonry.api"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "uptimely-core"
|
|
7
|
-
version = "0.
|
|
8
|
-
description = "
|
|
7
|
+
version = "0.2.0.dev0"
|
|
8
|
+
description = "Manage data-driven numerical analytics with complex dependencies at scale"
|
|
9
9
|
authors = [{ name = "Mikael Ahonen", email = "mikael.ahonen@uptimely.ai" }]
|
|
10
10
|
license = "MIT"
|
|
11
11
|
license-files = ["LICENSE"]
|
|
@@ -39,7 +39,7 @@ uptimely = "uptimely.cli.cli:main"
|
|
|
39
39
|
uptimely-mcp = "uptimely.mcp.server:main"
|
|
40
40
|
|
|
41
41
|
[project.urls]
|
|
42
|
-
Homepage = "
|
|
42
|
+
Homepage = "http://uptimely.ai/core/"
|
|
43
43
|
Repository = "https://github.com/uptimely-ai/uptimely-core"
|
|
44
44
|
Documentation = "https://uptimely-ai.github.io/uptimely-core"
|
|
45
45
|
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
# Uptimely Core
|
|
2
2
|
|
|
3
|
-
Uptimely Core is an open source Python package for declarative numerical
|
|
3
|
+
Uptimely Core is an open source Python package for declarative numerical
|
|
4
|
+
analytics with complex dependencies at scale.
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
Analytics definitions describe workflows in JSON, using a declarative model
|
|
7
|
+
inspired by OpenAPI and Kubernetes. The compiler generates plans from the
|
|
8
|
+
analytics; the package can also render dependency graphs and documentation.
|
|
6
9
|
|
|
7
10
|
Ships with simple engine and plans to integrate to common execution backends.
|
|
8
11
|
|
|
@@ -26,15 +29,23 @@ Read more at [uptimely.ai website](https://uptimely.ai).
|
|
|
26
29
|
Python 3.13 or newer is required. Install the package, download the examples
|
|
27
30
|
and run.
|
|
28
31
|
|
|
32
|
+
With pip:
|
|
33
|
+
|
|
29
34
|
```sh
|
|
30
35
|
pip install uptimely-core
|
|
31
36
|
uptimely examples download
|
|
32
|
-
|
|
37
|
+
uptimely explorer serve --project-root examples/pump_analytics
|
|
33
38
|
```
|
|
34
39
|
|
|
35
|
-
|
|
40
|
+
With Poetry, from your Poetry project:
|
|
41
|
+
|
|
42
|
+
```sh
|
|
43
|
+
poetry add uptimely-core
|
|
44
|
+
poetry run uptimely examples download
|
|
45
|
+
poetry run uptimely explorer serve --project-root examples/pump_analytics
|
|
46
|
+
```
|
|
36
47
|
|
|
37
|
-
Explore the examples files, generated resources and modify for the needs of your own project.
|
|
48
|
+
More use cases in [examples](examples/README.md). Explore the examples files, generated resources and modify for the needs of your own project.
|
|
38
49
|
|
|
39
50
|
## Documentation
|
|
40
51
|
|
|
@@ -47,7 +58,7 @@ Explore the [documentation site](https://uptimely-ai.github.io/uptimely-core/).
|
|
|
47
58
|
| [`docs/`](docs/index.md) | Architecture, specification, and development documentation. |
|
|
48
59
|
| [`examples/`](examples/README.md) | Runnable examples and generated artifacts. |
|
|
49
60
|
| [`scripts/`](scripts) | Code snippets for repository management |
|
|
50
|
-
| [`src/uptimely/`](src/uptimely/) | Package implementation for
|
|
61
|
+
| [`src/uptimely/`](src/uptimely/) | Package implementation for analytics, compilation, dependencies, documentation, and execution. |
|
|
51
62
|
| [`tests/`](tests/) | Automated tests for the package and examples. |
|
|
52
63
|
|
|
53
64
|
## Development
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"""Public package namespace for uptimely."""
|
|
2
|
+
|
|
3
|
+
from .analytics import (
|
|
4
|
+
Analytics,
|
|
5
|
+
Call,
|
|
6
|
+
Dimension,
|
|
7
|
+
Entity,
|
|
8
|
+
FeatureGraph,
|
|
9
|
+
Function,
|
|
10
|
+
PreparedAnalytics,
|
|
11
|
+
PythonAnalytics,
|
|
12
|
+
SubGraph,
|
|
13
|
+
from_python,
|
|
14
|
+
load_analytics,
|
|
15
|
+
prepare_analytics,
|
|
16
|
+
write_document,
|
|
17
|
+
)
|
|
18
|
+
from .compiler import CallableGraph, CallableNode, Compiler, ExecutionPlan
|
|
19
|
+
from .engine import Engine
|
|
20
|
+
|
|
21
|
+
__all__ = [
|
|
22
|
+
"Analytics",
|
|
23
|
+
"Call",
|
|
24
|
+
"CallableGraph",
|
|
25
|
+
"CallableNode",
|
|
26
|
+
"Compiler",
|
|
27
|
+
"Dimension",
|
|
28
|
+
"Entity",
|
|
29
|
+
"ExecutionPlan",
|
|
30
|
+
"Function",
|
|
31
|
+
"PythonAnalytics",
|
|
32
|
+
"PreparedAnalytics",
|
|
33
|
+
"from_python",
|
|
34
|
+
"load_analytics",
|
|
35
|
+
"prepare_analytics",
|
|
36
|
+
"write_document",
|
|
37
|
+
"SubGraph",
|
|
38
|
+
"FeatureGraph",
|
|
39
|
+
"Engine",
|
|
40
|
+
]
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"""Public package namespace for OpenAnalytics analytics."""
|
|
2
|
+
|
|
3
|
+
from uptimely.row_context import RowContext
|
|
4
|
+
|
|
5
|
+
from .api import from_python, load_analytics, prepare_analytics
|
|
6
|
+
from .feature_graph import FeatureGraph, SubGraph
|
|
7
|
+
from .json.codec import write_document
|
|
8
|
+
from .model import (
|
|
9
|
+
Analytics,
|
|
10
|
+
Argument,
|
|
11
|
+
Binding,
|
|
12
|
+
Dataset,
|
|
13
|
+
Dimension,
|
|
14
|
+
Entity,
|
|
15
|
+
Feature,
|
|
16
|
+
FunctionCatalog,
|
|
17
|
+
Mapping,
|
|
18
|
+
Order,
|
|
19
|
+
RowScope,
|
|
20
|
+
)
|
|
21
|
+
from .python import (
|
|
22
|
+
PythonAnalytics,
|
|
23
|
+
bind,
|
|
24
|
+
dataset,
|
|
25
|
+
dimension,
|
|
26
|
+
entity,
|
|
27
|
+
feature,
|
|
28
|
+
mapping,
|
|
29
|
+
ref,
|
|
30
|
+
row_context,
|
|
31
|
+
)
|
|
32
|
+
from .resolved import Call, Function, PreparedAnalytics
|
|
33
|
+
|
|
34
|
+
__all__ = [
|
|
35
|
+
"Argument",
|
|
36
|
+
"Binding",
|
|
37
|
+
"Call",
|
|
38
|
+
"Dataset",
|
|
39
|
+
"Dimension",
|
|
40
|
+
"Entity",
|
|
41
|
+
"Feature",
|
|
42
|
+
"FeatureGraph",
|
|
43
|
+
"Function",
|
|
44
|
+
"FunctionCatalog",
|
|
45
|
+
"Mapping",
|
|
46
|
+
"Order",
|
|
47
|
+
"PythonAnalytics",
|
|
48
|
+
"RowContext",
|
|
49
|
+
"RowScope",
|
|
50
|
+
"Analytics",
|
|
51
|
+
"PreparedAnalytics",
|
|
52
|
+
"from_python",
|
|
53
|
+
"load_analytics",
|
|
54
|
+
"prepare_analytics",
|
|
55
|
+
"write_document",
|
|
56
|
+
"SubGraph",
|
|
57
|
+
"bind",
|
|
58
|
+
"dataset",
|
|
59
|
+
"dimension",
|
|
60
|
+
"entity",
|
|
61
|
+
"feature",
|
|
62
|
+
"mapping",
|
|
63
|
+
"ref",
|
|
64
|
+
"row_context",
|
|
65
|
+
]
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"""Build and load validated analytics through explicit application operations."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import pathlib
|
|
6
|
+
|
|
7
|
+
from . import model, resolution, resolved, validation
|
|
8
|
+
from .json import codec
|
|
9
|
+
from .python import conversion
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def prepare_analytics(document: model.Analytics) -> resolved.PreparedAnalytics:
|
|
13
|
+
"""Resolve and validate a document without adding derived state to it.
|
|
14
|
+
|
|
15
|
+
Preparation uses declarative metadata, not executable Python signatures.
|
|
16
|
+
Rebuild the result after changing the document; it is not an automatic cache.
|
|
17
|
+
|
|
18
|
+
Args:
|
|
19
|
+
document: An analytics document that conforms to the document model.
|
|
20
|
+
|
|
21
|
+
Returns:
|
|
22
|
+
The document paired with its resolved functions and calls.
|
|
23
|
+
|
|
24
|
+
Raises:
|
|
25
|
+
ValueError: Analytics references, mappings, or dependencies are invalid.
|
|
26
|
+
"""
|
|
27
|
+
functions, calls = resolution.resolve_functions(document)
|
|
28
|
+
validation.validate_prepared(document, functions, calls)
|
|
29
|
+
return resolved.PreparedAnalytics(document=document, functions=functions, calls=calls)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def load_analytics(path: str | pathlib.Path) -> model.Analytics:
|
|
33
|
+
"""Load and semantically validate an analytics JSON file or directory.
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
path: A JSON document or a directory containing ``analytics.json``.
|
|
37
|
+
|
|
38
|
+
Returns:
|
|
39
|
+
A validated analytics document without attached derived state.
|
|
40
|
+
|
|
41
|
+
Raises:
|
|
42
|
+
OSError: The JSON document cannot be read.
|
|
43
|
+
ValueError: The document or its analytics declarations are invalid.
|
|
44
|
+
"""
|
|
45
|
+
document = model.Analytics.model_validate(codec.load_document(path))
|
|
46
|
+
prepare_analytics(document)
|
|
47
|
+
return document
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def from_python(
|
|
51
|
+
datasets: conversion.Datasets | None = None,
|
|
52
|
+
functions: conversion.Functions | None = None,
|
|
53
|
+
name: str | None = None,
|
|
54
|
+
dimensions: conversion.Dimensions | None = None,
|
|
55
|
+
*,
|
|
56
|
+
entities: conversion.Entities | None = None,
|
|
57
|
+
) -> model.Analytics:
|
|
58
|
+
"""Convert Python declarations and semantically validate the resulting model.
|
|
59
|
+
|
|
60
|
+
Args:
|
|
61
|
+
datasets: Dataset declarations wrapped in a single entity.
|
|
62
|
+
functions: Explicit catalog, or infer it from Python declarations.
|
|
63
|
+
name: Optional analytics name and synthetic entity identifier.
|
|
64
|
+
dimensions: Global dimension declarations.
|
|
65
|
+
entities: Explicit entity declarations, mutually exclusive with datasets.
|
|
66
|
+
|
|
67
|
+
Returns:
|
|
68
|
+
A validated analytics document without attached derived state.
|
|
69
|
+
|
|
70
|
+
Raises:
|
|
71
|
+
TypeError: Declarations have unsupported types.
|
|
72
|
+
ValueError: Declarations conflict or analytics semantics are invalid.
|
|
73
|
+
"""
|
|
74
|
+
document = conversion.to_model(
|
|
75
|
+
datasets=datasets,
|
|
76
|
+
functions=functions,
|
|
77
|
+
name=name,
|
|
78
|
+
dimensions=dimensions,
|
|
79
|
+
entities=entities,
|
|
80
|
+
)
|
|
81
|
+
prepare_analytics(document)
|
|
82
|
+
return document
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"""Shared function-catalog construction, merging, and serialization."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import collections.abc
|
|
6
|
+
|
|
7
|
+
from uptimely import contracts
|
|
8
|
+
|
|
9
|
+
from . import model as analytics_model
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def function_template(
|
|
13
|
+
function_id: str,
|
|
14
|
+
operation: contracts.FunctionOperation,
|
|
15
|
+
entrypoint: str,
|
|
16
|
+
args: dict[str, analytics_model.Argument],
|
|
17
|
+
) -> analytics_model.FunctionTemplate:
|
|
18
|
+
"""Create a function template for the analytics document from its declarations."""
|
|
19
|
+
return analytics_model.FunctionTemplate(
|
|
20
|
+
id=function_id,
|
|
21
|
+
operation=operation,
|
|
22
|
+
returns=contracts.OPERATION_RETURN_KINDS[operation],
|
|
23
|
+
entrypoint=entrypoint,
|
|
24
|
+
args=args,
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def merge_function_catalogs(
|
|
29
|
+
catalogs: collections.abc.Iterable[analytics_model.FunctionCatalog],
|
|
30
|
+
) -> dict[str, analytics_model.FunctionTemplate]:
|
|
31
|
+
"""Merge identical definitions and reject conflicting templates."""
|
|
32
|
+
functions: dict[str, analytics_model.FunctionTemplate] = {}
|
|
33
|
+
for catalog in catalogs:
|
|
34
|
+
for function_id, function in catalog.root.items():
|
|
35
|
+
current = functions.get(function_id)
|
|
36
|
+
if current is None:
|
|
37
|
+
functions[function_id] = function
|
|
38
|
+
continue
|
|
39
|
+
if current != function:
|
|
40
|
+
raise ValueError(f"Conflicting function definition for '{function_id}'")
|
|
41
|
+
return functions
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"""Feature dependency graph models and visualization."""
|
|
2
|
+
|
|
3
|
+
from .graph import FeatureGraph, GraphBase, Node, NodeMeta, SubGraph
|
|
4
|
+
from .models import FeatureNode, FunctionNode
|
|
5
|
+
|
|
6
|
+
__all__ = [
|
|
7
|
+
"FeatureGraph",
|
|
8
|
+
"FeatureNode",
|
|
9
|
+
"FunctionNode",
|
|
10
|
+
"GraphBase",
|
|
11
|
+
"Node",
|
|
12
|
+
"NodeMeta",
|
|
13
|
+
"SubGraph",
|
|
14
|
+
]
|
|
@@ -5,9 +5,9 @@ import re
|
|
|
5
5
|
import graphable as graphable_
|
|
6
6
|
from graphable import views
|
|
7
7
|
|
|
8
|
-
from
|
|
9
|
-
from
|
|
10
|
-
|
|
8
|
+
from .. import api, resolved
|
|
9
|
+
from .. import model as analytics_model
|
|
10
|
+
from .. import references as bindings
|
|
11
11
|
from . import models
|
|
12
12
|
|
|
13
13
|
Node = graphable_.graphable.Graphable
|
|
@@ -19,7 +19,7 @@ class GraphBase:
|
|
|
19
19
|
|
|
20
20
|
graph: graphable_.graph.Graph
|
|
21
21
|
_node_index: dict[str, Node]
|
|
22
|
-
_function_catalog: dict[str,
|
|
22
|
+
_function_catalog: dict[str, resolved.Function]
|
|
23
23
|
_explicit_output_names: list[str] | None
|
|
24
24
|
|
|
25
25
|
@staticmethod
|
|
@@ -142,29 +142,30 @@ class GraphBase:
|
|
|
142
142
|
class FeatureGraph(GraphBase):
|
|
143
143
|
"""Global dependency graph built from all feature mappings."""
|
|
144
144
|
|
|
145
|
-
def __init__(self,
|
|
145
|
+
def __init__(self, analytics: analytics_model.Analytics) -> None:
|
|
146
146
|
"""Load analytics function calls and build the complete dependency graph."""
|
|
147
|
+
prepared = api.prepare_analytics(analytics)
|
|
147
148
|
self.functions = [
|
|
148
|
-
function for function in
|
|
149
|
+
function for function in prepared.functions if function.role == "analytics"
|
|
149
150
|
]
|
|
150
|
-
self._graph_operations: list[tuple[
|
|
151
|
+
self._graph_operations: list[tuple[resolved.Function, str, str, list[str], list[str]]] = []
|
|
151
152
|
vectorize_functions = {function.id: function for function in self.functions}
|
|
152
153
|
|
|
153
|
-
for entity_id, entity in
|
|
154
|
+
for entity_id, entity in analytics.entities.items():
|
|
154
155
|
for dataset in entity.datasets:
|
|
155
156
|
for operation_id, mapping in dataset.mappings.items():
|
|
156
|
-
|
|
157
|
-
template =
|
|
157
|
+
operation = bindings.mapping_operation(mapping, analytics.functions)
|
|
158
|
+
template = analytics.functions[mapping.binding.function]
|
|
158
159
|
function = (
|
|
159
160
|
vectorize_functions.get(mapping.binding.function)
|
|
160
|
-
if
|
|
161
|
-
else
|
|
161
|
+
if operation == "vectorize"
|
|
162
|
+
else resolved.Function(
|
|
162
163
|
id=mapping.binding.function,
|
|
163
164
|
type="python_function",
|
|
164
165
|
return_type="dataframe",
|
|
165
166
|
info={"description": getattr(template, "description", None)},
|
|
166
167
|
entrypoint=template.entrypoint,
|
|
167
|
-
role=
|
|
168
|
+
role=operation,
|
|
168
169
|
)
|
|
169
170
|
)
|
|
170
171
|
if function is None:
|
|
@@ -183,13 +184,13 @@ class FeatureGraph(GraphBase):
|
|
|
183
184
|
[
|
|
184
185
|
feature_id
|
|
185
186
|
for feature_id in mapping.output_features
|
|
186
|
-
if feature_id not in
|
|
187
|
+
if feature_id not in analytics.dimensions
|
|
187
188
|
],
|
|
188
189
|
list(dict.fromkeys(dependencies)),
|
|
189
190
|
)
|
|
190
191
|
)
|
|
191
192
|
|
|
192
|
-
self.
|
|
193
|
+
self.analytics = analytics
|
|
193
194
|
self._function_catalog = {function.id: function for function in self.functions}
|
|
194
195
|
self._node_index: dict[str, Node] = {}
|
|
195
196
|
self._explicit_output_names = None
|
|
@@ -199,7 +200,7 @@ class FeatureGraph(GraphBase):
|
|
|
199
200
|
self,
|
|
200
201
|
function_name: str,
|
|
201
202
|
dependencies: list[str],
|
|
202
|
-
function:
|
|
203
|
+
function: resolved.Function | None = None,
|
|
203
204
|
) -> set[str]:
|
|
204
205
|
"""Return direct parent feature names for a bound feature."""
|
|
205
206
|
function = function or self._function_catalog.get(function_name)
|
|
@@ -235,7 +236,7 @@ class FeatureGraph(GraphBase):
|
|
|
235
236
|
output
|
|
236
237
|
for _function, _entity, _operation_id, outputs, _dependencies in self._graph_operations
|
|
237
238
|
for output in outputs
|
|
238
|
-
if output not in self.
|
|
239
|
+
if output not in self.analytics.dimensions
|
|
239
240
|
}
|
|
240
241
|
dependency_names = {
|
|
241
242
|
parent
|
|
@@ -263,20 +264,17 @@ class FeatureGraph(GraphBase):
|
|
|
263
264
|
),
|
|
264
265
|
)
|
|
265
266
|
|
|
266
|
-
for entity_id, entity in self.
|
|
267
|
+
for entity_id, entity in self.analytics.entities.items():
|
|
267
268
|
for dataset in entity.datasets:
|
|
268
269
|
for mapping in dataset.mappings.values():
|
|
269
|
-
|
|
270
|
-
mapping, self.specification.functions
|
|
271
|
-
)
|
|
270
|
+
operation = bindings.mapping_operation(mapping, self.analytics.functions)
|
|
272
271
|
for name in mapping.output_features:
|
|
273
272
|
feature = dataset.features[name]
|
|
274
273
|
register_feature_metadata(
|
|
275
274
|
name,
|
|
276
275
|
feature.type,
|
|
277
276
|
entity_id,
|
|
278
|
-
is_source_input=
|
|
279
|
-
and operation_type != "vectorize",
|
|
277
|
+
is_source_input=operation != "collapse" and operation != "vectorize",
|
|
280
278
|
)
|
|
281
279
|
for function, entity, _operation_id, outputs, _dependencies in self._graph_operations:
|
|
282
280
|
for output in outputs:
|
|
@@ -293,7 +291,7 @@ class FeatureGraph(GraphBase):
|
|
|
293
291
|
|
|
294
292
|
def feature_meta(
|
|
295
293
|
name: str,
|
|
296
|
-
function:
|
|
294
|
+
function: resolved.Function | None = None,
|
|
297
295
|
entity: str | None = None,
|
|
298
296
|
data_type: str | None = None,
|
|
299
297
|
) -> models.FeatureNode:
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
import dataclasses
|
|
2
2
|
|
|
3
|
-
from uptimely import
|
|
3
|
+
from uptimely import render
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
def _filled_fields(**fields: object) -> dict:
|
|
7
|
-
"""Return fields with values useful for graph rendering."""
|
|
8
|
-
return {key: value for key, value in fields.items() if value is not None}
|
|
5
|
+
from .. import resolved
|
|
9
6
|
|
|
10
7
|
|
|
11
8
|
@dataclasses.dataclass(frozen=True)
|
|
@@ -15,7 +12,7 @@ class FunctionNode:
|
|
|
15
12
|
name: str
|
|
16
13
|
features: tuple[str, ...]
|
|
17
14
|
entity: str | None
|
|
18
|
-
function:
|
|
15
|
+
function: resolved.Function | None = dataclasses.field(default=None, compare=False, hash=False)
|
|
19
16
|
|
|
20
17
|
@property
|
|
21
18
|
def node_id(self) -> str:
|
|
@@ -29,9 +26,9 @@ class FunctionNode:
|
|
|
29
26
|
def __repr__(self) -> str:
|
|
30
27
|
return self.name
|
|
31
28
|
|
|
32
|
-
def to_render_data(self, node_type: str = "function") -> dict:
|
|
29
|
+
def to_render_data(self, node_type: str = "function") -> dict[str, object]:
|
|
33
30
|
"""Return display metadata for rendering this function node."""
|
|
34
|
-
return
|
|
31
|
+
return render.filled_fields(
|
|
35
32
|
node_type=node_type,
|
|
36
33
|
is_function=True,
|
|
37
34
|
label=self.name,
|
|
@@ -77,9 +74,9 @@ class FeatureNode:
|
|
|
77
74
|
"""Whether this feature is both produced and consumed by the graph."""
|
|
78
75
|
return self.is_input and self.is_output
|
|
79
76
|
|
|
80
|
-
def to_render_data(self, node_type: str) -> dict:
|
|
77
|
+
def to_render_data(self, node_type: str) -> dict[str, object]:
|
|
81
78
|
"""Return display metadata for rendering this feature node."""
|
|
82
|
-
return
|
|
79
|
+
return render.filled_fields(
|
|
83
80
|
node_type=node_type,
|
|
84
81
|
is_function=False,
|
|
85
82
|
label=self.name,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Analytics JSON document encoding and I/O."""
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"""JSON serialization helpers for analytics models."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
import pathlib
|
|
7
|
+
import typing
|
|
8
|
+
|
|
9
|
+
from uptimely import storage as storage_module
|
|
10
|
+
|
|
11
|
+
if typing.TYPE_CHECKING:
|
|
12
|
+
from .. import model as analytics_model
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def load_document(path: str | pathlib.Path) -> dict[str, typing.Any]:
|
|
16
|
+
"""Read one JSON document, rejecting unsupported multi-file definitions."""
|
|
17
|
+
if storage_module.Storage.is_dir(path):
|
|
18
|
+
path = storage_module.Storage.join(path, "analytics.json")
|
|
19
|
+
analytics_definition = json.loads(storage_module.Storage.read(path))
|
|
20
|
+
if analytics_definition.get("includes", []) or analytics_definition.get("external_specs", []):
|
|
21
|
+
raise ValueError("Analytics must be defined in a single JSON file")
|
|
22
|
+
return analytics_definition
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def to_document(analytics_definition: analytics_model.Analytics) -> dict[str, typing.Any]:
|
|
26
|
+
"""Encode document models using the analytics document's identifier rules."""
|
|
27
|
+
payload = analytics_definition.model_dump(exclude_none=False)
|
|
28
|
+
for entity_id, entity in analytics_definition.entities.items():
|
|
29
|
+
serialized_entity = payload["entities"][entity_id]
|
|
30
|
+
for index, dataset in enumerate(entity.datasets):
|
|
31
|
+
serialized_entity["datasets"][index]["id"] = dataset.id
|
|
32
|
+
return payload
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def write_document(
|
|
36
|
+
analytics_definition: analytics_model.Analytics, path: str | pathlib.Path
|
|
37
|
+
) -> str:
|
|
38
|
+
"""Write an analytics document without mutating the source model."""
|
|
39
|
+
target = pathlib.Path(path)
|
|
40
|
+
target.parent.mkdir(parents=True, exist_ok=True)
|
|
41
|
+
target.write_text(json.dumps(to_document(analytics_definition), indent=2), encoding="utf-8")
|
|
42
|
+
return str(target)
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"""Analytics document models, independent of their authoring format."""
|
|
2
|
+
|
|
3
|
+
from .analytics import SUPPORTED_ANALYTICS_VERSION, Analytics
|
|
4
|
+
from .common import (
|
|
5
|
+
AnalyticsSource,
|
|
6
|
+
Argument,
|
|
7
|
+
Binding,
|
|
8
|
+
BindingArgument,
|
|
9
|
+
Dimension,
|
|
10
|
+
StrictModel,
|
|
11
|
+
)
|
|
12
|
+
from .dataset import (
|
|
13
|
+
Dataset,
|
|
14
|
+
Entity,
|
|
15
|
+
Feature,
|
|
16
|
+
Mapping,
|
|
17
|
+
MappingFeatures,
|
|
18
|
+
Order,
|
|
19
|
+
RowScope,
|
|
20
|
+
)
|
|
21
|
+
from .functions import (
|
|
22
|
+
FUNCTION_OPERATIONS,
|
|
23
|
+
FUNCTION_TYPES,
|
|
24
|
+
FunctionCatalog,
|
|
25
|
+
FunctionTemplate,
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
__all__ = [
|
|
29
|
+
"FUNCTION_OPERATIONS",
|
|
30
|
+
"FUNCTION_TYPES",
|
|
31
|
+
"SUPPORTED_ANALYTICS_VERSION",
|
|
32
|
+
"Analytics",
|
|
33
|
+
"AnalyticsSource",
|
|
34
|
+
"Argument",
|
|
35
|
+
"Binding",
|
|
36
|
+
"BindingArgument",
|
|
37
|
+
"Dataset",
|
|
38
|
+
"Dimension",
|
|
39
|
+
"Entity",
|
|
40
|
+
"Feature",
|
|
41
|
+
"FunctionCatalog",
|
|
42
|
+
"FunctionTemplate",
|
|
43
|
+
"Mapping",
|
|
44
|
+
"MappingFeatures",
|
|
45
|
+
"Order",
|
|
46
|
+
"RowScope",
|
|
47
|
+
"StrictModel",
|
|
48
|
+
]
|