Reference Client

The following are example reference code written in Python provided to assist you in getting started. This is NOT production ready code. It is only meant to be used as a high level reference.

This example shows authentication via OpenID Connect and calling the createsr api.

#!/usr/bin/python3

from datetime import datetime, timezone
import json
import requests
import base64
import pprint
import time
import random
import urllib.parse
import string

base_url = "https://devapigateway.sndbx.junipercloud.net:443/css/sr/pp/v01"
api_path = "createsr"

oidc_id_token = "WQiOiJzMTBZa0hZNnRhVHgtWFNidWttV2ZkZW5Hb2x1Q2NlVkI3VWU1Z2JoTm5rIiwiYWxnIjoiUlMyNTYifQ.WIiOiIwMHVtYm84OHprZEJRVmxKTjBoNyIsIm5hbWUiOiJWZW5rYXQgQmVsbGFta29uZGEiLCJsb2NhbGUiOiJlbi1VUyIsInZlciI6MSwiaXNzIjoiaHR0cHM6Ly9qdW5pcGVyLXBvYy5va3RhcHJldmlldy5jb20vb2F1dGgyL2RlZmF1bHQiLCJhdWQiOiIwb2FmdHBqYXRrRmc5a3VuazBoNyIsImlhdCI6MTU3NDc4ODY5MSwiZXhwIjoxNTc0NzkyMjkxLCJqdGkiOiJJRC5VbFlibmVRVkxhekVpS0pXS2QwLUlERm96TV9sTGVoYzIwY1JFd2VGRUVBIiwiYW1yIjpbInB3ZCJdLCJpZHAiOiIwMG9mdGUxYXFjY1JrUTZmTTBoNyIsIm5vbmNlIjoicHNtZ1lWeFB6MlRIbUFmSTZlN0F5Q1NQc3o5TWtHaHciLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJ2ZW5rYXRiQGp1bmlwZXIubmV0IiwiZ2l2ZW5fbmFtZSI6IlZlbmthdCIsImZhbWlseV9uYW1lIjoiQmVsbGFta29uZGEiLCJ6b25laW5mbyI6IkFtZXJpY2EvTG9zX0FuZ2VsZXMiLCJ1cGRhdGVkX2F0IjoxNTY0NjE1MzUxLCJhdXRoX3RpbWUiOjE1NzQ3ODg2OTB9.yq_Udq_h4JcEbSJJI9uRJD6PtESsnj9qAzd8R0D4nNechWUAeiCThGJCFGn--MSRM-fhek8IY9RrXltUiRqDBTthTxKQHWt-JIp4zGNBVep0IGVE64SjK8dvD84-M1D3n-ZPWKusvQGtqpJPbeQoSeNrJulA-tdWZLS6Q3ke_0uUiuK7iWHnHX2m_VqKz0sga_uQmYCMTI_FBsqTfFrpSwoZCCXSE4sB-m3lLGy4Ho8PZEmYqlB6fxGnzui08cuNhjgsJKPMyohXJ2hwQQwBYxfSGRXa7g-adPSGoBbvDqYiDS0ijCwzRRxS_k2vr-I5vVTAtNjewozIFV0Um4-Tdg"

# define a call_api routine - prepares headers, post message to api url, print response
def call_api(api_path, payload):
    api_headers = {
        "Authorization": f"Bearer {oidc_id_token}",
        "Content-Type": "application/json",
        "Accept": "application/json",
    }

    response_data = requests.post(
        f"{base_url}/{api_path}/",
        headers=api_headers,
        json=payload,
        timeout=180,
    )

    print(response_data)
    response = json.loads(bytes.decode(response_data.content))
    pprint.PrettyPrinter().pprint(response)
    return response

# routine to use for requestDateTime key. current time in utc is returned
def isoformat_time_now():
    time_str = datetime.now(timezone.utc).isoformat(timespec='milliseconds')
    return time_str.replace('+00:00', 'Z')

# routine to use for generating a unique id for customerUniqueTransactionID key.
def get_unique_id():
    return ''.join(random.choices(string.ascii_uppercase + string.digits + string.ascii_lowercase, k=40))    


# request body - Example Technical Case - createSR request
request_body = {
  "createSRRequest" : {
    "appId" : "cCMUrMyyJUcOWxNBkmwDX11GU2nY2mlF3i15hIE5",
    "userId" : "johnsmith@pristineparts.com",
    "requestDateTime" : isoformat_time_now(),
    "caseInformation" : {
      "caseTypeCode" : "TEC",
      "customerCaseNumber" : "PP1000",
      "customerSourceID" : "pristineparts-partner",
      "customerUniqueTransactionID" : get_unique_id(),
      "addSenderToEmail" : true,
      "ccEmail" : "joe@pristineparts.com",
      "followUpMethod" : "Full",
      "networkOutage" : false,
      "synopsis" : "FEC errors on port of QFX device",
      "priority" : "P3 - Medium",
      "problemDescription" : "Large number of errors on 1/0/10. Moved SFP to another port. Issue went away. Please analyze issue with FPC"
    },
    "contact" : {
      "accountID" : "101412170",
      "contactEmail" : "frank@pristineparts.com",
      "preferredTelephoneCountryCode" : "US",
      "preferredTelephoneNumber" : "8889991234",
      "preferredTelephoneExtension" : "1234"
    },
    "product" : {
      "serialNumber" : "XY123",
      "routerName" : "sjc.sw12"
    }
 }
}

api_response = call_api(api_path, request_body)

This example shows calling the create api using Client Certificate Authentication mechanism.

#!/usr/bin/python3
import http.client
import json
import socket
import ssl
import logging
import pprint
import string
import random

base_url = "https://devapigateway.sndbx.junipercloud.net:443/css/sr/pp/v01"
api_path = "createsr"

server_cert = 'server_public_certificate.crt'
client_cert = 'client_public_certificate.crt'
client_key = 'client_private_certificate.key'

context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH, cafile=server_cert)
context.load_cert_chain(certfile=client_cert, keyfile=client_key)

request_headers = {
    'Content-Type': 'application/json',
    'accept':'application/json'
}

# routine to use for requestDateTime key. current time in utc is returned
def isoformat_time_now():
    time_str = datetime.now(timezone.utc).isoformat(timespec='milliseconds')
    return time_str.replace('+00:00', 'Z')

# routine to use for generating a unique id for customerUniqueTransactionID key.
def get_unique_id():
    return ''.join(random.choices(string.ascii_uppercase + string.digits + string.ascii_lowercase, k=40))    

# request body - Example Technical Case - createSR request
request_body = {
  "createSRRequest" : {
    "appId" : "cCMUrMyyJUcOWxNBkmwDX11GU2nY2mlF3i15hIE5",
    "userId" : "johnsmith@pristineparts.com",
    "requestDateTime" : isoformat_time_now(),
    "caseInformation" : {
      "caseTypeCode" : "TEC",
      "customerCaseNumber" : "PP1000",
      "customerSourceID" : "pristineparts-partner",
      "customerUniqueTransactionID" : get_unique_id(),
      "addSenderToEmail" : true,
      "ccEmail" : "joe@pristineparts.com",
      "followUpMethod" : "Full",
      "networkOutage" : false,
      "synopsis" : "FEC errors on port of QFX device",
      "priority" : "P3 - Medium",
      "problemDescription" : "Large number of errors on 1/0/10. Moved SFP to another port. Issue went away. Please analyze issue with FPC"
    },
    "contact" : {
      "accountID" : "101412170",
      "contactEmail" : "frank@pristineparts.com",
      "preferredTelephoneCountryCode" : "US",
      "preferredTelephoneNumber" : "8889991234",
      "preferredTelephoneExtension" : "1234"
    },
    "product" : {
      "serialNumber" : "XY123",
      "routerName" : "sjc.sw12"
    }
 }
}

# Create a connection to submit HTTP requests
connection = http.client.HTTPSConnection(host, port=443, context=context)

# Use connection to submit the HTTP POST request
request_url = f"{base_url}/{api_path}/"
connection.request(method="POST", url=request_url, headers=request_headers, body=json.dumps(request_body))

# Print the HTTP response from the service
response = connection.getresponse()
print(response.status, response.reason)

# Print the service response
data = response.read()
pprint.PrettyPrinter().pprint(data)
This example shows calling the required apis to attach files to a case/SR.

#!/usr/bin/python3

from datetime import datetime, timezone
import json
import requests
import base64
import pprint
import time
import random
import urllib.parse
import string

# define a call_api routine - prepares headers (authentication based on OpenID connect), post message to api url, print response
def call_api(api_path, payload):
    api_headers = {
        "Authorization": f"Bearer {oidc_id_token}",
        "Content-Type": "application/json",
        "Accept": "application/json",
    }

    response_data = requests.post(
        f"{base_url}/{api_path}/",
        headers=api_headers,
        json=payload,
        timeout=180,
    )

    print(response_data)
    response = json.loads(bytes.decode(response_data.content))
    pprint.PrettyPrinter().pprint(response)
    return response

# routine to use for requestDateTime key. current time in utc is returned
def isoformat_time_now():
    time_str = datetime.now(timezone.utc).isoformat(timespec='milliseconds')
    return time_str.replace('+00:00', 'Z')

# routine to use for generating an unique id for customerUniqueTransactionID key.
def get_unique_id():
    return ''.join(random.choices(string.ascii_uppercase + string.digits + string.ascii_lowercase, k=40))    

# routine to use for generating an unique file name for each file being uploaded to S3.
def get_unique_filename():
  return datetime.today().strftime('%Y%m%d%H%M%S%f')[:-3]+str(random.randint(0,1000))+str(1000)    

# SETUP DATA

base_url = "https://devapigateway.sndbx.junipercloud.net:443/css/sr/pp/v01"
gettoken_api_path = "getfileuploadtoken"
attachfile_api_path = "attachfile"

# This example is with OpenID connect authentication

oidc_id_token = "WQiOiJzMTBZa0hZNnRhVHgtWFNidWttV2ZkZW5Hb2x1Q2NlVkI3VWU1Z2JoTm5rIiwiYWxnIjoiUlMyNTYifQ.WIiOiIwMHVtYm84OHprZEJRVmxKTjBoNyIsIm5hbWUiOiJWZW5rYXQgQmVsbGFta29uZGEiLCJsb2NhbGUiOiJlbi1VUyIsInZlciI6MSwiaXNzIjoiaHR0cHM6Ly9qdW5pcGVyLXBvYy5va3RhcHJldmlldy5jb20vb2F1dGgyL2RlZmF1bHQiLCJhdWQiOiIwb2FmdHBqYXRrRmc5a3VuazBoNyIsImlhdCI6MTU3NDc4ODY5MSwiZXhwIjoxNTc0NzkyMjkxLCJqdGkiOiJJRC5VbFlibmVRVkxhekVpS0pXS2QwLUlERm96TV9sTGVoYzIwY1JFd2VGRUVBIiwiYW1yIjpbInB3ZCJdLCJpZHAiOiIwMG9mdGUxYXFjY1JrUTZmTTBoNyIsIm5vbmNlIjoicHNtZ1lWeFB6MlRIbUFmSTZlN0F5Q1NQc3o5TWtHaHciLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJ2ZW5rYXRiQGp1bmlwZXIubmV0IiwiZ2l2ZW5fbmFtZSI6IlZlbmthdCIsImZhbWlseV9uYW1lIjoiQmVsbGFta29uZGEiLCJ6b25laW5mbyI6IkFtZXJpY2EvTG9zX0FuZ2VsZXMiLCJ1cGRhdGVkX2F0IjoxNTY0NjE1MzUxLCJhdXRoX3RpbWUiOjE1NzQ3ODg2OTB9.yq_Udq_h4JcEbSJJI9uRJD6PtESsnj9qAzd8R0D4nNechWUAeiCThGJCFGn--MSRM-fhek8IY9RrXltUiRqDBTthTxKQHWt-JIp4zGNBVep0IGVE64SjK8dvD84-M1D3n-ZPWKusvQGtqpJPbeQoSeNrJulA-tdWZLS6Q3ke_0uUiuK7iWHnHX2m_VqKz0sga_uQmYCMTI_FBsqTfFrpSwoZCCXSE4sB-m3lLGy4Ho8PZEmYqlB6fxGnzui08cuNhjgsJKPMyohXJ2hwQQwBYxfSGRXa7g-adPSGoBbvDqYiDS0ijCwzRRxS_k2vr-I5vVTAtNjewozIFV0Um4-Tdg"

# For this example, various keys used in the request apis
appId = "cCMUrMyyJUcOWxNBkmwDX11GU2nY2mlF3i15hIE5"
userId = "johnsmith@pristineparts.com"
customerSourceID = "pristineparts-partner"
accountID = "101412170",
contactEmail = "frank@pristineparts.com"
customerCaseNumber = "PP2000"
serviceRequestNumber = "2019-0722-T-0004"

# prepare request body for obtaining stsToken

token_request_body = {
  "fileUploadTokenRequest": {
    "appId": appId,
    "userId": userId,
    "requestDateTime": isoformat_time_now(),
    "caseInformation": {
      "customerCaseNumber": customerCaseNumber,
      "serviceRequestNumber": serviceRequestNumber,
      "customerSourceID": customerSourceID,
      "customerUniqueTransactionID": get_unique_id()
    },
    "contact" : {
      "accountID" : accountID,
      "contactEmail" : contactEmail

    },
  }
}

# STEP 1 - Get AWS S3 STSToken from Juniper using getfileuploadtoken API request

gettokenresponseInfo = call_api(gettoken_api_path, token_request_body)
stsToken = gettokenresponseInfo['fileUploadTokenResponse']['stsToken']

# STEP 2 - Upload File to AWS using AWS S3 SDK.

import boto3
from botocore.config import Config

boto3.set_stream_logger('')

s3 = boto3.resource(
    's3',
    config=Config(),
    region_name=stsToken['region'],
    aws_access_key_id=stsToken['accessKey'],
    aws_secret_access_key=stsToken['secret'],
    aws_session_token=stsToken['sessionToken'],
)

# The below step reads file from local path mentioned and uploads it to S3 using information from stsToken. Note the randamization of the filename (stsToken['path']+get_unique_filename()) to the path to permit multiple files with same name to be uploaded to S3.

uploadResponse = s3.meta.client.upload_file(
    'path to local file', stsToken['bucketName'], stsToken['path']+get_unique_filename(), ExtraArgs={"Metadata": {"uploadedby":"SR-API","original-file-name":urllib.parse.quote("filename")}}
)
print(uploadResponse)


# STEP 3 - Call Juniper attachFile API to link the files uploaded to the case/SR. In this example three files were uploaded with the stsToken obtained.

# prepare attachFile request body
attachfile_request_body {
  "attachFileDetailsRequest" : {
    "appId": appId,
    "userId": userId,
    "requestDateTime": isoformat_time_now(),
    "caseInformation": {
      "customerCaseNumber": customerCaseNumber,
      "serviceRequestNumber": serviceRequestNumber,
      "customerSourceID": customerSourceID,
      "customerUniqueTransactionID": get_unique_id()
    },
    "contact" : {
      "accountID" : accountID,
      "contactEmail" : contactEmail
    },
    "attachment" : [ {
      "title" : "mx960rsi.txt",
      "type" : "RSI",
      "sizeInBytes" : "100",
      "documentPath" : "archive/attachments/OETCLR/2019/07/22/T/0004/201908141630450101456",
      "uploadedDateTime" : "2019-08-14T16:30:45.010Z"
    },
    {
      "title" : "Log messages mx 960 router",
      "type" : "LOG",
      "sizeInBytes" : "10000",
      "documentPath" : "archive/attachments/OETCLR/2019/07/22/T/0004/201908141630500002645",
      "uploadedDateTime" : "2019-08-14T16:30:50.000Z"
    },
    {
      "title" : "networktopology.txt",
      "type" : "DOCUMENT",
      "sizeInBytes" : "300",
      "documentPath" : "archive/attachments/OETCLR/2019/07/22/T/0004/201908141631103003546",
      "uploadedDateTime" : "2019-08-14T16:31:10.300Z"
    } ]
  }
}

# call attachFile api

call_api(attachfile_api_path, attachfile_request_body)