BookmarkSubscribeRSS Feed
TedP
Obsidian | Level 7

I've seemingly read through all the threads and documentation with no avail.

 

I'd like to send a csv from one non-SAS server to a SAS server through a stored process which will return some output. This appears to be trivial to do when using non-file parameters, but impossible when using a csv.

 

For instance, assuming a python non-SAS backend, using the requests library I logon and then call the testprint_sp stored process.

base_url = "https://mybaseurl"
login_url = base_url + "/SASLogon/login"
s = requests.Session()
r = s.get(login_url, verify=False)

data = {"username": "uname", "password":"pwd123"}
r = s.post(login_url, data=data)

execute_url = base_url + "/SASStoredProcess/do?_program=/User Folders/my folder/testprint_sp"
data = {'num':20}
r = s.post(execute_url, data=data)

Or after logging on, simply browsing to 

https://mybaseurl/SASStoredProcess/do?_program=/User Folders/my folder/testprint_sp&num=20

This is great but it fails when I try to send a csv.

filename = "D:/Documents/testfile.csv"
files = {'file': ('myfile', open(filename, 'rb'))}
r = s.post(execute_url, data=data, files=files)

 All of the _WEBIN_% macro variables are missing. 

 

Now, there is a workaround which is to build an html form within a sas stored process.

<form action="StoredProcessWebApplicationURL" method="post"
 enctype="multipart/form-data">
<input type="hidden" name="_program" value="/Path/StoredProcessName">
<table border="0" cellpadding="5">
 <tr>
 <th>Choose a file to upload:</th>
 <td><input type="file" name="myfile"></td>
 </tr>
 <tr>
 <td colspan="2" align="center"><input type="submit" value="OK"></td>
 </tr>
</table>

But this adds the extra step of having a client using the form and browsing to a specific file. I'd like the data to be automatically sent to SAS without having an html form built in a SAS procedure.

 

Any help is greatly appreciated.

1 REPLY 1
boemskats
Lapis Lazuli | Level 10

Ted,

 

Are you sure you're setting the headers properly in your POST request from Python? The Content Type needs to be set to multipart/form-data.

http://stackoverflow.com/questions/68477/send-file-using-post-from-a-python-script

has an example where the header is set correctly in Python. It also suggests the 'poster' library which seems pretty nifty, rather than doing it all manually.

 

If you submit a form with an upload component from the browser, as per the STP form with input type "file", I think the browser automatically sets the header of Content-type: multipart/form-data. This is how SAS will know that you're uploading a file as part of the post request. Otherwise, the default content type in the header for a POST is set to application/x-www-form-encoded (I think).

 

As per top answer from http://stackoverflow.com/questions/4526273/what-does-enctype-multipart-form-data-mean:

 

When you make a POST request, you have to encode the data that forms the body of the request in some way.

HTML forms provide three methods of encoding.

  • application/x-www-form-urlencoded (the default)
  • multipart/form-data
  • text/plain

Work was being done on adding application/json, but that has been abandoned.

The specifics of the formats don't matter to most developers. The important points are:

When you are writing client-side code, all you need to know is use multipart/form-data when your form includes any <input type="file"> elements.

When you are writing server-side code: Use a prewritten form handling library (e.g. Perl's CGI->param or the one exposed by PHP's $_POST superglobal) and it will take care of the differences for you. Don't bother trying to parse the raw input received by the server.

Never use text/plain.

 

 

Hope this helps.

 

Nik

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

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
  • 1 reply
  • 2058 views
  • 0 likes
  • 2 in conversation