Skip to content

Instantly share code, notes, and snippets.

@stephenhillier
Last active November 4, 2020 22:56
Show Gist options
  • Save stephenhillier/6bf95b8331c407886a2952dc264adfdf to your computer and use it in GitHub Desktop.
Save stephenhillier/6bf95b8331c407886a2952dc264adfdf to your computer and use it in GitHub Desktop.
Common Document Generator Python example
""" Functions for interacting with the Common Document Generator (CDOGS) API """
import base64
import requests
import logging
from fastapi import HTTPException
from api import config
logger = logging.getLogger('docgen')
def get_docgen_token():
params = {
"grant_type": "client_credentials",
"client_id": config.COMMON_DOCGEN_CLIENT_ID,
"client_secret": config.COMMON_DOCGEN_CLIENT_SECRET,
"scope": ""
}
req = requests.post(
config.COMMON_DOCGEN_SSO_ENDPOINT,
data=params,
headers={
"Content-Type": "application/x-www-form-urlencoded",
}
)
req.raise_for_status()
token = req.json().get('access_token')
return token
def docgen_export_to_xlsx(data, template_path, report_name):
""" accepts a data dict and a path to an xlsx template
and makes a request to CDOGS.
Returns the response content object that can be added to a
starlette.responses.Response.
"""
# get auth token and prepare it as an Authorization: Bearer <token> header.
token = get_docgen_token()
auth_header = f"Bearer {token}"
# open up the Excel template, and base64 encode it for the docgen endpoint
template_data = open(
template_path, "rb").read()
base64_encoded = base64.b64encode(template_data).decode("UTF-8")
# the docgen endpoint accepts the following schema:
body = {
"data": data,
"options": {
"reportName": report_name,
},
"template": {
"encodingType": "base64",
"content": base64_encoded,
"fileType": "xlsx"
}
}
logger.info('making POST request to common docgen: %s',
config.COMMON_DOCGEN_ENDPOINT)
# put everything together and make the request.
try:
res = requests.post(config.COMMON_DOCGEN_ENDPOINT, json=body, headers={
"Authorization": auth_header, "Content-Type": "application/json"})
res.raise_for_status()
except requests.exceptions.HTTPError as e:
logger.info(e)
raise HTTPException(status_code=e.response.status_code, detail=str(e))
return res.content
export function downloadXlsx (r, defaultFilename) {
let filename = defaultFilename
// default filename, and inspect response header Content-Disposition
// for a more specific filename (if provided).
const filenameData = r.headers['content-disposition'] && r.headers['content-disposition'].split('filename=')
if (filenameData && filenameData.length === 2) {
filename = filenameData[1]
}
let blob = new Blob([r.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' })
let link = document.createElement('a')
link.href = window.URL.createObjectURL(blob)
link.download = filename
document.body.appendChild(link)
link.click()
setTimeout(() => {
document.body.removeChild(link)
window.URL.revokeObjectURL(link.href)
}, 0)
}
axios.post(`/export`, params, {
responseType: 'arraybuffer'
}).then((res) => {
downloadXlsx(res, 'MySpreadsheet.xlsx')
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment