Technology Blog Posts by Members
cancel
Showing results for 
Search instead for 
Did you mean: 
0 Likes
326

If you have ever been asked how many iFlows sit on a tenant, or which API proxies belong to which product, you already know how it goes. You open the UI, click into one package at a time, and copy names into a spreadsheet by hand. It takes a while, and the list is out of date the moment someone adds a new flow. I got tired of doing this, so I wrote a couple of small scripts to do it for me.

There are two scripts. Each one reads a different part of SAP Integration Suite and writes the result straight into an Excel file. They use the standard public OData APIs with an OAuth client credential, so nothing is installed on the tenant. You run them from your own machine and you get a clean spreadsheet at the end.

Here is the one thing to keep straight while you read. There are two separate scripts for two separate jobs:

  • cpi_inventory_export.py reads Cloud Integration and lists every integration package with the iFlows and the reusable artifacts inside each one.
  • apim_inventory_export.py reads API Management and lists every API proxy, the product it belongs to, and the applications subscribed to it.

They look alike and run the same way, but they connect to different services in BTP and need different roles. To avoid any mix up, I have written each one as its own part below. The download link for both is at the end.


What each script produces

Script Reads from Output file Sheets you get

cpi_inventory_export.pyCloud IntegrationCPI_Inventory.xlsxSummary, iFlows, Reusable Artifacts
apim_inventory_export.pyAPI ManagementAPIM_Inventory.xlsxSummary, API Proxies, API Products, Applications

The output is plain and easy to filter. The CPI file gives you one row per iFlow with its package name and its deployment status, plus a seperate sheet for the reusable artifacts like value mappings, message mappings and script collections. The APIM file gives you one row per proxy with the product it sits in and the apps subscribed to it, which is the view most people are really after.

gouthamshanmugam_0-1784914774730.png

gouthamshanmugam_1-1784914811489.png

Before you start

A few things need to be in place. These are the same for both scripts.

  • You can log in to the SAP BTP cockpit for your subaccount.
  • Cloud Integration or API Management is active in your Integration Suite tenant, depending on which script you want to run.
  • Python 3 is installed on your machine. You can check by opening a Command Prompt and running the command below.
python --version

If you see a version number come back, you are good. If the command is not recognised, install Python from python.org and tick the option to add it to PATH during setup.

gouthams11_2-1784375375178.png

Both scripts also need two small Python libraries. You only install these once, and the same two work for both scripts.

python -m pip install requests openpyxl

gouthams11_3-1784375619532.png


Part 1: Cloud Integration packages and iFlows (cpi_inventory_export.py)

This is the script that answers the question, what packages and iFlows do we have. It talks to the Process Integration Runtime service.

Step 1: Create the service instance

In your subaccount, open Service Marketplace and search for Process Integration Runtime. Open the tile and choose Create. On the Basic Info screen set these values:

  • Plan: api. This one matters. The integration-flow plan is only for sending messages to a deployed iFlow, and it will not list your packages. If you pick the wrong plan you get a 404 later.
  • Runtime Environment: Cloud Foundry
  • Space: your space, for example dev
  • Instance Name: cpi-extract

gouthams11_4-1784375694156.png

gouthams11_5-1784375760481.png

Step 2: Add the roles

Move to the Parameters step. In the Roles field select WorkspacePackagesRead and keep the grant type as Client Credentials. This role is what lets the script read your packages and iFlows. If you leave it out, the API later tells you it cannot find the entity set, which is a confusing error for what is really just a missing role.

One thing I added recently. The script now also shows the deployment status of each iFlow, whether it is Started, in Error, or Not Deployed, along with who deployed it and when. That status comes from the runtime side, so you also need to add MonitorDataRead here. If you skip it the script still runs fine, the status column just comes back as unknown. Once the roles are set, choose Create.

gouthams11_6-1784375799483.png

Step 3: Create the service key

Open the cpi-extract instance, go to Service Keys, and create one. Name it something like cpi-extract-key and leave the parameters box as the empty braces. Open the key in JSON view and copy these four values:

gouthams11_7-1784375902620.png

  • url
  • tokenurl
  • clientid
  • clientsecret

The Cloud Integration url usually has it-cpi in the host name and often ends with -rt. Make a mental note of that, because it is the easiest way to tell it apart from the API Management url in Part 2.

gouthams11_8-1784376048084.png

Step 4: Fill in the script and run it

Open cpi_inventory_export.py in any editor. Near the top, paste your four values inside the quotes and save. Keep the quotes in place.

CLIENT_ID = "your clientid"
CLIENT_SECRET = "your clientsecret"
TOKEN_URL = "your tokenurl"
API_URL = "your url"

gouthamshanmugam_4-1784913467931.png

Open a Command Prompt, move into the folder that holds the script, and run it.

cd "C:\path\to\your\folder"
python cpi_inventory_export.py

When it finishes you will see a line like Done. 12 packages and 40 artifacts exported to CPI_Inventory.xlsx. Open the file and you will find three sheets, a Summary with counts per package, an iFlows sheet on its own, and a Reusable Artifacts sheet for the value mappings, message mappings and script collections. All sitting in the same folder as the script.

gouthams11_10-1784376307852.pnggouthams11_11-1784376340972.png


Part 2: API Management proxies and products (apim_inventory_export.py)

This is the script that answers the question, what API proxies do we have and which product is each one in. It talks to the API Management, API portal service, which is a different service from Part 1.

Step 1: Create the service instance

In your subaccount, open Service Marketplace and search for API Management, API portal. Take care to pick this tile and not the developer portal tile next to it. Open it and choose Create. On the Basic Info screen set these values:

  • Plan: apiportal-apiaccess
  • Runtime Environment: Cloud Foundry
  • Space: your space, for example dev
  • Instance Name: api-extract

gouthams11_12-1784376397199.png

gouthams11_13-1784376444199.png

 

Step 2: Add the role

Move to the Parameters step. Here the role is entered as JSON, not picked from a list. This is the step people most often miss, and skipping it is what leaves you with an empty service key later. Type the role, then choose Create.

{ "role": "APIPortal.Administrator" }

Do not have the Administrator role? You do not need it for this. The Administrator role allows create, update, and delete, but this script only reads. If you cannot or should not use Administrator, use the read-only role instead:

{ "role": "APIPortal.Guest" }

APIPortal.Guest gives read-only access to the API portal, which is all the script needs to list your proxies and products. It is also the safer choice if you are following least privilege, so if you are unsure, start with Guest. Whichever role you choose, it goes here on the Parameters step of the instance, not on the service key.

gouthams11_15-1784376510124.png

Step 3: Create the service key

Open the api-extract instance, go to Service Keys, and create one. Name it something like api-extract-key and leave the parameters box as the empty braces. Open the key in JSON view and copy these four values:

gouthams11_16-1784376595391.png

  • url
  • tokenUrl
  • clientId
  • clientSecret

The API Management url has the word apiportal in the host name. This is the biggest difference from Part 1. If you accidentally use the Cloud Integration host, the one with it-cpi, you will get a 404, so double check you copied the url from this key and not the CPI one.

gouthams11_17-1784376737939.png

Step 4: Fill in the script and run it

Open apim_inventory_export.py in any editor. Near the top, paste your four values inside the quotes and save. Keep the quotes in place.

gouthamshanmugam_5-1784913528663.png

CLIENT_ID = "your clientId"
CLIENT_SECRET = "your clientSecret"
TOKEN_URL = "your tokenUrl"
API_URL = "your url"

There is one more optional value near the top called APIM_HOST. The script builds a callable API Proxy URL for every proxy, and it keeps it tenant neutral by writing it as https://<your-apim-host>/<base-path>. If you want the real URLs straight away, set APIM_HOST to your virtual host once. Otherwise just leave it and do a quick Find and Replace in Excel afterwards, either way works.

Open a Command Prompt, move into the folder that holds the script, and run it.

cd "C:\path\to\your\folder"
python apim_inventory_export.py

When it finishes you will see a line like Done. 1 proxies, 1 products, 1 applications exported to APIM_Inventory.xlsx. Open the file and you will find four sheets, a Summary, an API Proxies sheet with the full technical detail, an API Products sheet, and an Applications sheet. The API Proxies sheet now carries a lot more than before, the API type (REST, ODATA or SOAP), state, base paths, the API Proxy URL, the backend target URLs, the products, and the subscribed applications.

gouthams11_19-1784376893889.png

gouthams11_20-1784376943674.png

One small note on policies. I did try to pull the policies attached to each proxy as well, but the public management API does not expose them in a way that works the same across every tenant, so I left that column out rather than ship something half empty. If that changes I will add it back in.


Quick comparison of the two scripts

If you take away one thing from this blog, take away this table. It shows exactly where the two scripts differ, so you always know which value belongs to which script.

  cpi_inventory_export.py apim_inventory_export.py

Service in BTPProcess Integration RuntimeAPI Management, API portal
Planapiapiportal-apiaccess
Role(s)WorkspacePackagesRead, and MonitorDataRead for deployment statusAPIPortal.Administrator, or APIPortal.Guest for read-only
url containsit-cpiapiportal
Output fileCPI_Inventory.xlsxAPIM_Inventory.xlsx

Common issues

These are the problems you are most likely to hit, with the quick fix for each.

  • Service key is empty. The role was not set on the instance. Recreate the instance with the role, then make a new key. For API Management, remember you can use APIPortal.Guest if Administrator is not available.
  • 404 not found. Wrong host or wrong plan. Use the url from the correct service key, and check the plan.
  • Entity set not found on CPI. Add WorkspacePackagesRead and create a new key.
  • CPI status column shows unknown. That is the MonitorDataRead role missing. Add it to the instance and make a new key, the rest of the inventory is still fine without it.
  • 401 unauthorized. One of the four values is mistyped, or you put the service url into TOKEN_URL by mistake. The token url is the one with authentication in the host and it ends with /oauth/token. Copy them again from the key.
  • No module named requests. Run the pip install command again.
  • SyntaxError when you run the command. You are inside the Python shell, shown by three greater than signs. Type exit() first, then run the command from the normal prompt.

Download the scripts

Both scripts are on GitHub with a short README. Download them here and follow along. I keep pushing small improvements there, so the GitHub version is always the latest.

Download: cpi_inventory_export.py

Download: apim_inventory_export.py

If this saved you some clicking, drop a comment and tell me what you would like to see next. I am happy to extend the scripts, for example to add the last changed date for each artifact, or an API providers sheet on the APIM side.

1 Comment
EuricoBorges
Participant
0 Likes

@goutham-shanmugam beaware that your Phyton script for iflows inventory may bring more than what you want. 

Since you are using the /IntegrationDesigntimeArtifacts api you will get also non-iflows, if they exit in the package, like value mappings.