pythonfmu


Namepythonfmu JSON
Version 0.6.5 PyPI version JSON
download
home_pagehttps://github.com/NTNU-IHB/PythonFMU
SummaryA lightweight framework that enables the packaging of Python3.x code as co-simulation FMUs.
upload_time2024-09-26 11:40:55
maintainerNone
docs_urlNone
authorNTNU-IHB
requires_pythonNone
licenseMIT
keywords fmi
VCS
bugtrack_url
requirements fmpy pytest
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # PythonFMU

> A lightweight framework that enables the packaging of Python 3 code or CSV files as co-simulation FMUs (following FMI version 2.0).

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](https://github.com/NTNU-IHB/PythonFMU/issues)

[![CI](https://github.com/NTNU-IHB/PythonFMU/workflows/CI/badge.svg)](https://github.com/NTNU-IHB/PythonFMU/actions?query=workflow%3ACI)
[![PyPI](https://img.shields.io/pypi/v/pythonfmu)](https://pypi.org/project/pythonfmu/)
[![Conda Version](https://img.shields.io/conda/vn/conda-forge/pythonfmu.svg)](https://anaconda.org/conda-forge/pythonfmu)

[![Gitter](https://badges.gitter.im/NTNU-IHB/FMI4j.svg)](https://gitter.im/NTNU-IHB/PythonFMU?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)

### How do I build an FMU from python code?

1. Install `pythonfmu` package:

```bash
pip install pythonfmu
```

2. Create a new class extending the `Fmi2Slave` class declared in the `pythonfmu.fmi2slave` module (see below for an example).
3. Run `pythonfmu build` to create the fmu.

```
usage: pythonfmu build [-h] -f SCRIPT_FILE [-d DEST] [--doc DOCUMENTATION_FOLDER] [--no-external-tool]
                       [--no-variable-step] [--interpolate-inputs] [--only-one-per-process] [--handle-state]
                       [--serialize-state] [--use-memory-management]
                       [Project files [Project files ...]]

Build an FMU from a Python script.

positional arguments:
  Project files         Additional project files required by the Python script.

optional arguments:
  -h, --help            show this help message and exit
  -f SCRIPT_FILE, --file SCRIPT_FILE
                        Path to the Python script.
  -d DEST, --dest DEST  Where to save the FMU.
  --doc DOCUMENTATION_FOLDER
                        Documentation folder to include in the FMU.
  --no-external-tool    If given, needsExecutionTool=false
  --no-variable-step    If given, canHandleVariableCommunicationStepSize=false
  --interpolate-inputs  If given, canInterpolateInputs=true
  --only-one-per-process
                        If given, canBeInstantiatedOnlyOncePerProcess=true
  --handle-state        If given, canGetAndSetFMUstate=true
  --serialize-state     If given, canSerializeFMUstate=true
```

### How do I build an FMU from python code with third-party dependencies?

Often, Python scripts depends on non-builtin libraries like `numpy`, `scipy`, etc.
_PythonFMU_ does not package a full environment within the FMU.
However, you can package a `requirements.txt` or `environment.yml` file within your FMU following these steps:

1. Install _pythonfmu_ package: `pip install pythonfmu`
2. Create a new class extending the `Fmi2Slave` class declared in the `pythonfmu.fmi2slave` module (see below for an example).
3. Create a `requirements.txt` file (to use _pip_ manager) and/or a `environment.yml` file (to use _conda_ manager) that defines your dependencies.
4. Run `pythonfmu build -f myscript.py requirements.txt` to create the fmu including the dependencies file.

And using `pythonfmu deploy`, end users will be able to update their local Python environment. The steps to achieve that:

1. Install _pythonfmu_ package: `pip install pythonfmu`
2. Be sure to be in the Python environment to be updated. Then execute `pythonfmu deploy -f my.fmu`

```
usage: pythonfmu deploy [-h] -f FMU [-e ENVIRONMENT] [{pip,conda}]

Deploy a Python FMU. The command will look in the `resources` folder for one of the following files:
`requirements.txt` or `environment.yml`. If you specify a environment file but no package manager, `conda` will be selected for `.yaml` and `.yml` otherwise `pip` will be used. The tool assume the Python environment in which the FMU should be executed is the current one.

positional arguments:
  {pip,conda}           Python packages manager

optional arguments:
  -h, --help            show this help message and exit
  -f FMU, --file FMU    Path to the Python FMU.
  -e ENVIRONMENT, --env ENVIRONMENT
                        Requirements or environment file.
```

### Example:

#### Write the script

```python

from pythonfmu import Fmi2Causality, Fmi2Slave, Boolean, Integer, Real, String


class PythonSlave(Fmi2Slave):

    author = "John Doe"
    description = "A simple description"

    def __init__(self, **kwargs):
        super().__init__(**kwargs)

        self.intOut = 1
        self.realOut = 3.0
        self.booleanVariable = True
        self.stringVariable = "Hello World!"
        self.register_variable(Integer("intOut", causality=Fmi2Causality.output))
        self.register_variable(Real("realOut", causality=Fmi2Causality.output))
        self.register_variable(Boolean("booleanVariable", causality=Fmi2Causality.local))
        self.register_variable(String("stringVariable", causality=Fmi2Causality.local))
        
        # Note:
        # it is also possible to explicitly define getters and setters as lambdas in case the variable is not backed by a Python field.
        # self.register_variable(Real("myReal", causality=Fmi2Causality.output, getter=lambda: self.realOut, setter=lambda v: set_real_out(v))

    def do_step(self, current_time, step_size):
        return True

```

#### Create the FMU

```
pythonfmu build -f pythonslave.py myproject
```

In this example a python class named `PythonSlave` that extends `Fmi2Slave` is declared in a file named `pythonslave.py`,
where `myproject` is an optional folder containing additional project files required by the python script.
Project folders such as this will be recursively copied into the FMU. Multiple project files/folders may be added.

### Note

PythonFMU does not bundle Python, which makes it a tool coupling solution.
This means that you can not expect the generated FMU to work on a different system (The system would need a compatible Python version and libraries).
But to ease its usage the wrapper uses the limited Python API, making the pre-built binaries for Linux and Windows 64-bits
compatible with any Python 3 environment. If you need to compile the wrapper for a specific configuration,
you will need CMake and a C++ compiler. The commands for building the wrapper on Linux and on Windows can be seen in
the [GitHub workflow](./.github/workflows/main.yml).

PythonFMU does not automatically resolve 3rd party dependencies. If your code includes e.g. `numpy`, the target system also needs to have `numpy` installed.

---

Would you rather build FMUs in Java? Check out [FMI4j](https://github.com/NTNU-IHB/FMI4j)!  
Need to distribute your FMUs? [FMU-proxy](https://github.com/NTNU-IHB/FMU-proxy) to the rescue!

### Publications

[Hatledal, Lars Ivar, Frédéric Collonval, and Houxiang Zhang. "Enabling python driven co-simulation models with PythonFMU." Proceedings of the 34th International ECMS-Conference on Modelling and Simulation-ECMS 2020. ECMS European Council for Modelling and Simulation, 2020.](https://doi.org/10.7148/2020-0235)

### Credits

This work has been possible thanks to the contributions of: <br> 
@markaren from NTNU-IHB <br>
@fcollonval from Safran SA.

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/NTNU-IHB/PythonFMU",
    "name": "pythonfmu",
    "maintainer": null,
    "docs_url": null,
    "requires_python": null,
    "maintainer_email": null,
    "keywords": "FMI",
    "author": "NTNU-IHB",
    "author_email": null,
    "download_url": "https://files.pythonhosted.org/packages/50/bd/61c366eb0062db204315b81fa702a19ef4240d8129adffe89319a01ed2c3/pythonfmu-0.6.5.tar.gz",
    "platform": null,
    "description": "# PythonFMU\n\n> A lightweight framework that enables the packaging of Python 3 code or CSV files as co-simulation FMUs (following FMI version 2.0).\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](https://github.com/NTNU-IHB/PythonFMU/issues)\n\n[![CI](https://github.com/NTNU-IHB/PythonFMU/workflows/CI/badge.svg)](https://github.com/NTNU-IHB/PythonFMU/actions?query=workflow%3ACI)\n[![PyPI](https://img.shields.io/pypi/v/pythonfmu)](https://pypi.org/project/pythonfmu/)\n[![Conda Version](https://img.shields.io/conda/vn/conda-forge/pythonfmu.svg)](https://anaconda.org/conda-forge/pythonfmu)\n\n[![Gitter](https://badges.gitter.im/NTNU-IHB/FMI4j.svg)](https://gitter.im/NTNU-IHB/PythonFMU?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)\n\n### How do I build an FMU from python code?\n\n1. Install `pythonfmu` package:\n\n```bash\npip install pythonfmu\n```\n\n2. Create a new class extending the `Fmi2Slave` class declared in the `pythonfmu.fmi2slave` module (see below for an example).\n3. Run `pythonfmu build` to create the fmu.\n\n```\nusage: pythonfmu build [-h] -f SCRIPT_FILE [-d DEST] [--doc DOCUMENTATION_FOLDER] [--no-external-tool]\n                       [--no-variable-step] [--interpolate-inputs] [--only-one-per-process] [--handle-state]\n                       [--serialize-state] [--use-memory-management]\n                       [Project files [Project files ...]]\n\nBuild an FMU from a Python script.\n\npositional arguments:\n  Project files         Additional project files required by the Python script.\n\noptional arguments:\n  -h, --help            show this help message and exit\n  -f SCRIPT_FILE, --file SCRIPT_FILE\n                        Path to the Python script.\n  -d DEST, --dest DEST  Where to save the FMU.\n  --doc DOCUMENTATION_FOLDER\n                        Documentation folder to include in the FMU.\n  --no-external-tool    If given, needsExecutionTool=false\n  --no-variable-step    If given, canHandleVariableCommunicationStepSize=false\n  --interpolate-inputs  If given, canInterpolateInputs=true\n  --only-one-per-process\n                        If given, canBeInstantiatedOnlyOncePerProcess=true\n  --handle-state        If given, canGetAndSetFMUstate=true\n  --serialize-state     If given, canSerializeFMUstate=true\n```\n\n### How do I build an FMU from python code with third-party dependencies?\n\nOften, Python scripts depends on non-builtin libraries like `numpy`, `scipy`, etc.\n_PythonFMU_ does not package a full environment within the FMU.\nHowever, you can package a `requirements.txt` or `environment.yml` file within your FMU following these steps:\n\n1. Install _pythonfmu_ package: `pip install pythonfmu`\n2. Create a new class extending the `Fmi2Slave` class declared in the `pythonfmu.fmi2slave` module (see below for an example).\n3. Create a `requirements.txt` file (to use _pip_ manager) and/or a `environment.yml` file (to use _conda_ manager) that defines your dependencies.\n4. Run `pythonfmu build -f myscript.py requirements.txt` to create the fmu including the dependencies file.\n\nAnd using `pythonfmu deploy`, end users will be able to update their local Python environment. The steps to achieve that:\n\n1. Install _pythonfmu_ package: `pip install pythonfmu`\n2. Be sure to be in the Python environment to be updated. Then execute `pythonfmu deploy -f my.fmu`\n\n```\nusage: pythonfmu deploy [-h] -f FMU [-e ENVIRONMENT] [{pip,conda}]\n\nDeploy a Python FMU. The command will look in the `resources` folder for one of the following files:\n`requirements.txt` or `environment.yml`. If you specify a environment file but no package manager, `conda` will be selected for `.yaml` and `.yml` otherwise `pip` will be used. The tool assume the Python environment in which the FMU should be executed is the current one.\n\npositional arguments:\n  {pip,conda}           Python packages manager\n\noptional arguments:\n  -h, --help            show this help message and exit\n  -f FMU, --file FMU    Path to the Python FMU.\n  -e ENVIRONMENT, --env ENVIRONMENT\n                        Requirements or environment file.\n```\n\n### Example:\n\n#### Write the script\n\n```python\n\nfrom pythonfmu import Fmi2Causality, Fmi2Slave, Boolean, Integer, Real, String\n\n\nclass PythonSlave(Fmi2Slave):\n\n    author = \"John Doe\"\n    description = \"A simple description\"\n\n    def __init__(self, **kwargs):\n        super().__init__(**kwargs)\n\n        self.intOut = 1\n        self.realOut = 3.0\n        self.booleanVariable = True\n        self.stringVariable = \"Hello World!\"\n        self.register_variable(Integer(\"intOut\", causality=Fmi2Causality.output))\n        self.register_variable(Real(\"realOut\", causality=Fmi2Causality.output))\n        self.register_variable(Boolean(\"booleanVariable\", causality=Fmi2Causality.local))\n        self.register_variable(String(\"stringVariable\", causality=Fmi2Causality.local))\n        \n        # Note:\n        # it is also possible to explicitly define getters and setters as lambdas in case the variable is not backed by a Python field.\n        # self.register_variable(Real(\"myReal\", causality=Fmi2Causality.output, getter=lambda: self.realOut, setter=lambda v: set_real_out(v))\n\n    def do_step(self, current_time, step_size):\n        return True\n\n```\n\n#### Create the FMU\n\n```\npythonfmu build -f pythonslave.py myproject\n```\n\nIn this example a python class named `PythonSlave` that extends `Fmi2Slave` is declared in a file named `pythonslave.py`,\nwhere `myproject` is an optional folder containing additional project files required by the python script.\nProject folders such as this will be recursively copied into the FMU. Multiple project files/folders may be added.\n\n### Note\n\nPythonFMU does not bundle Python, which makes it a tool coupling solution.\nThis means that you can not expect the generated FMU to work on a different system (The system would need a compatible Python version and libraries).\nBut to ease its usage the wrapper uses the limited Python API, making the pre-built binaries for Linux and Windows 64-bits\ncompatible with any Python 3 environment. If you need to compile the wrapper for a specific configuration,\nyou will need CMake and a C++ compiler. The commands for building the wrapper on Linux and on Windows can be seen in\nthe [GitHub workflow](./.github/workflows/main.yml).\n\nPythonFMU does not automatically resolve 3rd party dependencies. If your code includes e.g. `numpy`, the target system also needs to have `numpy` installed.\n\n---\n\nWould you rather build FMUs in Java? Check out [FMI4j](https://github.com/NTNU-IHB/FMI4j)!  \nNeed to distribute your FMUs? [FMU-proxy](https://github.com/NTNU-IHB/FMU-proxy) to the rescue!\n\n### Publications\n\n[Hatledal, Lars Ivar, Fr\u00e9d\u00e9ric Collonval, and Houxiang Zhang. \"Enabling python driven co-simulation models with PythonFMU.\" Proceedings of the 34th International ECMS-Conference on Modelling and Simulation-ECMS 2020. ECMS European Council for Modelling and Simulation, 2020.](https://doi.org/10.7148/2020-0235)\n\n### Credits\n\nThis work has been possible thanks to the contributions of: <br> \n@markaren from NTNU-IHB <br>\n@fcollonval from Safran SA.\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "A lightweight framework that enables the packaging of Python3.x code as co-simulation FMUs.",
    "version": "0.6.5",
    "project_urls": {
        "Homepage": "https://github.com/NTNU-IHB/PythonFMU"
    },
    "split_keywords": [
        "fmi"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "688f44d532cd93fa769315850621b667ff4065b45f8bae87ee49c735232f7262",
                "md5": "4966e2eefa9b0e9874ef1e569fa7d75c",
                "sha256": "52d217869868144a195873956999b775cca8d1b865f4fbfa7b5bfd334178252d"
            },
            "downloads": -1,
            "filename": "pythonfmu-0.6.5-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "4966e2eefa9b0e9874ef1e569fa7d75c",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": null,
            "size": 356804,
            "upload_time": "2024-09-26T11:40:53",
            "upload_time_iso_8601": "2024-09-26T11:40:53.982433Z",
            "url": "https://files.pythonhosted.org/packages/68/8f/44d532cd93fa769315850621b667ff4065b45f8bae87ee49c735232f7262/pythonfmu-0.6.5-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "50bd61c366eb0062db204315b81fa702a19ef4240d8129adffe89319a01ed2c3",
                "md5": "91a925c5f9bb1c48bcff7c8faad71972",
                "sha256": "9a39f413076a8ee0b617c2f3338f45ff2d78467ce7a2a40ab643166bfc1422e7"
            },
            "downloads": -1,
            "filename": "pythonfmu-0.6.5.tar.gz",
            "has_sig": false,
            "md5_digest": "91a925c5f9bb1c48bcff7c8faad71972",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 341506,
            "upload_time": "2024-09-26T11:40:55",
            "upload_time_iso_8601": "2024-09-26T11:40:55.578996Z",
            "url": "https://files.pythonhosted.org/packages/50/bd/61c366eb0062db204315b81fa702a19ef4240d8129adffe89319a01ed2c3/pythonfmu-0.6.5.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-09-26 11:40:55",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "NTNU-IHB",
    "github_project": "PythonFMU",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [
        {
            "name": "fmpy",
            "specs": []
        },
        {
            "name": "pytest",
            "specs": []
        }
    ],
    "lcname": "pythonfmu"
}
        
Elapsed time: 0.62215s