28 Mar 2025

Create a Python REST API server

Sometimes when using a low-code/no-code environment to create a solution you still need a bit of programming that might be difficult to achieve there.

In that case you could implement the needed functionality somewhere else, expose it e.g. as a REST API endpoint and use it from the low-code/no-code environment.

Such functionality could be generating an SSA token.
Since it's not resource intensive at all, you just need to run a tiny bit of code once every hour, it might be possible with a free hosted solution as well.

When looking for such a solution for Python, I found https://www.pythonanywhere.com and gave that a try.
(Note: we also have a blog post on creating a Python web app and this toolkit might also be useful if using Python with APS)

1) Sign up

Signing up

2) Create a new Flask web app

On the "Web" tab

  1. Click "Add a new web app"
  2. Click "Next"
  3. Select "Flask"
  4. Select "Python 3.10"
  5. Click "Next"

Create Flask web app

3) Expose a REST API endpoint

At the end of the previous step you ended up on the configuration page of your new web app.
You just have to

  1. Scroll down
  2. Click on "Go to directory" of the "Source code"
  3. Click on "flask_app.py" to edit its content

Edit flask_app.py

We just have to replace the file's content with this: 

import jwt, time, requests
from flask import Flask, json, request

app = Flask(__name__)

def generate_jwt_assertion(KEY_ID, PRIVATE_KEY, APS_CLIENT_ID, SSA_OXYGEN_ID, SCOPE):
    return jwt.encode({
        "iss": APS_CLIENT_ID,
        "sub": SSA_OXYGEN_ID,
        "aud": "https://developer.api.autodesk.com/authentication/v2/token",
        "exp": int(time.time()) + 300,
        "scope": SCOPE.split(" ")
    }, PRIVATE_KEY, algorithm="RS256", headers={"alg": "RS256", "kid": KEY_ID})

def get_access_token(jwt_assertion, APS_CLIENT_ID, APS_SECRET_ID, SCOPE):
    response = requests.post('https://developer.api.autodesk.com/authentication/v2/token', headers={
        'Accept': 'application/json',
        'Content-Type': 'application/x-www-form-urlencoded'
    }, data={
        'grant_type': 'urn:ietf:params:oauth:grant-type:jwt-bearer',
        'assertion': jwt_assertion,
        'scope': SCOPE
    }, auth=(APS_CLIENT_ID, APS_SECRET_ID))
    return response.json()

@app.route('/ssatokenjson', methods=['POST'])
def post_ssatokenjson():
    data = request.get_json()
    APS_CLIENT_ID = data['APS_CLIENT_ID']
    APS_SECRET_ID = data['APS_SECRET_ID']
    SSA_OXYGEN_ID = data['SSA_OXYGEN_ID']
    KEY_ID = data['KEY_ID']
    PRIVATE_KEY = data['PRIVATE_KEY']
    SCOPE = data['SCOPE']
    jwt_assertion = generate_jwt_assertion(KEY_ID, PRIVATE_KEY, APS_CLIENT_ID, SSA_OXYGEN_ID, SCOPE)
    access_token = get_access_token(jwt_assertion, APS_CLIENT_ID, APS_SECRET_ID, SCOPE)
    return json.dumps(access_token)

Then click the highlighted button to refresh our web app:

Refresh web app

4) Test REST API endpoint

Now we can use a program like Insomnia (or Postman, etc) to test the endpoint, in our case called https://adamthenagy.pythonanywhere.com/ssatokenjson 
It just requires the Content-Type: application/json header and a json body like this containing the values for APS_CLIENT_IDAPS_SECRET_IDSSA_OXYGEN_IDKEY_IDPRIVATE_KEYSCOPE

In cURL it would look like this:

curl --request POST \
  --url https://adamthenagy.pythonanywhere.com/ssatokenjson \
  --header 'Content-Type: application/json' \
  --data '{
	"APS_CLIENT_ID": "BRbIPA_____JmAjR",
	"APS_SECRET_ID": "uDWyuA__________lAoKjCW6",
	"SSA_OXYGEN_ID": "76Z____UGE",
	"KEY_ID": "3aa5b72e-_______-ccb5bbc874d3",
	"PRIVATE_KEY": "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCA________IpqAaMbE2P65SrcD\n-----END RSA PRIVATE KEY-----\n",
	"SCOPE": "data:read data:write data:create data:search"	
}'

REST API test in Insomnia

Related Article