{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Physical Activity\n",
"**Table of contents**\n",
"\n",
"- Overview\n",
"\n",
"- Setup\n",
"\n",
" - Authentication Token\n",
"\n",
"- Query\n",
"\n",
" - Output Description\n",
"\n",
"- Related Links"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Overview\n",
"\n",
"Use the Physical Activity API to calculate emissions from physical activities and operations. The API supports emissions accounting aligned with Scope 3 Category 15 (Investments) under the GHG Protocol, enabling organizations to estimate financed emissions based on physical activity data such as area-based metrics for commercial real estate and other physical operations.\n",
"\n",
"In the API request, you provide the activity type, value, and unit of measurement. The API response provides a breakdown of emissions by gas and an aggregate CO2e value. The API supports attribution for private companies using equity/debt based calculations or EVIC (Enterprise Value Including Cash)."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Setup\n",
"Ensure that Python 3+ is installed on your system.\n",
"\n",
"Note: To run this notebook, you must first add your credentials to `'../../../auth/secrets.ini'` in the following format:\n",
"\n",
"```\n",
"[EAPI]\n",
"api.pat_token = \n",
"api.tenant_id = \n",
"```"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Install the prerequisite Python packages.\n",
"\n",
"%pip install pandas configparser IPython requests"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import pandas as pd\n",
"import configparser\n",
"import requests\n",
"import json\n",
"from IPython.display import display as display_summary"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Authentication Token\n",
"Run the following code snippet to generate a Bearer Token by using your api_key configured in secrets.ini."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"config = configparser.RawConfigParser()\n",
"config.read(['../../../auth/secrets.ini','../../../auth/config.ini'])\n",
"\n",
"EAPI_PAT_TOKEN = config.get('EAPI', 'api.pat_token')\n",
"EAPI_TENANT_ID = config.get('EAPI', 'api.tenant_id')\n",
"EAPI_CLIENT_ID = 'ghgemissions-' + EAPI_TENANT_ID\n",
"\n",
"EAPI_AUTH_CLIENT_ID = 'saascore-' + EAPI_TENANT_ID\n",
"EAPI_AUTH_ENDPOINT = config.get('EAPI', 'api.auth_endpoint')\n",
"\n",
"EAPI_BASE_URL = config.get('EAPI', 'api.base_url')\n",
"EAPI_ENDPOINT = f\"{EAPI_BASE_URL}/physical-activity\"\n",
"\n",
"auth_request_headers: dict = {}\n",
"auth_request_headers[\"X-IBM-Client-Id\"] = EAPI_AUTH_CLIENT_ID\n",
"auth_request_headers[\"X-IBM-Envizi-Pat\"] = EAPI_PAT_TOKEN\n",
"\n",
"verify = True\n",
"\n",
"auth_url = f\"{EAPI_AUTH_ENDPOINT}\"\n",
"\n",
"response = requests.post(url = auth_url,\n",
" headers = auth_request_headers,\n",
" verify = verify\n",
" )\n",
"if response.status_code == 200:\n",
" jwt_token = response.text\n",
" print(\"Authentication Success\")\n",
"else: \n",
" print(\"Authentication Failed\")\n",
" print(response.text)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Query\n",
"\n",
"The example request payload (below) queries IBM Envizi - Emissions API for the emissions generated from 0.1 square kilometers of commercial real estate in the USA:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"payload = {\n",
" \"activity\": {\n",
" \"type\": \"commercial real estate\",\n",
" \"value\": 0.1,\n",
" \"unit\": \"km2\"\n",
" },\n",
" \"location\": {\n",
" \"country\": \"USA\"\n",
" },\n",
" \"time\": {\n",
" \"date\": \"2025-01-23\"\n",
" }\n",
"}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Query with Attribution (Equity/Debt Based)\n",
"\n",
"The example request payload (below) includes attribution for private companies using equity and debt values. This is useful for calculating financed emissions based on ownership structure:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"payload_with_equity_debt = {\n",
" \"activity\": {\n",
" \"type\": \"commercial real estate\",\n",
" \"value\": 0.1,\n",
" \"unit\": \"km2\"\n",
" },\n",
" \"location\": {\n",
" \"country\": \"USA\"\n",
" },\n",
" \"time\": {\n",
" \"date\": \"2025-01-23\"\n",
" },\n",
" \"attribution\": {\n",
" \"outstandingAmount\": 1000000,\n",
" \"totalEquity\": 3000000,\n",
" \"totalDebt\": 2000000\n",
" }\n",
"}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Query with Attribution (EVIC Based)\n",
"\n",
"The example request payload (below) includes attribution using EVIC (Enterprise Value Including Cash). This method is useful for calculating financed emissions based on enterprise value:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"payload_with_evic = {\n",
" \"activity\": {\n",
" \"type\": \"commercial real estate\",\n",
" \"value\": 0.1,\n",
" \"unit\": \"km2\"\n",
" },\n",
" \"location\": {\n",
" \"country\": \"USA\"\n",
" },\n",
" \"time\": {\n",
" \"date\": \"2025-01-23\"\n",
" },\n",
" \"attribution\": {\n",
" \"outstandingAmount\": 1000000.0,\n",
" \"evic\": 10000000.0\n",
" }\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Create the query headers\n",
"request_headers: dict = {}\n",
"request_headers[\"Content-Type\"] = \"application/json\"\n",
"request_headers[\"x-ibm-client-id\"] = EAPI_CLIENT_ID\n",
"request_headers[\"Authorization\"] = \"Bearer \" + jwt_token\n",
"\n",
"# Submit the request\n",
"response = requests.post(EAPI_ENDPOINT, \n",
" headers = request_headers,\n",
" data = json.dumps(payload))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"For more information about allowable parameters for the payload, please see [Emissions API Developer Guide](https://developer.ibm.com/apis/catalog/ghgemissions--ibm-envizi-emissions-api/Introduction)."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"if response.text != \"\":\n",
" # Get the response as json\n",
" response_json = response.json()\n",
" \n",
" # Get json and convert to dataframe\n",
" json_str = json.dumps(response_json)\n",
" dict = json.loads(json_str)\n",
" dataframe = pd.json_normalize(dict) \n",
" \n",
" # display\n",
" print(\"\\n\\n\")\n",
" pd.set_option('display.max_colwidth', None)\n",
" display( dataframe) \n",
"else:\n",
" print(\"Empty Response\") "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Output Explanation\n",
"\n",
"transactionId - An Emissions API transaction id.\n",
"\n",
"totalCO2e - The total emissions as CO2 equivalent (CO2e)\n",
"\n",
"co2 - The amount of CO2 (Carbon Dioxide) in the CO2e value.\n",
"\n",
"ch4 - The amount of CH4 (Methane) in the CO2e value.\n",
"\n",
"n2O - The amount of N2O (Nitrous Oxide) in the CO2e value.\n",
"\n",
"hfc - The amount of HFCs (Hydrofluorocarbons) in the CO2e value.\n",
"\n",
"pfc - The amount of PFCs (Perfluorocarbons) in the CO2e value.\n",
"\n",
"sf6 - The amount of SF6 (Sulphur Hexafluoride) in the CO2e value.\n",
"\n",
"nf3 - The amount of NF3 (Nitrogen Trifluoride) in the CO2e value.\n",
"\n",
"bioCo2 - The amount of bio CO2 in the CO2 value.\n",
"\n",
"indirectCo2e - The amount of CO2e that is indirect in the CO2e value.\n",
"\n",
"unit - The unit of measure of the values.\n",
"\n",
"description - A description of the source factor set of the factor used in the calculation."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Related Links\n",
"\n",
"[Emissions API Developer Guide](https://developer.ibm.com/apis/catalog/ghgemissions--ibm-envizi-emissions-api/Introduction)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.0"
}
},
"nbformat": 4,
"nbformat_minor": 4
}