Exploration Local Notebook
Prerequisites
- Access to a CDF Project.
- Know how to install and setup
Python
. - Launch a
Python
notebook.
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