BookmarkSubscribeRSS Feed
agno3
Calcite | Level 5

Hello,

 

My mission(I've chosen to accept it) is to upload a zip file (bundled up XPT files in there) to an API. I'm using the code below. The issue(s) I've run into are 

1) Is the code complete/correct  from the MULTI PART aspect ? The client is expecting a "multipart/form-data" type of upload. 

2)  Do I need the boundary to be defined, considering there are multiple xpt files in the zip file ? Currently commented out. If needed, where does it go ?

 

Some notes:

1) There is no "data size" limiting this operation.

2) Yes, the macro variables resolve correctly. Can't share that sensitive information here.

 

Thanks in advance.

AgNO3.

@ChrisHemedinger 

 


options nobomfile; filename dd_raw "../dataraw/dd_raw.zip"; /*%let boundary=%sysfunc(uuidgen());*/ proc http url = "&base_uri/repository/container/&containerAID/&version/assetgroup/&agaid/upload" method='post' in=multi (dd_raw header = "content-type: multipart/form-data", "xpt data"); debug level=3; headers 'Authorization'="Bearer &ACCESS_TOKEN"; run;

proc_http_log.PNG

3 REPLIES 3
ChrisHemedinger
Community Manager

@agno3 ,

 

I would first try without any special options, using just POST with the ZIP file as the IN= payload. If that doesn't do the trick, see the MULTI option on PROC HTTP (documentation). Your example doesn't look like valid syntax to me.

 

Or, See if the example here helps with the task. This workaround was the trick to use before there was a MULTI option, I think.

 

 

SAS Innovate 2025: Call for Content! Submit your proposals before Sept 16. Accepted presenters get amazing perks to attend the conference!
agno3
Calcite | Level 5

Thanks for your reply. 

 

Unfortunately, neither avenues have gotten me the intended result.

As for the example you pointed out to.  the PROC ends in a "Bad Request". Below is my entire code, and the log snippet. Please see the "error:"invalid_files " message. FYI - I've tried this with 4 different files - XPT,XLSX,SAS7BDAT and a ZIP file. All of them yield the same error message. And yes, these files do have ample data in them. log_snip.PNG

 

%let boundary=%sysfunc(uuidgen()); 
filename input1 "../dataraw/f_ae_003.xpt";

%let updestfile = f_ae_003;

data _null_;
    infile request end=eof;
    file input1;

      if _n_ = 1 then do;
        put "--&boundary"; 
        put 'Content-Disposition: form-data; name="attributes"';
        put ;
        put '{"name":"' "&updestfile" '", "parent":{"id":"' "folderID" '"}}';
        put "--&boundary"; 
        put 'Content-Disposition: form-data; name="file"; filename="' "&updestfile" '"';

        put "Content-Type: application/ASCII";
/*        put "Content-Type: application/octet-stream";*/
        put ;
      end;

    input;
    put _infile_;

    if eof then
     do;
       put "--&boundary--"; 
     end;
  run;

  data _null_;
    file input1 mod recfm=f lrecl=1;
    infile request  recfm=f lrecl=1;
    
    input;
    put _infile_;
run;


  *---------------------------------------------------------------------------------------;
  *>> Determine size of request and store in macro variable  *****************************;
  *---------------------------------------------------------------------------------------;
  data _null_;
    length bytes $1024;
    fid = fopen("input1");
    rc = fread(fid);
    bytes = finfo(fid, 'File Size (bytes)');
    call symput("FileSize",trim(bytes));
    rc = fclose(fid);
    put bytes;
  run;

  *---------------------------------------------------------------------------------------;
  *>> Submit the Upload request to Box  **************************************************;
  *---------------------------------------------------------------------------------------;
  proc http
      url=  "&base_uri/repository/container/&containerAID/&version/assetgroup/&agaid/upload"
        method    = "POST"
        out       = resp
        headerout = headout
        in        = input1
        ct        = "multipart/form-data; boundary=&boundary"
    ;
    headers
      "Authorization"  = "Bearer &ACCESS_TOKEN"
      "Content-Length" = "&filesize"
    ;
	debug level=3;

  run;

As for the SAS documentation link, something seems off (atleast to me) as word POST is not wrapped in quotes. And even when I add quotes, it doesnt "finish" running...

 

documentation_example_log.PNG

 

Help here will be abundantly appreciated.

thanks.

ChrisHemedinger
Community Manager

I usually start with the API documentation, which often has examples that use cURL or another language. From there it's simple to transcribe to the equivalent in SAS PROC HTTP. Is there doc for the API? I understand your data is sensitive, but is the system you're using a well-known service?

SAS Innovate 2025: Call for Content! Submit your proposals before Sept 16. Accepted presenters get amazing perks to attend the conference!

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
What is Bayesian Analysis?

Learn the difference between classical and Bayesian statistical approaches and see a few PROC examples to perform Bayesian analysis in this video.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 3 replies
  • 945 views
  • 0 likes
  • 2 in conversation