Exploration Local Notebook
Prerequisites
- Access to a CDF Project.
- Know how to install and setup
Python. - Launch a
Pythonnotebook.
Generating SDK for Your Data Model¶
pygen supports generating an SDK on the fly for easy exploration in a notebook
First, instansiate a CogniteClient. This can be done with any of the supported methods from
the cognite-sdk:
from cognite.client import CogniteClient
Service Principal in Microsoft Entra
client = CogniteClient.default_oauth_client_credentials(
project="<my-cdf-project>",
cdf_cluster="<my-cdf-cluster>",
tenant_id="<my_domain>.onmicrosoft.com",
client_id="<my_service_principal_client_id>",
client_secret="<my_service_principal_client_secret>",
)
Interactive Login Microsoft Entra
client = CogniteClient.default_oauth_interactive(
project="<my-cdf-project>",
cdf_cluster="<my-cdf-cluster>",
tenant_id="cognitepygen.onmicrosoft.com",
client_id="<my_service_principal_client_id>",
)
Device Code
from cognite.client import ClientConfig
from cognite.client.credentials import OAuthDeviceCode
credentials = OAuthDeviceCode.default_for_azure_ad(
tenant_id="cognitepygen.onmicrosoft.com",
client_id="<device_client_id>",
cdf_cluster="<my-cdf-cluster>",
)
client = CogniteClient(ClientConfig(client_name="client-name", project="<my-cdf-project>", credentials=credentials))
For convenience pygen has a helper method for loading credentials from a toml file
from cognite.pygen import generate_sdk_notebook, load_cognite_client_from_toml
We have a local .toml file on the following format to create a CogniteClient
[cognite]
project = "<cdf-project>"
tenant_id = "<tenant-id>"
cdf_cluster = "<cdf-cluster>"
client_id = "<client-id>"
client_secret = "<client-secret>"
Then, we use the following function from pygen to create a `CogniteClient
client = load_cognite_client_from_toml("config.toml")
We can now create a SDK for the following data model.
pygen = generate_sdk_notebook(
("sp_pygen_power", "WindTurbine", "1"),
client,
)
Successfully retrieved data model(s) ('sp_pygen_power', 'WindTurbine', '1')
Name collision detected in ViewId(space='sp_pygen_power', external_id='SensorTimeSeries', version='1'): 'type'. An underscore will be added to the 'type' to avoid name collision.
Writing SDK to C:\Users\ANDERS~1\AppData\Local\Temp\pygen\sp_pygen_power_WindTurbine_1\wind_turbine
Done!
Added C:\Users\ANDERS~1\AppData\Local\Temp\pygen\sp_pygen_power_WindTurbine_1 to sys.path to enable import
Imported wind_turbine
You can now use the generated SDK in the current Python session.
The data classes are available by importing, for example, `from wind_turbine.data_classes import BladeWrite`
The function above does the following:
- Downloads the data model.
- Generates an SDK.
- Puts it in the temporary folder /
pygen - Adds that folder to the
sys.path - Imports the client
- Instantiates then new client
Use Generated SDK¶
pygen.wind_turbine.list(limit=5)
| space | external_id | name | capacity | windfarm | rotor | nacelle | blades | datasheets | data_record | |
|---|---|---|---|---|---|---|---|---|---|---|
| 0 | sp_wind | hornsea_1_mill_3 | hornsea_1_mill_3 | 7.0 | Hornsea 1 | {'space': 'sp_wind', 'external_id': 'hornsea_1... | {'space': 'sp_wind', 'external_id': 'hornsea_1... | [{'space': 'sp_wind', 'external_id': 'hornsea_... | [{'space': 'sp_wind', 'external_id': 'windmill... | {'version': 4, 'last_updated_time': 2024-11-16... |
| 1 | sp_wind | hornsea_1_mill_2 | hornsea_1_mill_2 | 7.0 | Hornsea 1 | {'space': 'sp_wind', 'external_id': 'hornsea_1... | {'space': 'sp_wind', 'external_id': 'hornsea_1... | [{'space': 'sp_wind', 'external_id': 'hornsea_... | [{'space': 'sp_wind', 'external_id': 'windmill... | {'version': 4, 'last_updated_time': 2024-11-16... |
| 2 | sp_wind | hornsea_1_mill_1 | hornsea_1_mill_1 | 7.0 | Hornsea 1 | {'space': 'sp_wind', 'external_id': 'hornsea_1... | {'space': 'sp_wind', 'external_id': 'hornsea_1... | [{'space': 'sp_wind', 'external_id': 'hornsea_... | [{'space': 'sp_wind', 'external_id': 'windmill... | {'version': 4, 'last_updated_time': 2024-11-16... |
| 3 | sp_wind | hornsea_1_mill_4 | hornsea_1_mill_4 | 7.0 | Hornsea 1 | {'space': 'sp_wind', 'external_id': 'hornsea_1... | {'space': 'sp_wind', 'external_id': 'hornsea_1... | [{'space': 'sp_wind', 'external_id': 'hornsea_... | [{'space': 'sp_wind', 'external_id': 'windmill... | {'version': 4, 'last_updated_time': 2024-11-16... |
| 4 | sp_wind | hornsea_1_mill_5 | hornsea_1_mill_5 | 7.0 | Hornsea 1 | {'space': 'sp_wind', 'external_id': 'hornsea_1... | {'space': 'sp_wind', 'external_id': 'hornsea_1... | [{'space': 'sp_wind', 'external_id': 'hornsea_... | [{'space': 'sp_wind', 'external_id': 'windmill... | {'version': 4, 'last_updated_time': 2024-11-16... |
pygen.metmast.list()
| space | external_id | position | wind_speed | tilt_angle | temperature | data_record | |
|---|---|---|---|---|---|---|---|
| 0 | sp_wind | utsira_station | 62.0 | utsira_station_wind_speed | utsira_station_tilt_angle | utsira_station_temperature | {'version': 1, 'last_updated_time': 2024-11-16... |
| 1 | sp_wind | hitra_station | 63.0 | hitra_station_wind_speed | hitra_station_tilt_angle | hitra_station_temperature | {'version': 1, 'last_updated_time': 2024-11-16... |
| 2 | sp_wind | smola_station | 64.0 | smola_station_wind_speed | smola_station_tilt_angle | smola_station_temperature | {'version': 1, 'last_updated_time': 2024-11-16... |
To see a more complete example of functionality for the generated client see the Usage section in the documentation.
Generating SDK using Demo Data Model¶
In case you want to try out pygen, but do not have a data model with data available, pygen comes with a demo data model included in the package.
from cognite.pygen import demo, load_cognite_client_from_toml
solar = demo.SolarFarmAPM()
client = load_cognite_client_from_toml()
%%time
pygen = solar.create(client)
Data model DataModelId(space='pygen', external_id='SolarFarmAPM', version='1') already exists, skipping deployment ✅ Data Model Ready! Skipping TimeSeries creation, all 4 TimeSeries already exist Skipping FileMetadata creation, all 3 FileMetadata already exist All 17 nodes already exists All 21 edges already exists ✅ Population Complete! Writing SDK to C:\Users\ANDERS~1\AppData\Local\Temp\pygen Done! Added C:\Users\ANDERS~1\AppData\Local\Temp\pygen to sys.path to enable import Imported solar_farm_apm.client ✅ SDK Generated! CPU times: total: 469 ms Wall time: 3.41 s
Use Generated SDK¶
We can now inspect the data model using our newly generated SDK.
pygen.assets.list()
| external_id | area_id | category_id | created_date | description | documents | is_active | is_critical_line | linked_assets | metrics | name | parent | source_db | tag | updated_date | version | last_updated_time | created_time | deleted_time | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | solarfarm:fornebu | 1 | 1 | 2017-01-01 00:00:00+00:00 | The most sunny place in Norway | [] | True | True | [] | [] | Fornebu | None | AlbertCerebrum | 2023-01-01 00:00:00+00:00 | 2 | 2023-08-20 07:48:17.799000+00:00 | 2023-08-20 07:48:17.799000+00:00 | None | |
| 1 | solarpanel:sunny | 2 | 2 | 2017-01-01 00:00:00+00:00 | The panel on the first building | [] | True | False | [inverter:sunny] | [] | Solar Panel Sunny | solarfarm:fornebu | AlbertCerebrum | 2022-01-01 00:00:00+00:00 | 1 | 2023-08-20 07:48:17.799000+00:00 | 2023-08-20 07:48:17.799000+00:00 | None | |
| 2 | solarpanel:cloudy | 3 | 2 | 2020-01-01 00:00:00+00:00 | The panel on the second building | [] | True | True | [inverter:cloudy] | [] | Solar Panel Cloudy | solarfarm:fornebu | AlbertCerebrum | 2022-01-01 00:00:00+00:00 | 1 | 2023-08-20 07:48:17.799000+00:00 | 2023-08-20 07:48:17.799000+00:00 | None | |
| 3 | transformer:sunny | 2 | 3 | 2017-01-01 00:00:00+00:00 | The transformer connected to sunny | [] | True | False | [substation:fornebu] | [] | Transformer Sunny | solarfarm:fornebu | AlbertCerebrum | 2022-01-01 00:00:00+00:00 | 1 | 2023-08-20 07:48:17.799000+00:00 | 2023-08-20 07:48:17.799000+00:00 | None | |
| 4 | transformer:cloudy | 3 | 3 | 2017-01-01 00:00:00+00:00 | The transformer connected to cloudy | [] | True | False | [substation:fornebu] | [] | Transformer Cloudy | solarfarm:fornebu | AlbertCerebrum | 2021-01-01 00:00:00+00:00 | 1 | 2023-08-20 07:48:17.799000+00:00 | 2023-08-20 07:48:17.799000+00:00 | None | |
| 5 | transformer:saver | 4 | 3 | 2022-01-01 00:00:00+00:00 | The transformer connected to battery | [] | True | True | [substation:fornebu] | [] | Transformer Saver | solarfarm:fornebu | AlbertCerebrum | 2023-03-01 00:00:00+00:00 | 1 | 2023-08-20 07:48:17.799000+00:00 | 2023-08-20 07:48:17.799000+00:00 | None | |
| 6 | inverter:sunny | 2 | 4 | 2017-01-01 00:00:00+00:00 | The inverter connected to sunny | [] | True | False | [transformer:sunny] | [] | Inverter Sunny | solarfarm:fornebu | AlbertCerebrum | 2022-01-01 00:00:00+00:00 | 1 | 2023-08-20 07:48:17.799000+00:00 | 2023-08-20 07:48:17.799000+00:00 | None | |
| 7 | inverter:cloudy | 3 | 4 | 2017-01-01 00:00:00+00:00 | The inverter connected to cloudy | [] | True | False | [transformer:cloudy] | [] | Inverter Cloudy | solarfarm:fornebu | AlbertCerebrum | 2021-01-01 00:00:00+00:00 | 1 | 2023-08-20 07:48:17.799000+00:00 | 2023-08-20 07:48:17.799000+00:00 | None | |
| 8 | inverter:saver | 4 | 4 | 2022-01-01 00:00:00+00:00 | The inverter connected to battery | [] | True | True | [transformer:saver] | [] | Inverter Saver | solarfarm:fornebu | AlbertCerebrum | 2023-03-01 00:00:00+00:00 | 1 | 2023-08-20 07:48:17.799000+00:00 | 2023-08-20 07:48:17.799000+00:00 | None | |
| 9 | substation:fornebu | 1 | 4 | 2017-01-01 00:00:00+00:00 | The substation for the solar farm | [] | True | True | [] | [] | Fornebu station | solarfarm:fornebu | AlbertCerebrum | 2023-03-01 00:00:00+00:00 | 1 | 2023-08-20 07:48:17.799000+00:00 | 2023-08-20 07:48:17.799000+00:00 | None | |
| 10 | battery:winter | 4 | 5 | 2020-01-01 00:00:00+00:00 | The battery for the solar farm | [] | True | True | [inverter:saver] | [] | Saver | solarfarm:fornebu | AlbertCerebrum | 2020-06-01 00:00:00+00:00 | 1 | 2023-08-20 07:48:17.799000+00:00 | 2023-08-20 07:48:17.799000+00:00 | None |
pygen.work_orders.retrieve("planned:1001")
WorkOrder(external_id='planned:1001', version=2, last_updated_time=datetime.datetime(2023, 8, 20, 7, 48, 17, 799000, tzinfo=TzInfo(UTC)), created_time=datetime.datetime(2023, 8, 20, 7, 48, 17, 799000, tzinfo=TzInfo(UTC)), deleted_time=None, actual_hours=3, created_date=datetime.datetime(2023, 1, 1, 0, 0, tzinfo=TzInfo(UTC)), description='Inspect solar panels', due_date=datetime.datetime(2023, 1, 1, 0, 0, tzinfo=TzInfo(UTC)), duration_hours=5, end_time=datetime.datetime(2023, 1, 2, 0, 0, tzinfo=TzInfo(UTC)), is_active=False, is_cancelled=False, is_completed=True, is_safety_critical=False, linked_assets=['solarpanel:sunny', 'solarpanel:cloudy'], percentage_progress=100, planned_start=datetime.datetime(2023, 1, 1, 0, 0, tzinfo=TzInfo(UTC)), priority_description='Medium Planned Priority', program_number='1', start_time=datetime.datetime(2023, 1, 1, 0, 0, tzinfo=TzInfo(UTC)), status='Done', title='Planned Inspection', work_items=['work:inspection:1001', 'work:cleaning:1001'], work_order_number='1', work_package_number='1')
Once we are finished exploting pygen using the demo data we can remove it with the .clean() method
solar.clean(client)
About to delete data model DataModelId(space='pygen', external_id='SolarFarmAPM', version='1') About to delete views [ViewId(space='pygen', external_id='WorkItem', version='e3b9053e1dd01e'), ViewId(space='pygen', external_id='WorkOrder', version='27f589c97cdb01'), ViewId(space='pygen', external_id='Asset', version='a974167b65241a')] About to delete containers [ContainerId(space='pygen', external_id='Asset'), ContainerId(space='pygen', external_id='WorkOrder'), ContainerId(space='pygen', external_id='WorkItem')] along with all nodes and edges About to delete space pygen
Deleted 4 TimeSeries Deleted 3 FileMetadata Deleted 17 nodes Deleted 0 edges Deleted 4 type nodes Deleted data model DataModelId(space='pygen', external_id='SolarFarmAPM', version='1') Deleted views [ViewId(space='pygen', external_id='WorkItem', version='e3b9053e1dd01e'), ViewId(space='pygen', external_id='WorkOrder', version='27f589c97cdb01'), ViewId(space='pygen', external_id='Asset', version='a974167b65241a')] Deleted containers [ContainerId(space='pygen', external_id='Asset'), ContainerId(space='pygen', external_id='WorkOrder'), ContainerId(space='pygen', external_id='WorkItem')] Deleted space pygen