Your SAS programs, embedded in web apps and elsewhere

Upload file to a stored process from python/php/other backend

Posts: 33

Upload file to a stored process from python/php/other backend

[ Edited ]

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 =, data=data)

execute_url = base_url + "/SASStoredProcess/do?_program=/User Folders/my folder/testprint_sp"
data = {'num':20}
r =, 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 =, 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"
<input type="hidden" name="_program" value="/Path/StoredProcessName">
<table border="0" cellpadding="5">
 <th>Choose a file to upload:</th>
 <td><input type="file" name="myfile"></td>
 <td colspan="2" align="center"><input type="submit" value="OK"></td>

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.

Frequent Contributor
Posts: 122

Re: Upload file to a stored process from python/php/other backend



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.

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


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.



Ask a Question
Discussion stats
  • 1 reply
  • 2 in conversation