openagua-engine

Connect a model engine to OpenAgua

https://github.com/openagua/openagua-engine

Science Score: 54.0%

This score indicates how likely this project is to be science-related based on various indicators:

  • CITATION.cff file
    Found CITATION.cff file
  • codemeta.json file
    Found codemeta.json file
  • .zenodo.json file
    Found .zenodo.json file
  • DOI references
  • Academic publication links
    Links to: zenodo.org
  • Committers with academic emails
  • Institutional organization owner
  • JOSS paper metadata
  • Scientific vocabulary similarity
    Low similarity (15.1%) to scientific vocabulary
Last synced: 7 months ago · JSON representation ·

Repository

Connect a model engine to OpenAgua

Basic Info
  • Host: GitHub
  • Owner: openagua
  • License: mit
  • Language: Python
  • Default Branch: main
  • Size: 79.1 KB
Statistics
  • Stars: 1
  • Watchers: 1
  • Forks: 0
  • Open Issues: 1
  • Releases: 1
Created about 5 years ago · Last pushed about 4 years ago
Metadata Files
Readme License Citation

README.md

DOI

Overview

openagua-engine is a Python package to help connect a model engine to OpenAgua, so that it can be controlled from and communicate with OpenAgua. It includes 1. a task queue subscriber to process model tasks instantiated in the OpenAgua app 2. functions to report progress to the OpenAgua app 3. functions to read from/write to the OpenAgua database

OpenAgua uses RabbitMQ to manage model run tasks and, for the time being, PubNub for realtime communication (for updating model progress in and stopping the model from OpenAgua). This package uses Celery to listen for tasks in RabbitMQ queues. Access to the OpenAgua database is via the OpenAgua API

Installation

From pip

This package is availabe via PyPI (see project page):

pip install openagua-engine

From source

python setup.py install should do the trick.

Getting started

The following should help you get going. In addition, see examples of OpenAgua Engine in action at https://github.com/openagua/engine-examples

Configuration

OpenAgua Engine requires several configuration keys to work. These may be provided directly as arguments to classes/functions, and/or as system environment variables. The possible configuration keys are as follows, listed by their recognized environment variable and respective argument name:

  • OA_API_KEY (api_key) - This is used to access the OpenAgua API. Get this from your account settings in OpenAgua.
  • OA_MODEL_KEY (model_key) - This is used to route model runs started in OpenAgua to the model engine you want to set up. Get this from the model configuration page in OpenAgua.
  • OA_RUN_KEY (run_key) (OPTIONAL) - This is a key associated with a particular run configuration that can isolate an engine instance from other engines connected to the same model. If this is omitted, the engine will accept any run associated with the model key (if no run key is assigned in the run configuration). Get this from the run configuration.
  • OA_RABBITMQ_HOST (variable only) - The RabbitMQ server IP address.

These may be provided in a number of ways. One common and easy way is to use a file called .env with your keys (and maybe some others as needed for your application):

dotenv OA_API_KEY=APIKEY123 OA_SECRET_KEY=SECRETKEY123 OA_MODEL_KEY=MODELKEY456 OA_RABBITMQ_HOST=1.2.3.4 OA_PUBNUB_PUBLISH_KEY=pubnubpublishkey123 OA_PUBNUB_SUBSCRIBE_KEY=pubnubsubscribekey123 This can be loaded into your main tasks.py script as: python from dotenv import load_dotenv load_dotenv()

Usage

An app engine will generally consist of five major steps/functions: 1. listen to a task queue to process model run requests, 2. read data from OpenAgua once a task is received, 3. run the model using the data, 4. publish model run progress and subscribe to user interventions, and 5. save data back to OpenAgua.

These are described along with code snippets below. See the examples for more complete script examples.

1. Listen to a task queue

A basic model engine requires a file called tasks.py that contains an entry function wrapped in a decorator "app", which is a Celery app created by openagua-engine. This app is then run in one of two ways.

1a. Create the entry function

```python from openaguaengine import createapp

app = create_app()

@app.task(name='model.run') def run(kwargs): # Do something great! return ``` **IMPORTANT: The name='model.run' bit above is critical. When a model is run in OpenAgua, the model.run function is called.

1b. Start the app

The app above is a Celery app, and can be run as: celery -A tasks worker -l INFO

Alternatively, the app may be called from within the script, for example by appending tasks.py with: python if __name__=='__main__': app.start(['-A', 'tasks', 'worker', '-l', 'INFO'])

WINDOWS USERS: Celery does not officially support Windows. While there are several fixes, one that seems to work is to use the "solo" process when running this app: celery -A tasks worker -l INFO -P solo Unfortunately, this means you cannot do concurrent (parallel) runs. Further work is needed to identify workarounds. In the meantime, if the app can be run on Linux, either a dedicated Linux server or Windows Subsystem for Linux (WSL) are options if concurrency is needed.

2. Read data from OpenAgua

Here is an example to instantiate the OpenAgua API and get a network: python from openagua_engine import OpenAguaEngine as OA oa = OA() api = oa.Client network = api.get_network(77)

3. Run the model

The sky is the limit here, especially considering parallel processing needs.

One easy way to parallel process is as follows. Among other arguments sent by OpenAgua to the task queue (the "kwargs" in the run function above) are the scenario ID combinations to be run. Because openagua-engine uses Celery, the app created with create_app() can be used to decorate a scenario-centric function, which can then be run in asynchronous mode, as follows:

```python @app.task(name='model.run') def run(**kwargs): network = oa.get_network(123)

scenario_id_combinations = kwargs.pop('scenario_ids', [])
for scen_ids in scenario_id_combinations:

    # Run a single scenario model asynchronously
    run_scenario.apply_async(args=(scen_ids, network,), kwargs=kwargs)

@app.task def runscenario(scenids, **kwargs): # Run model here... return ```

4a. Publish progress

openagua-engine includes methods to report (publish) progress. First, import an OpenAgua class (from openagua-engine import OpenAgua). Then, use it as follows:

```python totalsteps = 60 # This would normally be queried from a scenario
guid = kwargs.get('guid') run
name = kwargs.get('runname') networkid=kwargs.get('networkid') oa = OpenAgua(guid, runname, networkid, scenids, total_steps)

Tell OpenAgua / the user that the model has started

oa.start()

for step in range(totalsteps): mymodel.step() # Assume a model with method "step" to do some computation datetime = my_model.datetime oa.step(datetime)

Tell OpenAgua / the user that the model has finished

oa.finish() ```

4b. Subscribe to user interactions

The OpenAgua class above also monitors for user interactions, namely pause and stop. These are set as boolean (True/False) attributes of the OpenAgua object. We can include this in the above script as: ```python for i in range(totalsteps): # Check if the user has paused or stopped the run # Note that pause is not currently implemented in the app if oa.paused: pausestarttime = dt.datetime.now() while oa.paused and (dt.datetime.now() - pausestart_time).seconds < 86400: sleep(0.5) # check every 1/2 second

if oa.stopped:  # this should be after pause is checked, to stop during a pause
    oa.stop()  # This will report back to OA that the model has stopped
    break

```

5. Save data

[forthcoming]

Owner

  • Name: OpenAgua
  • Login: openagua
  • Kind: organization

Collaborative water system modeling

Citation (CITATION.cff)

cff-version: 1.2.0
message: "If you use this software, please cite it as below."
authors:
  - family-names: Rheinheimer
    given-names: David E.
    orcid: https://orcid.org/0000-0003-1525-9069
title: "OpenAgua Engine"
version: 0.2.18
doi: 10.5281/zenodo.5730572
date-released: 2022-01-10

GitHub Events

Total
Last Year

Committers

Last synced: about 3 years ago

All Time
  • Total Commits: 52
  • Total Committers: 2
  • Avg Commits per committer: 26.0
  • Development Distribution Score (DDS): 0.019
Top Committers
Name Email Commits
rheinheimer h****n@g****m 51
David Rheinheimer r****r@u****m 1

Issues and Pull Requests

Last synced: over 1 year ago

All Time
  • Total issues: 1
  • Total pull requests: 0
  • Average time to close issues: N/A
  • Average time to close pull requests: N/A
  • Total issue authors: 1
  • Total pull request authors: 0
  • Average comments per issue: 0.0
  • Average comments per pull request: 0
  • Merged pull requests: 0
  • Bot issues: 0
  • Bot pull requests: 0
Past Year
  • Issues: 0
  • Pull requests: 0
  • Average time to close issues: N/A
  • Average time to close pull requests: N/A
  • Issue authors: 0
  • Pull request authors: 0
  • Average comments per issue: 0
  • Average comments per pull request: 0
  • Merged pull requests: 0
  • Bot issues: 0
  • Bot pull requests: 0
Top Authors
Issue Authors
  • drheinheimer (1)
Pull Request Authors
Top Labels
Issue Labels
Pull Request Labels

Packages

  • Total packages: 1
  • Total downloads:
    • pypi 13 last-month
  • Total dependent packages: 0
  • Total dependent repositories: 1
  • Total versions: 7
  • Total maintainers: 1
pypi.org: openagua-engine

Tools to connect a model engine to OpenAgua

  • Versions: 7
  • Dependent Packages: 0
  • Dependent Repositories: 1
  • Downloads: 13 Last month
Rankings
Dependent packages count: 10.0%
Dependent repos count: 21.7%
Average: 24.6%
Forks count: 29.8%
Downloads: 29.8%
Stargazers count: 31.9%
Maintainers (1)
Last synced: 7 months ago

Dependencies

requirements.txt pypi
  • Pygments ==2.10.0
  • ably ==1.1.1
  • aiohttp ==3.8.1
  • aiosignal ==1.2.0
  • amqp ==5.0.6
  • async-timeout ==4.0.1
  • attrs ==21.2.0
  • billiard ==3.6.4.0
  • bleach ==4.1.0
  • cbor2 ==5.4.2
  • celery ==5.2.1
  • certifi ==2021.10.8
  • charset-normalizer ==2.0.7
  • click ==8.0.3
  • click-didyoumean ==0.3.0
  • click-plugins ==1.1.1
  • click-repl ==0.2.0
  • colorama ==0.4.4
  • docutils ==0.18
  • frozenlist ==1.2.0
  • idna ==3.3
  • importlib-metadata ==4.8.2
  • keyring ==23.2.1
  • kombu ==5.2.2
  • loguru ==0.5.3
  • methoddispatch ==3.0.2
  • msgpack ==1.0.3
  • multidict ==5.2.0
  • openagua-client ==0.2.1
  • packaging ==21.3
  • pkginfo ==1.8.1
  • prompt-toolkit ==3.0.22
  • pubnub ==5.4.0
  • pycryptodomex ==3.11.0
  • pyparsing ==3.0.6
  • pytz ==2021.3
  • pywin32-ctypes ==0.2.0
  • readme-renderer ==30.0
  • requests ==2.26.0
  • requests-toolbelt ==0.9.1
  • rfc3986 ==1.5.0
  • six ==1.16.0
  • tqdm ==4.62.3
  • twine ==3.6.0
  • typing_extensions ==4.0.0
  • urllib3 ==1.26.7
  • vine ==5.0.0
  • wcwidth ==0.2.5
  • webencodings ==0.5.1
  • win32-setctime ==1.0.3
  • yarl ==1.7.2
  • zipp ==3.6.0
setup.py pypi
  • celery *