
Image created with DALL·E
|
Piet Mondrian's artwork.
I have recently attended HILMA AF KLINT & PIET MONDRIAN
Still, I wanted a Piet Mondrian's mug. However, my kitchen cupboard has no more overflow space...
I had to get creative.... |
Disclaimer:
- The ideas presented in this blog are personal insights thus are not necessarily endorsed by SAP.
- Images/data in this blog post is from personal SAP BTP Free Tier and/or OpenAI accounts. Any resemblance to real data is purely coincidental.
- Access to some online resources referenced in this blog may be subject to a contractual relationship with either SAP and/or OpenAI.
Putting it all together
Here goes the agenda for this brief.
Image generation with DALL·E API.
With
DALL·E API it is possible to integrate state of the art image generation capabilities directly into apps and products...with little or no code.
A wish come true. SAP BTP, Kyma runtime serverless to the rescue...
With a few lines of code my wish of owning a digital mug has eventually come true.
const { Configuration, OpenAIApi } = require("openai");
const configuration = new Configuration({
apiKey: process.env.OPENAI_API_KEY,
});
const openai = new OpenAIApi(configuration);
async function PietMondrianMug() {
try
{
const response = await openai.createImage({
prompt: "create Piet Mondrian mug",
n: 4, //1,
size: "1024x1024",
});
const data = response.data;
console.log(data);
return JSON.stringify(data,0,2);
}
catch (err) {
console.log(err.message);
return JSON.stringify(err, 0, 2);
}
}
module.exports = {
main: async function (event) {
switch(event.extensions.request.url) {
case '/mug':
return PietMondrianMug();
}
return "no mug today";
}
}
Here goes the
serverless payload with 4 mug images:
{
"created": *********,
"data": [
{
"url": "https://***.blob.***/private/org-*****"
},
################# truncated payload ############################
]
}
No code today. DALL·E API with SAP API Management
In my quest for simplicity, I personally find
SAP API Management, part of
SAP BTP platform, one of the best low code/no code API
middlewares ever.
It allows to create API proxies with built-in
security and
CORS policies and even have HTTP
streaming to cope with the large payloads. With little or no code at all.
SAP APIM can be used to create an API proxy, as follows:
OpenAPI proxy resources |
Security policy |
 |
 |
The API Keys are stored in a
kvm ( key value map), as depicted below:
<!-- Key/value pairs can be stored, retrieved, and deleted from named existing maps by configuring this policy by specifying PUT, GET, or DELETE operations -->
<!-- https://help.sap.com/viewer/66d066d903c2473f81ec33acfe2ccdb4/Cloud/en-US/b72dc3f262c1441587e76d0e808... -->
<!-- mapIdentifier refers to the name of the key value map -->
<KeyValueMapOperations mapIdentifier="openapi" async="true" continueOnError="false" enabled="true" xmlns="http://www.sap.com/apimgmt">
<Get assignTo="sapapim.apiKey" index="1">
<Key><Parameter>api_key</Parameter></Key>
</Get>
<!-- the scope of the key value map. Valid values are environment, organization, apiproxy and policy -->
<Scope>environment</Scope>
</KeyValueMapOperations>
Good to know:
- kvm values can be encrypted
CORS policy settings
handler options |
cors settings |
 |
 |
Streaming settings. Configure an API proxy to enable HTTP request and response streaming.
Configure an API proxy to enable HTTP request and response streaming. | SAP Help
Good to know:
Piet Mondrian's mug with SAP Appgyver / SAP Build Apps
Data source logic:
 |
 |
Set Custom Request Body schema |
Test Create Record |
 |
  |
Page logic:
Record properties: custom schema object |
Create record: openai_models data source |
 |
 |
JS inputs |
JS custom object |
 |
 |
Page variable definition |
Page variable assignment |
 |
 |
Eventually, we can use the appgyver platform web preview and inspect the behaviour of the
java script custom code, as follows:

Quovadis ?
Time to reflect on the accomplished achievement.
That's how I took
le taureau par les cornes by combining the power of simplicity of the modern generative AI models with the power of integration of
SAP BTP platform with its enterprise-grade runtimes (
kyma) and application building services (
SAP API Management and
SAP Build Apps).
Just wondering what your
wish come true may be? So let me ask again,
quovadis ? Your feedback is welcome...
SAP Kyma Community and
SAP BTP, Kyma runtime Q&A Tags
Be
balsamiq; You can follow me in SAP Community:
piotr.tesny
Appendix.
SAP Build Apps JS custom code
var data = inputs.input1;
console.log(data);
const b64_json = data.data[0].b64_json;
try
{
const bytes = myBase64.atob(b64_json)
.split('')
.map(c => c.charCodeAt(0));
console.log('bytes: ', bytes.length)
const blob = new Blob([ new Uint8Array(bytes) ], { type: 'image/jpeg' });
//console.log('blob: ', blob)
const url = (URL || webkitURL).createObjectURL(blob);
console.log(url)
return { result: url };
} catch (err) {
const error = {
code: 'Unknown Error',
message: 'Something went wrong with the blob.',
rawError: err,
}
console.log(error)
return [1, { error }]
}
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
const myBase64 = {
btoa: (input = '') => {
let str = input;
let output = '';
for (let block = 0, charCode, i = 0, map = chars;
str.charAt(i | 0) || (map = '=', i % 1);
output += map.charAt(63 & block >> 8 - i % 1 * 8)) {
charCode = str.charCodeAt(i += 3/4);
if (charCode > 0xFF) {
throw new Error("'btoa' failed: The string to be encoded contains characters outside of the Latin1 range.");
}
block = block << 8 | charCode;
}
return output;
},
atob: (input = '') => {
let str = input.replace(/=+$/, '');
let output = '';
if (str.length % 4 == 1) {
throw new Error("'atob' failed: The string to be decoded is not correctly encoded.");
}
for (let bc = 0, bs = 0, buffer, i = 0;
buffer = str.charAt(i++);
~buffer && (bs = bc % 4 ? bs * 64 + buffer : buffer,
bc++ % 4) ? output += String.fromCharCode(255 & bs >> (-2 * bc & 6)) : 0
) {
buffer = chars.indexOf(buffer);
}
return output;
}
};
Additional resources