SAP Cloud Foundry – Python and Cloud Connector – HTTP

Estimated read time 17 min read
SAP Cloud Foundry enables developers to create full-stack applications with seamless backend integration to on-premise systems. This blog explains how to use Python to connect to on-premise resources through the SAP Cloud Connector. Python is the preferred language in the AI ecosystem, making it increasingly important for developing intelligent agents. For instance, we may want our agent to access APIs in an S4HANA system. With the Cloud Connector, this can be done securely within the enterprise environment.

Access HTTP-based resources:

In this scenario, we want to connect to an HTTP-based API, such as a RESTful API or an OData service, using Python in SAP Cloud Foundry. To do this, we need to set up the SAP Cloud Connector.

For this demonstration, we will use a simple “Hello World” server running locally on my computer. The goal is to access this local server from the SAP Cloud Foundry runtime through the Cloud Connector. This setup will show how to bridge cloud applications with on-premise resources.

Szenario Architecture

Prerequisite:

Before proceeding with the steps outlined in this guide, it is essential to have an instance of the SAP Cloud Connector installed. While it is possible to install the cloud connector on a server, for the purposes of this demonstration, we will be using a Windows machine. We recommend following the instructions provided in this blog (https://blogs.sap.com/2021/09/05/installation-and-configuration-of-sap-cloud-connector/) to install and configure the cloud connector.

Second requirement is a BTP subaccount with a Cloud Foundry Environment. To this subaccount we will connect the Cloud Connector.

1. Cloud Connector Configuration:

The first step is to create a configuration in the Cloud Connector that connects to our subaccount and exposes the HTTP resource. For the purpose of this demonstration, I ran a small Node.js server on my Windows machine that outputs “Hello World”.

Localhost Example Server

To create the configuration, navigate to the admin interface for the cloud connector and create a “Cloud to On-Premise” configuration.

Cloud To On-Premise Configuration

In the screenshot above, you can see that I exposed the internal host “localhost” with port 3333 via a virtual host called “virtualhost”. This virtual host is the host that we will be requesting from the BTP side. For the time being, I exposed all paths using an unrestricted access policy, but in production scenarios, access policies can be defined more granularly.

BTP Registered Cloud Connectors

On the BTP end, we can check the cockpit and the connected cloud connectors in the respective menu tab. If you cannot see this tab, you may be missing some roles. It is important to note that we see the LocationID “FELIXLAPTOP”, which is an identifier that distinguishes multiple cloud connectors connected to the same subaccount.

2. Create Connectivity Service instance:

To use the Cloud Connector from our runtime environment, we first need a connectivity service instance. Here’s how to do it:

In the BTP Cockpit, go to your desired Subaccount and create a new service instance, as shown below.

We use the “Connectivity Service” with the plan “lite”. Give the service instance a name, assign it to a space, and click create.

The important credentials are stored in a service key. To get these credentials, we create a service key.

 

{
“clientid”: “sb-sampleclientid!b3008|connectivity!b137”,
“clientsecret”: “****-****-****-****”,
“url”: “https://tenant_name.authentication.sap.hana.ondemand.com”,
“identityzone”: “sample-zone”,
“tenantid”: “xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx”,
“tenantmode”: “dedicated”,
“verificationkey”: “—–BEGIN PUBLIC KEY—–nXXXXXX…n—–END PUBLIC KEY—–“,
“xsappname”: “sampleappname!b3008|connectivity!b137”,
“uaadomain”: “authentication.sap.hana.ondemand.com”,
“credential-type”: “binding-secret”,
“onpremise_proxy_host”: “connectivityproxy.internal.cf.sap.hana.ondemand.com”,
“onpremise_proxy_http_port”: “20003”,
“onpremise_proxy_ldap_port”: “20001”,
“onpremise_proxy_port”: “20003”,
“onpremise_proxy_rfc_port”: “20001”,
“onpremise_socks5_proxy_port”: “20004”,
“token_service_domain”: “authentication.sap.hana.ondemand.com”,
“token_service_url”: “https://tenant_name.authentication.sap.hana.ondemand.com”
}

 

We now have a set of credentials, as shown above. The key details are:

OAuth Credentials: These include the “clientid”, “clientsecret”, and “url”. They are used to authenticate when accessing the proxy.

Proxy Details: These include the “onpremise_proxy_host” and the various ports, such as “onpremise_proxy_port”, “onpremise_proxy_http_port”, and “onpremise_socks5_proxy_port”. These details are configured as the proxy to route traffic. The proxy securely tunnels requests through the Cloud Connector to the on-premise destination.

3. Developing a Cloud Foundry App:

 

Now let’s put this together in a simple Python example to perform an actual HTTP request:

The Python script will send a request using Python’s standard requests library. We use the connection details provided by the Connectivity Service. To route the traffic through the Cloud Connector, we specify the proxy configuration, including the host, port, and the proxy-authentication header.

 

import requests

# Connectivity Service Service Key
connectivity_service_key = {
“clientid”: “sb-sampleclientid!b3008|connectivity!b137”,
“clientsecret”: “****-****-****-****”,
“url”: “https://tenant_name.authentication.sap.hana.ondemand.com”,
“identityzone”: “sample-zone”,
“tenantid”: “xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx”,
“tenantmode”: “dedicated”,
“verificationkey”: “—–BEGIN PUBLIC KEY—–nXXXXXX…n—–END PUBLIC KEY—–“,
“xsappname”: “sampleappname!b3008|connectivity!b137”,
“uaadomain”: “authentication.sap.hana.ondemand.com”,
“credential-type”: “binding-secret”,
“onpremise_proxy_host”: “connectivityproxy.internal.cf.sap.hana.ondemand.com”,
“onpremise_proxy_http_port”: “20003”,
“onpremise_proxy_ldap_port”: “20001”,
“onpremise_proxy_port”: “20003”,
“onpremise_proxy_rfc_port”: “20001”,
“onpremise_socks5_proxy_port”: “20004”,
“token_service_domain”: “authentication.sap.hana.ondemand.com”,
“token_service_url”: “https://tenant_name.authentication.sap.hana.ondemand.com”
}

# Target Application Details (replace with your app information)
application_host = “virtualhost”
application_port = 3333
application_path = “/hello”
location_id = “FELIXLAPTOP” # Adjust to match your Cloud Connector location

def get_connectivity_service_token(client_id, client_secret, token_service_url):
“””
Fetches an OAuth token from the SAP Connectivity Service.
“””
response = requests.post(
url=token_service_url,
params={“grant_type”: “client_credentials”},
auth=(client_id, client_secret)
)

if response.status_code != 200:
print(f”Error: {response.status_code} – {response.text}”)
exit(-1)

return response.json().get(“access_token”)

def example_http_request(host, port, path, auth_token, location_id, proxy_host):
“””
Performs an HTTP GET request through SAP Cloud Connector.
“””
url = f”http://{host}:{port}{path}”
headers = {
“Proxy-Authorization”: f”Bearer {auth_token}”,
“SAP-Connectivity-SCC-Location_ID”: location_id
}
proxies = {“http”: proxy_host}

response = requests.get(url, headers=headers, proxies=proxies, verify=False)
return response

# Fetch OAuth Token
print(“Fetching OAuth token…”)
token = get_connectivity_service_token(
connectivity_service_key[“clientid”],
connectivity_service_key[“clientsecret”],
connectivity_service_key[“token_service_url”] + “/oauth/token”
)
print(“Token acquired successfully.”)

# Build proxy URL
proxy_host = “http://” + connectivity_service_key[“onpremise_proxy_host”] + “:” + connectivity_service_key[“onpremise_proxy_port”]

# Perform HTTP Request
print(“Sending HTTP request through SAP Cloud Connector…”)
response = example_http_request(application_host, application_port, application_path, token, location_id, proxy_host)
print(“Response received:”)
print(response.content.decode(“utf-8”))
print(“Script execution completed.”)

 

 

First, we obtain a token from the OAuth 2.0 Token Service URL. This is done using the get_connectivity_service_token function, where we send the necessary credentials.

Note: Make sure to add /oauth/token at the end of the Token Service URL.

The response will return a Bearer Token, which we need to perform the actual HTTP request.

In the example_http_request function, we use Python’s requests library to send the request. The proxies option allows us to route the traffic through the Cloud Connector’s HTTP proxy. For this, we:

Combine the proxy_host (connectivity service proxy host) and port (e.g., HTTP port).For other traffic types, such as TCP-based traffic, we would use the SOCKS5 port.

We also include important headers:

Proxy-Authorization: This includes the Bearer Token (“Bearer <token>”).SAP-Connectivity-Location-ID: This optional header specifies the location ID of the connected Cloud Connector. For example, if my Cloud Connector is connected under “FELIXLAPTOP”, I include this value.

The actual destination URL points to the virtual host and virtual port configured in the Cloud Connector. For this example:

virtualhost:3333 communicates with my local server.The path /hello returns a sample message.

Finally, we combine all steps into a simple sequential script to demonstrate the entire flow.

To make it deployable on Cloud Foundry, we add a standard manifest.yaml file.

 


applications:
– name: cloud_connector_test_task
memory: 128MB
buildpack: python_buildpack
command: python app.py

 

It sets the buildpack to python_buildpack.

Additionally, we include a requirements.txt file in the directory.

 

requests

 

 

Ending up with the following structure:

 

my-python-cloud-connector-app/
│
├── manifest.yaml
├── requirements.txt
├── app.py (or your main Python script)

 

Note: The script we created obviously does not run on our local environment. Because a) we cannot connect to the connectivity service from outside of the BTP and b) the destination URL is not reachable from our local environment. In this blog, I show how to use a hybrid testing setup to develop against backend resources that  are behind the cloud connector.

4. Testing the Application:

Now lets deploy using the following command:

 

cf push cloud_connector_test_task –task

 

You push your script as a task (one-time executable) to the Cloud Foundry space. Then, you start the task using the following command:

 

cf run-task cloud_connector_test_task –command “python app.py” –name example_task
cf logs cloud_connector_test_task –recent

 

 

This will show the logs from the latest task execution. It may take a few seconds for the task to start and complete.

In the logs, if everything worked correctly, you should see the “Hello World” message from your on-premises PC, confirming that the connection through the Cloud Connector was successful.

 

2024-12-17T15:25:11.52+0100 [APP/TASK/example_task/0] OUT Fetching OAuth token…
2024-12-17T15:25:11.69+0100 [APP/TASK/example_task/0] OUT Token acquired successfully.
2024-12-17T15:25:11.69+0100 [APP/TASK/example_task/0] OUT Sending HTTP request through SAP Cloud Connector…
2024-12-17T15:25:13.66+0100 [APP/TASK/example_task/0] OUT Response received:
2024-12-17T15:25:13.66+0100 [APP/TASK/example_task/0] OUT {“message”:”Hello World 2024-12-17T14:25:13.444Z”}
2024-12-17T15:25:13.66+0100 [APP/TASK/example_task/0] OUT Script execution completed.

 

That means we have successfully established connectivity via the cloud connector and made a HTTP request.

In the next blog I will show how to create a TCP socket in Python to connect to TCP resources.

Hope you find the content of this blog helpful. Feel free to comment for further clarifications.

 

​ SAP Cloud Foundry enables developers to create full-stack applications with seamless backend integration to on-premise systems. This blog explains how to use Python to connect to on-premise resources through the SAP Cloud Connector. Python is the preferred language in the AI ecosystem, making it increasingly important for developing intelligent agents. For instance, we may want our agent to access APIs in an S4HANA system. With the Cloud Connector, this can be done securely within the enterprise environment.Access HTTP-based resources:In this scenario, we want to connect to an HTTP-based API, such as a RESTful API or an OData service, using Python in SAP Cloud Foundry. To do this, we need to set up the SAP Cloud Connector.For this demonstration, we will use a simple “Hello World” server running locally on my computer. The goal is to access this local server from the SAP Cloud Foundry runtime through the Cloud Connector. This setup will show how to bridge cloud applications with on-premise resources.Szenario ArchitecturePrerequisite:Before proceeding with the steps outlined in this guide, it is essential to have an instance of the SAP Cloud Connector installed. While it is possible to install the cloud connector on a server, for the purposes of this demonstration, we will be using a Windows machine. We recommend following the instructions provided in this blog (https://blogs.sap.com/2021/09/05/installation-and-configuration-of-sap-cloud-connector/) to install and configure the cloud connector.Second requirement is a BTP subaccount with a Cloud Foundry Environment. To this subaccount we will connect the Cloud Connector.1. Cloud Connector Configuration:The first step is to create a configuration in the Cloud Connector that connects to our subaccount and exposes the HTTP resource. For the purpose of this demonstration, I ran a small Node.js server on my Windows machine that outputs “Hello World”.Localhost Example ServerTo create the configuration, navigate to the admin interface for the cloud connector and create a “Cloud to On-Premise” configuration.Cloud To On-Premise ConfigurationIn the screenshot above, you can see that I exposed the internal host “localhost” with port 3333 via a virtual host called “virtualhost”. This virtual host is the host that we will be requesting from the BTP side. For the time being, I exposed all paths using an unrestricted access policy, but in production scenarios, access policies can be defined more granularly.BTP Registered Cloud ConnectorsOn the BTP end, we can check the cockpit and the connected cloud connectors in the respective menu tab. If you cannot see this tab, you may be missing some roles. It is important to note that we see the LocationID “FELIXLAPTOP”, which is an identifier that distinguishes multiple cloud connectors connected to the same subaccount.2. Create Connectivity Service instance:To use the Cloud Connector from our runtime environment, we first need a connectivity service instance. Here’s how to do it:In the BTP Cockpit, go to your desired Subaccount and create a new service instance, as shown below.We use the “Connectivity Service” with the plan “lite”. Give the service instance a name, assign it to a space, and click create.The important credentials are stored in a service key. To get these credentials, we create a service key. {
“clientid”: “sb-sampleclientid!b3008|connectivity!b137”,
“clientsecret”: “****-****-****-****”,
“url”: “https://tenant_name.authentication.sap.hana.ondemand.com”,
“identityzone”: “sample-zone”,
“tenantid”: “xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx”,
“tenantmode”: “dedicated”,
“verificationkey”: “—–BEGIN PUBLIC KEY—–nXXXXXX…n—–END PUBLIC KEY—–“,
“xsappname”: “sampleappname!b3008|connectivity!b137”,
“uaadomain”: “authentication.sap.hana.ondemand.com”,
“credential-type”: “binding-secret”,
“onpremise_proxy_host”: “connectivityproxy.internal.cf.sap.hana.ondemand.com”,
“onpremise_proxy_http_port”: “20003”,
“onpremise_proxy_ldap_port”: “20001”,
“onpremise_proxy_port”: “20003”,
“onpremise_proxy_rfc_port”: “20001”,
“onpremise_socks5_proxy_port”: “20004”,
“token_service_domain”: “authentication.sap.hana.ondemand.com”,
“token_service_url”: “https://tenant_name.authentication.sap.hana.ondemand.com”
} We now have a set of credentials, as shown above. The key details are:OAuth Credentials: These include the “clientid”, “clientsecret”, and “url”. They are used to authenticate when accessing the proxy.Proxy Details: These include the “onpremise_proxy_host” and the various ports, such as “onpremise_proxy_port”, “onpremise_proxy_http_port”, and “onpremise_socks5_proxy_port”. These details are configured as the proxy to route traffic. The proxy securely tunnels requests through the Cloud Connector to the on-premise destination.3. Developing a Cloud Foundry App: Now let’s put this together in a simple Python example to perform an actual HTTP request:The Python script will send a request using Python’s standard requests library. We use the connection details provided by the Connectivity Service. To route the traffic through the Cloud Connector, we specify the proxy configuration, including the host, port, and the proxy-authentication header. import requests

# Connectivity Service Service Key
connectivity_service_key = {
“clientid”: “sb-sampleclientid!b3008|connectivity!b137”,
“clientsecret”: “****-****-****-****”,
“url”: “https://tenant_name.authentication.sap.hana.ondemand.com”,
“identityzone”: “sample-zone”,
“tenantid”: “xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx”,
“tenantmode”: “dedicated”,
“verificationkey”: “—–BEGIN PUBLIC KEY—–nXXXXXX…n—–END PUBLIC KEY—–“,
“xsappname”: “sampleappname!b3008|connectivity!b137”,
“uaadomain”: “authentication.sap.hana.ondemand.com”,
“credential-type”: “binding-secret”,
“onpremise_proxy_host”: “connectivityproxy.internal.cf.sap.hana.ondemand.com”,
“onpremise_proxy_http_port”: “20003”,
“onpremise_proxy_ldap_port”: “20001”,
“onpremise_proxy_port”: “20003”,
“onpremise_proxy_rfc_port”: “20001”,
“onpremise_socks5_proxy_port”: “20004”,
“token_service_domain”: “authentication.sap.hana.ondemand.com”,
“token_service_url”: “https://tenant_name.authentication.sap.hana.ondemand.com”
}

# Target Application Details (replace with your app information)
application_host = “virtualhost”
application_port = 3333
application_path = “/hello”
location_id = “FELIXLAPTOP” # Adjust to match your Cloud Connector location

def get_connectivity_service_token(client_id, client_secret, token_service_url):
“””
Fetches an OAuth token from the SAP Connectivity Service.
“””
response = requests.post(
url=token_service_url,
params={“grant_type”: “client_credentials”},
auth=(client_id, client_secret)
)

if response.status_code != 200:
print(f”Error: {response.status_code} – {response.text}”)
exit(-1)

return response.json().get(“access_token”)

def example_http_request(host, port, path, auth_token, location_id, proxy_host):
“””
Performs an HTTP GET request through SAP Cloud Connector.
“””
url = f”http://{host}:{port}{path}”
headers = {
“Proxy-Authorization”: f”Bearer {auth_token}”,
“SAP-Connectivity-SCC-Location_ID”: location_id
}
proxies = {“http”: proxy_host}

response = requests.get(url, headers=headers, proxies=proxies, verify=False)
return response

# Fetch OAuth Token
print(“Fetching OAuth token…”)
token = get_connectivity_service_token(
connectivity_service_key[“clientid”],
connectivity_service_key[“clientsecret”],
connectivity_service_key[“token_service_url”] + “/oauth/token”
)
print(“Token acquired successfully.”)

# Build proxy URL
proxy_host = “http://” + connectivity_service_key[“onpremise_proxy_host”] + “:” + connectivity_service_key[“onpremise_proxy_port”]

# Perform HTTP Request
print(“Sending HTTP request through SAP Cloud Connector…”)
response = example_http_request(application_host, application_port, application_path, token, location_id, proxy_host)
print(“Response received:”)
print(response.content.decode(“utf-8”))
print(“Script execution completed.”)  First, we obtain a token from the OAuth 2.0 Token Service URL. This is done using the get_connectivity_service_token function, where we send the necessary credentials.Note: Make sure to add /oauth/token at the end of the Token Service URL.The response will return a Bearer Token, which we need to perform the actual HTTP request.In the example_http_request function, we use Python’s requests library to send the request. The proxies option allows us to route the traffic through the Cloud Connector’s HTTP proxy. For this, we:Combine the proxy_host (connectivity service proxy host) and port (e.g., HTTP port).For other traffic types, such as TCP-based traffic, we would use the SOCKS5 port.We also include important headers:Proxy-Authorization: This includes the Bearer Token (“Bearer <token>”).SAP-Connectivity-Location-ID: This optional header specifies the location ID of the connected Cloud Connector. For example, if my Cloud Connector is connected under “FELIXLAPTOP”, I include this value.The actual destination URL points to the virtual host and virtual port configured in the Cloud Connector. For this example:virtualhost:3333 communicates with my local server.The path /hello returns a sample message.Finally, we combine all steps into a simple sequential script to demonstrate the entire flow.To make it deployable on Cloud Foundry, we add a standard manifest.yaml file. —
applications:
– name: cloud_connector_test_task
memory: 128MB
buildpack: python_buildpack
command: python app.py It sets the buildpack to python_buildpack.Additionally, we include a requirements.txt file in the directory. requests  Ending up with the following structure: my-python-cloud-connector-app/
│
├── manifest.yaml
├── requirements.txt
├── app.py (or your main Python script) Note: The script we created obviously does not run on our local environment. Because a) we cannot connect to the connectivity service from outside of the BTP and b) the destination URL is not reachable from our local environment. In this blog, I show how to use a hybrid testing setup to develop against backend resources that  are behind the cloud connector.4. Testing the Application:Now lets deploy using the following command: cf push cloud_connector_test_task –task You push your script as a task (one-time executable) to the Cloud Foundry space. Then, you start the task using the following command: cf run-task cloud_connector_test_task –command “python app.py” –name example_task
cf logs cloud_connector_test_task –recent  This will show the logs from the latest task execution. It may take a few seconds for the task to start and complete.In the logs, if everything worked correctly, you should see the “Hello World” message from your on-premises PC, confirming that the connection through the Cloud Connector was successful. 2024-12-17T15:25:11.52+0100 [APP/TASK/example_task/0] OUT Fetching OAuth token…
2024-12-17T15:25:11.69+0100 [APP/TASK/example_task/0] OUT Token acquired successfully.
2024-12-17T15:25:11.69+0100 [APP/TASK/example_task/0] OUT Sending HTTP request through SAP Cloud Connector…
2024-12-17T15:25:13.66+0100 [APP/TASK/example_task/0] OUT Response received:
2024-12-17T15:25:13.66+0100 [APP/TASK/example_task/0] OUT {“message”:”Hello World 2024-12-17T14:25:13.444Z”}
2024-12-17T15:25:13.66+0100 [APP/TASK/example_task/0] OUT Script execution completed. That means we have successfully established connectivity via the cloud connector and made a HTTP request.In the next blog I will show how to create a TCP socket in Python to connect to TCP resources.Hope you find the content of this blog helpful. Feel free to comment for further clarifications.   Read More Technology Blogs by SAP articles 

#SAP

#SAPTechnologyblog

You May Also Like

More From Author