Technology Blog Posts by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
qiangwan87
Discoverer
641

In this blog, we are going to demonstrate basic python development in business application studio, and how to deploy it in Cloud Foundry. 

Create Dev space

Open Business Application Studio and create a dev space Python of "Basic" kind with "Python Tools" extension selected.

01.png

Create a Python application

In the Python dev space, create a new project directory mypython. In addition also create a virtual environment env and activate it. Run following commands. 

cd projects
mkdir mypython
cd mypython
python3 -m venv env 
source env/bin/activate
touch mta.yaml
touch xs-security.json
mkdir app-router
mkdir app-router/resources
touch app-router/resources/index.html
touch app-router/xs-app.json
mkdir python-src
touch python-src/main.py
touch python-src/requirements.txt

app-router/resources/index.html

<html>
<head>
    <title>Python</title>
</head>
<body>
    <h1>My Python Application</h1>
</body>
</html>

app-router/xs-app.json

{
    "welcomeFile": "index.html",
    "authenticationMethod": "route",
    "routes": [
        {
            "source": "^/(.*)$",
            "target": "/",
            "destination": "dest_python"
        }
    ]
}

python-src/requirements.txt

Flask
cfenv
sap-xssec
PyJWT
requests

python-src/main.py

import os
import requests
from flask import Flask, request, abort
from cfenv import AppEnv
from sap import xssec

app = Flask(__name__)
env = AppEnv()

port = int(os.environ.get('PORT', 3000))
xuaa_service = env.get_service(name='mypython-auth')
dest_service = env.get_service(name='mypython-dest')

@app.route('/')
def hello():
    if 'authorization' not in request.headers:
        abort(401)

    access_token = request.headers.get('authorization')[7:]
    security_context = xssec.create_security_context(access_token, xuaa_service.credentials)
    isAuthorized = security_context.check_scope('$XSAPPNAME.python')

    if not isAuthorized:
        abort(403)

    return "Congratulations! You are authenticated!"

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=port)

xs-security.json

{
    "xsappname": "mypython-auth",
    "tenant-mode": "dedicated",
    "oauth2-configuration": {
        "redirect-uris": [
            "https://**.hana.ondemand.com/**"
        ]
    },
    "scopes": [
        {
            "name": "$XSAPPNAME.python",
            "description": "python"
        }
    ],
    "attributes": [],
    "role-templates": [
        {
            "name": "python",
            "description": "my python role",
            "scope-references": ["$XSAPPNAME.python"],
            "attribute-references": []
        }
    ],
    "role-collections": [
        {
            "name": "python",
            "description": "With this role users can access My Python app",
            "role-template-references": ["$XSAPPNAME.python"]
        }
    ]
}

mta.yaml

_schema-version: '3.2'
ID: mypython
version: 1.0.0
description: sample python application
modules:
  - name: mypython-approuter
    type: html5
    path: app-router
    properties:
      destinations: >
        [
          {
            "name":"dest_python",
            "url":"https://${space}-mypython-backend.${default-domain}",
            "forwardAuthToken": true
          }
        ]
    parameters:
      memory: 256M
      disk-quota: 256M
    requires:
      - name: mypython-auth 
    build-parameters:
      ignore: ["node_modules"]

  - name: mypython-backend
    type: python
    path: python-src
    parameters:
      routes:
        - route: https://${space}-${app-name}.${default-domain}
      buildpack: python_buildpack
      memory: 256M
      disk-quota: 256M
      command: python main.py
    requires:
      - name: mypython-auth

resources:
  - name: mypython-auth
    type: org.cloudfoundry.managed-service
    parameters:
      service: xsuaa
      service-plan: application
      path: ./xs-security.json
      config:
        xsappname: mypython
        tenant-mode: dedicated

Install approuter module

Under the app-router directory, run command "npm init". Press Enter on every step. This process will walk you through creating a package.json file.

02.png

Next run command "npm install @SAP/approuter --save"This generates package-lock.json and node_modules folder. 

Open package.json and update the scripts section (line 6). It calls approuter. 

{
  "name": "app-router",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
    "start": "node node_modules/@sap/approuter/approuter.js"
  },
  "author": "",
  "license": "ISC",
  "description": "",
  "dependencies": {
    "@sap/approuter": "^20.3.1"
  }
}

Install python libraries

Under project root directory run command "pip install -r python-src/requirements.txt". 

Build & Deploy

Under project root, run command "mta build" to create a mta archive. Then run command "cf deploy mta_archives/mypython_...". Wait until the deployment to finish.

Login to BTP subaccount >> Cloud Foundry >> Spaces, we can see two applications were created. 

qiangwan87_0-1746812646038.png

Testing

Prior to access the application, we need to assign the role collection "python" to our account. Then open the url of "mypython-approuter" application. 

qiangwan87_1-1746812796199.png

Login and then we will be see the output of "main.py" program. 

qiangwan87_2-1746812927385.png

In this blog, we covered a simple python program development and deployment in SAP BTP cloud foundry environment. Later on we will describe other aspects of python developments in BTP. Stay tuned!