|
| 1 | +<div align="center"> |
| 2 | + |
| 3 | + |
| 4 | + |
| 5 | + <br /> |
| 6 | + |
| 7 | + <div> |
| 8 | + <a href="https://pypi.org/project/tracdap-runtime"><img alt="PyPI Version" src="https://img.shields.io/pypi/v/tracdap-runtime.svg?maxAge=3600" /></a> |
| 9 | + <a href="https://pypi.org/project/tracdap-runtime"><img alt="Python Versions" src="https://img.shields.io/pypi/pyversions/tracdap-runtime.svg?maxAge=3600" /></a> |
| 10 | + <a href="https://github.com/finos/tracdap/actions/workflows/packaging.yaml?query=branch%3Amain"><img alt="Packaging status" src="https://github.com/finos/tracdap/actions/workflows/packaging.yaml/badge.svg?branch:main&workflow:CI" /></a> |
| 11 | + <a href="https://github.com/finos/tracdap/actions/workflows/compliance.yaml?query=branch%3Amain"><img alt="Compliance status" src="https://github.com/finos/tracdap/actions/workflows/compliance.yaml/badge.svg?branch:main&workflow:CI" /></a> |
| 12 | + <a href="https://github.com/pandas-dev/pandas/blob/main/LICENSE"><img alt="License - Apache-2.0" src="https://img.shields.io/pypi/l/tracdap-runtime.svg" /></a> |
| 13 | + <a href="https://community.finos.org/docs/governance/software-projects/stages/incubating/"><img alt="FINOS - Incubating" src="https://cdn.jsdelivr.net/gh/finos/contrib-toolbox@master/images/badge-incubating.svg" /></a> |
| 14 | + </div> |
| 15 | + |
| 16 | + <p> |
| 17 | + <a href="https://www.fintrac.co.uk/">Homepage</a> |
| 18 | + ◆ <a href="https://docs.fintrac.co.uk/versions/latest/modelling">Documentation</a> |
| 19 | + ◆ <a href="https://github.com/fintrac-hub/examples">Examples</a> |
| 20 | + ◆ <a href="https://github.com/finos/tracdap">Source Code</a> |
| 21 | + ◆ <a href="https://github.com/finos/tracdap/issues">Issue Tracker</a> |
| 22 | + </p> |
| 23 | +</div> |
| 24 | + |
| 25 | + |
1 | 26 | # TRAC Model Runtime for Python
|
2 | 27 |
|
3 |
| -*TRAC D.A.P. is a next-generation data and analytics platform for use in highly regulated environments* |
| 28 | +The TRAC Model Runtime is a lightweight package for building portable, |
| 29 | +production-grade Python models. Models created with the runtime can be |
| 30 | +executed anywhere, from local development environments to enterprise |
| 31 | +production systems. The runtime can be used independently of the broader |
| 32 | +TRAC platform and provides a simple framework in which to build, ship, |
| 33 | +and share models. |
| 34 | + |
| 35 | +Each model defines its parameters, inputs and outputs, and the runtime |
| 36 | +provides the execution context, ensuring that models always receive valid |
| 37 | +data and parameters. Taking responsibility for data access, marshalling |
| 38 | +and formatting out of the model code allows developers to focus on model |
| 39 | +logic, safe in the knowledge that the model will behave consistently |
| 40 | +across environments. |
| 41 | + |
| 42 | +For a complete guide to writing models in the TRAC framework, see the |
| 43 | +[online documentation](https://docs.fintrac.co.uk/versions/latest/modelling). |
4 | 44 |
|
5 |
| -The TRAC model runtime provides all the APIs needed to write models for the TRAC platform. |
6 |
| -It includes an implementation of the runtime library that can be used as a development |
7 |
| -sandbox, so you can run and debug TRAC models right away from your favourite IDE or notebook. |
8 |
| -A number of tools are included to make it easy to plug in development data and configuration. |
9 |
| -When your models are ready they can be loaded into a real instance of TRAC for testing and |
10 |
| -eventual deployment. |
11 | 45 |
|
12 |
| -Documentation for the TRAC platform is available on our website at |
13 |
| -[tracdap.finos.org](https://tracdap.finos.org). |
| 46 | +## 📦 Requirements |
14 | 47 |
|
15 |
| -## Requirements |
| 48 | +* **Python :** 3.10 or later |
| 49 | +* **Tools :** Any popular IDE (PyCharm, VS Code, etc.) |
| 50 | +* **Pandas :** Version 1.2 and later are supported |
| 51 | +* **Polars :** Version 1.0 and later are supported |
16 | 52 |
|
17 |
| -The TRAC runtime for Python has these requirements: |
| 53 | +*Some 3rd party libraries may have additional version constraints, |
| 54 | +for example, Pandas 1.5 is not available for Python 3.12 or later.* |
18 | 55 |
|
19 |
| -* Python: 3.9 up to 3.13 |
20 |
| -* Pandas: 1.2 up to 2.2 (optional) |
21 |
| -* NumPy: 1.2 up to 2.2 (optional, required by Pandas) |
22 |
| -* Polars: 1.X (optional) |
23 | 56 |
|
24 |
| -3rd party libraries may impose additional constraints on supported versions of key libraries. |
25 |
| -For example, Pandas 1.5 is not available for Python 3.12 or 3.13, while NumPy 2.0 is only |
26 |
| -compatible with Pandas 2.1 and later. |
| 57 | +## 🚀 Quick start |
27 | 58 |
|
28 |
| -## Installing the runtime |
| 59 | +TRAC can be added to a new or existing Python project using [pip](https://pip.pypa.io): |
29 | 60 |
|
30 |
| -The TRAC runtime package can be installed directly from PyPI: |
| 61 | +```shell |
| 62 | +$ pip install tracdap-runtime |
| 63 | +``` |
31 | 64 |
|
32 |
| - pip install tracdap-runtime |
| 65 | +You will also need to install a data framework (Pandas or Polars) and any other libraries that the model uses. |
33 | 66 |
|
34 |
| -The TRAC runtime depends on Pandas and PySpark, so these libraries will be pulled in as |
35 |
| -dependencies. If you want to target particular versions, install them explicitly first. |
| 67 | +Here is a minimum working example of a TRAC model that performs aggregation on a dataset: |
36 | 68 |
|
| 69 | +```python |
| 70 | +import tracdap.rt.api as trac |
37 | 71 |
|
38 |
| -## Writing a model |
| 72 | +class QuickStartModel(trac.TracModel): |
39 | 73 |
|
40 |
| -Once the runtime is installed you can write your first TRAC model! Start by |
41 |
| -inheriting the TracModel base class, your IDE should be able to generate stubs for you: |
| 74 | + def define_parameters(self): |
42 | 75 |
|
43 |
| - import tracdap.rt.api as trac |
| 76 | + # Define any parameters the model will use |
| 77 | + return trac.define_parameters( |
| 78 | + trac.P("exchange_rate", trac.FLOAT, "EUR / GBP exchange rate") |
| 79 | + ) |
44 | 80 |
|
45 |
| - class SampleModel(trac.TracModel): |
| 81 | + def define_inputs(self): |
46 | 82 |
|
47 |
| - def define_parameters(self) -> tp.Dict[str, trac.ModelParameter]: |
48 |
| - pass |
| 83 | + # Define an input table with the columns and data types that the model needs |
| 84 | + customer_loans = trac.define_input_table( |
| 85 | + trac.F("id", trac.STRING, label="Customer account ID", business_key=True), |
| 86 | + trac.F("region", trac.STRING, label="Customer home region", categorical=True), |
| 87 | + trac.F("loan_amount", trac.FLOAT, label="Principal loan amount (EUR)"), |
| 88 | + label="Customer loans data") |
49 | 89 |
|
50 |
| - def define_inputs(self) -> tp.Dict[str, trac.ModelInputSchema]: |
51 |
| - pass |
| 90 | + return {"customer_loans": customer_loans} |
52 | 91 |
|
53 |
| - def define_outputs(self) -> tp.Dict[str, trac.ModelOutputSchema]: |
54 |
| - pass |
| 92 | + def define_outputs(self): |
55 | 93 |
|
56 |
| - def run_model(self, ctx: trac.TracContext): |
57 |
| - pass |
| 94 | + # Define an output table with the columns and data types that the model will produce |
| 95 | + loans_by_region = trac.define_output_table( |
| 96 | + trac.F("region", trac.STRING, label="Customer home region", categorical=True), |
| 97 | + trac.F("total_lending", trac.FLOAT, label="Total lending (GBP)"), |
| 98 | + label="Loans by region") |
58 | 99 |
|
59 |
| -You can fill in the three define_* methods to declare any parameters, inputs and outputs your |
60 |
| -model is going to need, then start writing your model code in run_model. |
| 100 | + return {"loans_by_region": loans_by_region} |
61 | 101 |
|
62 |
| -To learn about modelling with TRAC D.A.P. and what is possible, check out the |
63 |
| -[modelling tutorials](https://tracdap.readthedocs.io/en/stable/modelling/tutorial) |
64 |
| -available in our online documentation. The tutorials are based on |
65 |
| -[example models](https://github.com/finos/tracdap/tree/main/examples/models/python) |
66 |
| -in the TRAC GitHub repository. We run these examples as part of our CI, so they will always |
67 |
| -be in sync with the corresponding version of the runtime library. |
| 102 | + def run_model(self, ctx: trac.TracContext): |
68 | 103 |
|
| 104 | + # Parameters and inputs are loaded and validated by TRAC |
| 105 | + exchange_rate = ctx.get_parameter("exchange_rate") |
| 106 | + customer_loans = ctx.get_pandas_table("customer_loans") |
69 | 107 |
|
70 |
| -## Building the runtime from source |
| 108 | + # Model code is regular Python |
| 109 | + customer_loans["loan_amount_gbp"] = customer_loans["loan_amount"] * exchange_rate |
71 | 110 |
|
72 |
| -This is not normally necessary for model development, but if you want to do it here are the commands. |
| 111 | + loans_by_region = customer_loans \ |
| 112 | + .groupby("region", observed=True, as_index=False) \ |
| 113 | + .aggregate(total_lending=("loan_amount_gbp", "sum")) |
73 | 114 |
|
74 |
| - cd tracdap-runtime/python |
| 115 | + # Logs written to ctx.log are captured by the platform |
| 116 | + ctx.log().info("Aggregated loans for %d regions", len(loans_by_region)) |
75 | 117 |
|
76 |
| - # Configure a Python environment |
| 118 | + # Outputs are handed back to TRAC for validation and saving |
| 119 | + ctx.put_pandas_table("loans_by_region", loans_by_region) |
77 | 120 |
|
78 |
| - python -m venv ./venv |
79 |
| - venv\Scripts\activate # For Windows platforms |
80 |
| - . venv/bin/activate # For macOS or Linux |
81 |
| - pip install -r requirements.txt |
| 121 | +# Use the desktop launcher to run, test and debug models locally |
| 122 | +if __name__ == "__main__": |
| 123 | + import tracdap.rt.launch as launch |
| 124 | + launch.launch_model(QuickStartModel, "config/quick_start.yaml", "config/sys_config.yaml") |
| 125 | +``` |
82 | 126 |
|
83 |
| - # Build the Python package files |
| 127 | +The model needs two config files in order to run: A job config file and a system config file. |
| 128 | +By convention, for local development these are kept in a ``config`` folder. |
84 | 129 |
|
85 |
| - python ./build_runtime.py --target dist |
| 130 | +The system config file defines the resources that are available for models to use. |
| 131 | +As a minimum the default storage location must be specified. |
| 132 | + |
| 133 | +*sys_config.yaml* |
| 134 | +```yaml |
| 135 | +properties: |
| 136 | + |
| 137 | + storage.default.location: example_data |
| 138 | + storage.default.format: CSV |
| 139 | + |
| 140 | +resources: |
| 141 | + |
| 142 | + example_data: |
| 143 | + resourceType: INTERNAL_STORAGE |
| 144 | + protocol: LOCAL |
| 145 | + properties: |
| 146 | + rootPath: C:\path\to\your\data |
| 147 | +``` |
| 148 | +
|
| 149 | +The job config file supplies the model with the parameters, inputs and outputs that it needs to run. |
| 150 | +The default data location from ``sys_config.yaml`` is used to load input data and save output data. |
| 151 | +TRAC checks the types and schemas of every parameter and input dataset, types are cast automatically |
| 152 | +where it is safe to do so, otherwise TRAC will raise an error if the inputs are not valid. |
| 153 | +
|
| 154 | +*quick_start.yaml* |
| 155 | +```yaml |
| 156 | +job: |
| 157 | + runModel: |
86 | 158 |
|
87 |
| -The package files will appear under build/dist |
| 159 | + parameters: |
| 160 | + exchange_rate: 0.865 |
| 161 | + |
| 162 | + inputs: |
| 163 | + customer_loans: "inputs/customer_loans_data.csv" |
| 164 | + |
| 165 | + outputs: |
| 166 | + loans_by_region: "outputs/example_model/loans_by_region.csv" |
| 167 | +``` |
| 168 | +
|
| 169 | +You can run the model from your IDE (right click the model file and choose "Run", |
| 170 | +or look for the "Play" button). You will see the model logs, and an output file |
| 171 | +will be created inside your data folder. |
| 172 | +
|
| 173 | +
|
| 174 | +## 📖 Documentation |
| 175 | +
|
| 176 | +See the [online documentation](https://docs.fintrac.co.uk/versions/latest/modelling) |
| 177 | +for a complete guide to writing models in the TRAC framework, |
| 178 | +including tutorials and an API reference. |
| 179 | +
|
| 180 | +
|
| 181 | +## ✋ Contributing |
| 182 | +
|
| 183 | +If you'd like to contribute a feature or a fix then we'd love to hear from you! |
| 184 | +Please raise an issue on our [issue tracker](https://github.com/finos/tracdap/issues) |
| 185 | +to discuss your suggestion before working on a PR. |
| 186 | +
|
| 187 | +Contributions are governed according to the [contribution guidelines](https://github.com/finos/tracdap/blob/main/CONTRIBUTING.md) |
| 188 | +and the [FINOS code of conduct](https://www.finos.org/code-of-conduct). |
| 189 | +
|
| 190 | +
|
| 191 | +## 📜 License |
| 192 | +
|
| 193 | +The TRAC model runtime is maintained by [finTRAC Ltd](https://fintrac.co.uk/) in association with |
| 194 | +the [Fintech Open Source Foundation](https://www.finos.org/) (FINOS) and distributed under the terms of |
| 195 | +the [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0). |
| 196 | +
|
| 197 | +SPDX-License-Identifier: [Apache-2.0](https://spdx.org/licenses/Apache-2.0) |
| 198 | +
|
| 199 | +For more information including copyright history, |
| 200 | +see the [NOTICE](https://github.com/finos/tracdap/blob/main/NOTICE) file. |
| 201 | +
|
| 202 | +
|
| 203 | +## 🏢 Enterprise |
| 204 | +
|
| 205 | +Professional support for TRAC is available from [finTRAC Ltd](https://fintrac.co.uk/), |
| 206 | +for more information please [contact us](https://fintrac.co.uk/contact). |
0 commit comments