SASPy (SAS Python Interface)
SASPy is an open-source Python package that provides an interface to the SAS System, allowing Python programmers to leverage their licensed SAS infrastructure. It enables bi-directional data exchange between pandas DataFrames and SAS datasets, submission of SAS code, and access to SAS analytical capabilities like machine learning and econometrics. Currently at version 5.105.1, the library maintains an active release cadence with frequent updates addressing new features, enhancements, and bug fixes.
Common errors
-
SAS Connection failed. No connection established. Double check your settings in sascfg_personal.py file.
cause This is a general connection error, often due to incorrect or missing `sascfg_personal.py` configuration, unreachable SAS server, or issues with Java (for IOM) or SSH (for STDIO over SSH) settings.fixVerify the `sascfg_personal.py` file exists and has correct connection parameters for your SAS environment. Ensure SAS is running and accessible from the Python client. For IOM, check Java installation and classpath. For SSH, verify SSH credentials and host reachability. Run the connection command manually (provided in the error message for some access methods) for more detailed diagnostics. -
RuntimeError: ERROR 180-322: Statement is not valid or it is used out of proper order.
cause Often occurs when SAS-specific options (like `dsopts`) are expected by a SASPy method but not provided, or when a SAS statement is syntactically incorrect or out of context for the SAS session.fixReview the specific SASPy method call (e.g., `sasdata.sort()`) and its documentation. Ensure all required parameters and SAS dataset options are correctly passed. If using `submit()`, carefully check the SAS code for syntax errors or misplaced statements. -
StdinNotImplementedError: raw_input was called, but this frontend does not support input requests.
cause SASPy attempts to prompt for authentication credentials (e.g., username/password) in a non-interactive Python environment (like a script or some Jupyter setups) that cannot handle user input.fixProvide credentials using an `.authinfo` file (recommended for non-interactive environments) or by setting them in your `sascfg_personal.py` configuration, rather than relying on interactive prompts. Ensure the `.authinfo` file has appropriate permissions (e.g., 600 for SSH). -
We failed in getConnection An exception was thrown during the encryption key exchange.
cause This error is specific to IOM connections, particularly with SAS OnDemand for Academics (ODA) running SAS 9.4M7+, and indicates missing or outdated Java encryption JAR files required for the connection.fixEnsure that the necessary encryption JAR files are present in your SASPy Java deployment. Refer to the SASPy configuration documentation (sassoftware.github.io/saspy/configuration.html) for specific instructions on obtaining and placing these JARs for your SAS version and access method.
Warnings
- breaking With Pandas 3.0.0, a change was made to store `None` as `NaN`, which caused `dataframe2sasdata` to throw exceptions. This was fixed in SASPy v5.104.1.
- gotcha SASPy relies on `sascfg_personal.py` for connection configurations. If you modify the original `sascfg.py` instead of creating `sascfg_personal.py`, your configurations might be overwritten during a SASPy upgrade.
- gotcha Using `proc printto` in submitted SAS code to redirect the SAS Log or Listing can cause SASPy to hang, fail, or not return results, as SASPy parses the log for operational information.
- gotcha SAS `ABORT` statements (e.g., `%abort`, `data _null_; abort;`) can unexpectedly terminate the connected SAS session, breaking the SASPy connection and leading to further errors.
Install
-
pip install saspy -
conda install -c conda-forge saspy
Imports
- SASsession
from saspy import SASsession
import saspy sas = saspy.SASsession()
Quickstart
import saspy
import pandas as pd
import os
# NOTE: SASPy requires a configuration file (sascfg_personal.py) to define connection details.
# This file is typically located in your Python site-packages/saspy directory or ~/.config/saspy/.
# For example, using a 'winlocal' configuration (defined in sascfg_personal.py):
# sas = saspy.SASsession(cfgname='winlocal')
# If only one configuration is defined, or if running in an interactive environment that supports prompts:
sas = saspy.SASsession()
print(f"SAS Connection established: {sas.SASsessionid}")
# Example: Submit SAS code and get results
result = sas.submit("proc print data=sashelp.class(obs=5); run;")
print("SAS Log:\n", result['LOG'])
print("SAS Listing:\n", result['LST'])
# Example: Transfer a pandas DataFrame to SAS
data_df = pd.DataFrame({
'col1': [1, 2, 3],
'col2': ['A', 'B', 'C']
})
sas_data_obj = sas.dataframe2sasdata(data_df, 'WORK.mydata')
print(f"DataFrame '{data_df.shape}' transferred to SAS library WORK as 'mydata'.")
# Example: Read SAS data back into a pandas DataFrame
retrieved_df = sas.sasdata('mydata', libref='WORK').to_dataframe()
print(f"Retrieved DataFrame head:\n{retrieved_df.head()}")
sas.endsas()