Examples ======== First, get an instance of the ``ThreediApi``: .. code:: python from threedi_api_client import ThreediApi env_file = "/.env" api = ThreediApi(env_file) Now you can easily make use of the api models generated by the openapi client. Let us create a simulation. We will use a ``Simulation`` model instance to pass data to the API. Some fields are optional but we do need to specify: - the unique organisation ID we want to run the simulation for - the model schema to use for the simulation by referring to the id of the threedimodel resource - datetime (in ISO 8601 (UTC) format) for the simulation start - either a end datetime (also in ISO 8601 (UTC) format) or the duration parameter in seconds If you do not know the unique ID for your organisation you can make use of the API to request it. .. code:: python api.organisations_list(name__istartswith="nelen") {'count': 2, 'next': None, 'previous': None, 'results': [{'name': 'Nelen & Schuurmans', 'unique_id': 'b8f91de705774fe8a4e7cb2d9413bf5c', 'url': 'https://api.3di.live/v3.0/organisations/61f5a464c35044c19bc7d4b42d7f58cb/'}, {'name': 'Nelen & Schuurmans alleen werknemers', 'unique_id': 'e82c74c4fb5846b3ae990c0cc69130c6', 'url': 'https://api.3di.live/v3.0/organisations/cde64bc165644be9af023fc4fa18d098/'}]} Now we can create the ``Simulation`` model instance. .. code:: python from threedi_api_client.openapi import Simulation # start date will be a datetime object from datetime import datetime my_extreme_event_simulation = Simulation( name="my extreme event", # (optional) threedimodel=1, # The model schema to use for the simulation by referring to the id of the threedimodel resource organisation='b8f91de705774fe8a4e7cb2d9413bf5c', start_datetime=datetime.utcnow(), # accepts datetime instance duration=7200 # in secs ==> 2 hours ) The ``simulations_create`` method allows you to create a new Simulation resource. .. code:: python api.simulations_create(my_extreme_event_simulation) {'created': 'now', 'duration': 7200, 'duration_humanized': '2 hours, 0 minutes, 0 seconds', 'end_datetime': '2019-11-04T16:19:46Z', 'id': 631, 'name': 'my extreme event', 'organisation': 'b8f91de705774fe8a4e7cb2d9413bf5c', 'organisation_name': 'Nelen & Schuurmans', 'slug': 'my-extreme-event-378f55a5-06df-4021-8fb6-65bbb70519dc', 'start_datetime': '2019-11-04T14:19:46Z', 'threedimodel': 'https://api.3di.live/v3.0/threedimodels/1/', 'threedimodel_id': '1', 'url': 'https://api.3di.live/v3.0/simulations/631/', 'user': 'lars.claussen', 'uuid': '378f55a5-06df-4021-8fb6-65bbb70519dc'} Simulations allow for adding an arbitrary number of events to them like - rain events - sources and sinks - initial conditions - laterals - saved states - structure controls All of them have their own openapi client model. To add a constant rain event to the simulation you would do the following. .. code:: python from threedi_api_client.openapi import ConstantRain const_rain = ConstantRain( simulation=631, # the ID we got from our create call above offset=60, # let the rain start after one minute duration=5000, # let the rain last for 5000 secs value=0.0006, # not too extreme after all...;-) units="m/s" # the only unit supported for now ) api.simulations_events_rain_constant_create(631, const_rain) {'duration': 5000, 'offset': 60, 'simulation': 'https://api.3di.live/v3.0/simulations/631/', 'units': 'm/s', 'url': 'https://api.3di.live/v3.0/simulations/631/events/rain/constant/17/', 'value': 0.0006} If you want to see which events are defined on a given simulation .. code:: python api.simulations_events(631) {'boundaries': None, 'breach': [], 'filerasterrain': [], 'filerastersourcessinks': [], 'filetimeseriesrain': [], 'filetimeseriessourcessinks': [], 'initial_groundwaterlevel': None, 'initial_onedwaterlevel': None, 'initial_onedwaterlevelpredefined': None, 'initial_savedstate': None, 'initial_twodwaterlevel': None, 'laterals': [], 'lizardrasterrain': [], 'lizardrastersourcessinks': [], 'lizardtimeseriesrain': [], 'lizardtimeseriessourcessinks': [], 'savedstates': [], 'timedstructurecontrol': [], 'timeseriesrain': [{'constant': True, 'duration': 5000, 'interpolate': False, 'offset': 60, 'simulation': 'https://api.3di.live/v3.0/simulations/631/', 'units': 'm/s', 'url': 'https://api.3di.live/v3.0/simulations/631/events/rain/timeseries/17/', 'values': [[0.0, 0.0006], [5000.0, 0.0]]}], 'timeseriessourcessinks': []} Advanced usage ~~~~~~~~~~~~~~ See below for an example of uploading a rain raster. .. code:: python from pathlib import Path from threedi_api_client.files import upload_file simulation_pk = 1 filename = 'bergermeer_rasters_from_geotiffs.nc' local_file_path = Path('./data/bergermeer_rasters_from_geotiffs.nc') # Create rain raster upload resource in API # returns a 'file_upload' instance containing a # put_url property which is the URL to the object # storage object to be uploaded with an HTTP PUT requests. file_upload = api.simulations_events_rain_rasters_upload( filename, simulation_pk) # Upload the file upload_file(file_upload.put_url, local_file_path) Async client ~~~~~~~~~~~~ This project also provides an asynchronous api client. To use the async-client make sure you install the optional dependencies using ``pip install threedi-api-client[aio]`` and then import from the ``aio`` submodule. The async-client works the same as the synchronous client, except all api calls are coroutines. For example, to asynchronously request files from the api: .. code:: python import asyncio from threedi_api_client.api import ThreediApi from threedi_api_client.openapi.api.v3_api import V3Api config = { "THREEDI_API_HOST": "https://api.3di.live", "THREEDI_API_PERSONAL_API_TOKEN": "your_personal_api_token_here" } async def main(): async with ThreediApi(config=config) as api_client: api_client: V3Api print(await api_client.files_list()) if __name__ == '__main__': asyncio.run(main())