BookmarkSubscribeRSS Feed

Viya Jobs returning temporary and dynamically generated images

Started a week ago by
Modified a week ago by
Views 161

In one of the many customer iterations I had recently, I was asked to help develop a solution to allow an image that was dynamically created by a third-party library/API to be embedded in a SAS Visual Analytics (VA) report. In addition to some input parameters passed to that external API that are irrelevant to our discussion, there was one in special that contained the full path and name of the output image to be generated. Although it seems a simple task, it doesn’t take too long to realize some of the challenges:

 

  1. If the output image is stored with a fixed path and name, it doesn’t work well in VA reports with concurrent users:
    • Image file names and/or locations must be unique and dynamically generated to allow concurrency, so different users don’t overwrite each other.
  2. If you generate random distinct names for each request, after the solution has been running for a while, you may have many image files stored somewhere:
    • You must have a mechanism that manages the number of images stored, so it doesn’t grow forever.
  3. The client application consuming the images runs on a browser, so we must be able to stream the images or reference them by a URL or URI:
    • The third-party API doesn’t accept URL or URI as parameters, so you must perform a conversion of some sort.

 

I’ve decided to use SAS code as a Viya Job to be able to deal with the constraints above. With the SAS code I’d be able to:

 

  1. Leverage temporary files via filename statements to generate the image names – those file names are unique, and files get automatically deleted when the SAS session ends, helping with challenges 1 and 2.
  2. Leverage Viya Content Server to temporarily store the image files – files stored in the Content Server can be referenced by a URI and are automatically deleted after some time, helping with challenges 2 and 3.

 

I only needed to find a way to transfer the image generated by the external API to the Viya Content Server, and it only took me one Google search for “sas copy binary files” to find the solution I was looking for in the first hit, a blog by Chris Hemedinger, more precisely the portion that uses the FCOPY function from SAS:

 

https://blogs.sas.com/content/sasdummy/2013/09/17/copy-file-macro/

 

This is the SAS code with the key elements:

* Close all ODS output;
ods _all_ close;

* Set the temporary file location;
filename _bcin TEMP recfm=n; * RECFM=N means that the input is read as a stream (there are no records);

* Obtain the temporary /path/file value;
%let tmpfile=%qsysfunc(pathname(_bcin));

* Here you would add the code to call the external API passing &tmpfile as parameter;

* Fileref _webout with name _webout.html is automatically assigned in Viya Jobs;
* If fileref with name _webout.* has an extension that the browser knows how to visualize, such as html, jpg, etc. it will display it;
* The pre-assigned fileref _webout is not needed, so we must delete it first;
%let RC=%sysfunc(fdelete(_webout)); 

* Set content server file location;
* We need a fileref with the image's extension (so the browser can display it) and add recfm=n;
* The fileref could be called anything you want;
filename _webout filesrvc parenturi="&SYS_JES_JOB_URI" name="_webout.jpg" recfm=n;

* Copy API output to Content Server;
data _null_;
   length msg $ 384;
   rc=fcopy('_bcin', '_webout');
   if rc=0 then
      put 'NOTE: Copied _bcin to _webout.';
   else do;
      msg=sysmsg();
      put 'ERROR:' rc= msg=;
   end;
run;

The code starts with closing all ODS outputs because we know we will be returning an image produced by an external API, so no ODS output is needed. Then we set the temporary file name and location using a TEMP fileref called _bcin and store its value in a macro variable. That macro variable is passed to the external API as the full path and name of the output image to be created. Next, we delete the existing fileref _webout. This fileref is automatically created for you in Viya Jobs with attribute name=_webout.html. All content of filerefs with name=_webout.* are automatically streamed back to the calling application, but we need a fileref that is slightly different. We need a fileref with RECFM=N, to indicate the file consists of a stream of bytes in binary format with no record boundaries, which is going to be necessary later when using the function FCOPY to copy the image generated by the API to the Content Server, and we want its name=_webout.jpg, so the browser knows it’s an image and therefore knows how to display it. The fileref itself does not need to be called _webout. The final data step copies the output image to Viya Content Server leveraging both filerefs. For the cleanup, the temporary file given by the TEMP fileref will be automatically disposed when the job finishes, and its copy in the _webout fileref will also be automatically deleted after some time.

 

If for some reason you want the name attribute of the fileref to be something other than _webout.*, or send back multiple files to the calling application, then you can call the Viya Job with _action=json. This makes the job return a list of output files in a json structure and the calling application has the freedom to decide what to do with each output file. This is explored in this other SAS Communities publication called Viya Jobs that Create Multiple Output Files.

 

In my final implementation, the code returned a couple of files (the output image and a small json file with information about the code execution status), simply because this is the template I’m currently leveraging for the Viya Jobs I develop. It also makes it simple to integrate the job with VA via DDC (Data-Driven Content), which is what I had to do for that customer. Indeed, I used that framework to provide a solution where the chart was being created in Python, using SAS PROC PYTHON, after receiving input parameters from VA, but this will be the topic for another blog.

Contributors
Version history
Last update:
a week ago
Updated by:

sas-innovate-2026-white.png



April 27 – 30 | Gaylord Texan | Grapevine, Texas

Registration is open

Walk in ready to learn. Walk out ready to deliver. This is the data and AI conference you can't afford to miss.
Register now and lock in 2025 pricing—just $495!

Register now

SAS AI and Machine Learning Courses

The rapid growth of AI technologies is driving an AI skills gap and demand for AI talent. Ready to grow your AI literacy? SAS offers free ways to get started for beginners, business leaders, and analytics professionals of all skill levels. Your future self will thank you.

Get started

Article Tags