sassoftware / saspy

A Python interface module to the SAS System. It works with Linux, Windows, and Mainframe SAS as well as with SAS in Viya.
https://sassoftware.github.io/saspy
Other
375 stars 149 forks source link

Submit SAS code directly from Python session #533

Closed kwangccc closed 1 year ago

kwangccc commented 1 year ago

Hi all,

I am new to SASPy and would like some guidance please.

I am trying to write out sas7bdat file from a pandas dataframe using sas.df2sd function. It seems straightforward in other posts and online examples however I am getting an error.

Using Jupyter Notebook, connecting to a remote server:

Code:

sas = saspy.SASsession(cfgname='default')

test dataframe

import seaborn as sns df = sns.load_dataset('iris')

setting library

sas.saslib(libref='dat', path='/sasdata/modeling/_general/ad_hoc_kw/data') df_sas = sas.df2sd(df = df, table = 'iris_test', libref='dat')

Error from Log:

25 ;';";*/; 26
27 data null; retain libref; retain cobs 1; 28 set sashelp.vlibnam end=last; 29 if cobs EQ 1 then 30 put "LIBREFSSTART="; 31 cobs = 2; 32 if libref NE libname then 33 put %upcase("lib=") libname %upcase('libEND='); 34 libref = libname; 35 if last then 36 put "LIBREFSEND="; 37 run; LIBREFSSTART= LIB=DAT LIBEND= LIB=SASHELP LIBEND= LIB=MAPS LIBEND= LIB=MAPSSAS LIBEND= LIB=MAPSGFK LIBEND= LIB=SASUSER LIBEND= LIB=WORK LIBEND= LIBREFSEND= NOTE: There were 60 observations read from the data set SASHELP.VLIBNAM. NOTE: DATA statement used (Total process time): real time 0.00 seconds cpu time 0.00 seconds

38
39
40 ;';";*/;%put %upcase(e3969440a681a2408885998500000005); E3969440A681A2408885998500000005 41 filename sock socket ':44575' recfm=V termstr=LF lrecl=32767; ERROR: Could not load /sas_home/sas_install/SASFoundation/9.4/dbcs/sasexe/sasxbamt (49 images loaded) ERROR: libnsl.so.1: cannot open shared object file: No such file or directory ERROR: Invalid logical name. ERROR: Error in the FILENAME statement. 42 data dat.'iris_test'n; 43 length 'sepal_length'n 8 'sepal_width'n 8 'petal_length'n 8 'petal_width'n 8 'species'n $10; 44 infile sock nbyte=nb delimiter='03'x STOPOVER; 44 infile sock nbyte=nb delimiter='03'x STOPOVER;

             23

ERROR 23-2: Invalid option name NBYTE.

45 input @; 46 if infile = '' then delete; 47 else do; 48 input 'sepal_length'n ; 49 input 'sepal_width'n ; 50 input 'petal_length'n ; 51 input 'petal_width'n ; 52 input 'species'n ; 53 'species'n = translate('species'n, '0A'x, '01'x); 54 'species'n = translate('species'n, '0D'x, '02'x ); 55 ; 56 end; 57 run; NOTE: The SAS System stopped processing this step because of errors. WARNING: The data set DAT.IRIS_TEST may be incomplete. When this step was stopped there were 0 observations and 5 variables. WARNING: Data set DAT.IRIS_TEST was not replaced because this step was stopped. NOTE: DATA statement used (Total process time): real time 0.00 seconds cpu time 0.00 seconds

58 filename sock; WARNING: No logical assign for filename SOCK. 59
60 ;';";/; 61
62
63 ;
';";/;%put %upcase(e3969440a681a2408885998500000006); E3969440A681A2408885998500000006

tomweber-sas commented 1 year ago

Hey, I can help, but I can't just guess at what you're doing. Can you show me the code you ran and all of the output it produced? Also submit your SASsession object so I can see the useful info it produces:

import saspy
sas = saspy.SASsession()
sas

Oh, you just added some of it. So submit your SASsession object so I can see what version of SAS you're connected to. Thanks, Tom

kwangccc commented 1 year ago

Hi Tom, thanks for getting back so quickly, below is my output:

Access Method = STDIO SAS Config name = default SAS Config file = /usr/local/anaconda3/lib/python3.9/site-packages/saspy/sascfg.py WORK Path = SAS Version = 9.04.01M7P08062020 SASPy Version = 4.7.0 Teach me SAS = False Batch = False Results = Pandas SAS Session Encoding = utf-8 Python Encoding value = utf_8 SAS process Pid value = 2321615

tomweber-sas commented 1 year ago

The SAS error has to do with not being able to load the Socket Access method for the filename statement. That's a base part of SAS. I'm not sure why you would be getting that error. What kind of SAS deployment are you connecting to? Ah, that helps, so this is a stand alone linux deployment of SAS 9.4M7? And you're running python on that same linux box it seams.

The SAS error is:

41 filename sock socket ':44575' recfm=V termstr=LF lrecl=32767;
ERROR: Could not load /sas_home/sas_install/SASFoundation/9.4/dbcs/sasexe/sasxbamt (49 images loaded)
ERROR: libnsl.so.1: cannot open shared object file: No such file or directory
ERROR: Invalid logical name.
ERROR: Error in the FILENAME statement.

But I'm not sure why you would get that errror. Can you just run SAS and submit that filename statement w/out it getting that error?

kwangccc commented 1 year ago

Apologies for the lack of knowledge here, what do you mean by SAS deployment? Also, how would I run it w/out getting that error?

tomweber-sas commented 1 year ago

Can you show me your configuration? I'm curious what you have for the saspath value. The path in the error has dbcs in it, which make me wonder what specific configuration of SAS you're starting up. Is it really a DBCS version as opposed to just a uft-8 version (as far as encoding, locale, ...)

Well, your on that linux box where SAS is installed, right? Show me your config and I'll know a little better.

kwangccc commented 1 year ago

from this code

saspy <module 'saspy' from '/usr/local/anaconda3/lib/python3.9/site-packages/saspy/init.py'>

saspy.SAScfg

'/usr/local/anaconda3/lib/python3.9/site-packages/saspy/sascfg.py'

I suspect an installation/configuration error? (our IT team performs the installation)

tomweber-sas commented 1 year ago

yes, show me '/usr/local/anaconda3/lib/python3.9/site-packages/saspy/sascfg.py'

kwangccc commented 1 year ago

SAS_config_names = ['default', 'ssh', 'iomlinux', 'iomwin', 'winlocal', 'winiomlinux', 'winiomwin', 'httpsviya', 'httpviya', 'iomcom'] `

SAS_config_options = {'lock_down': False, 'verbose' : True, 'prompt' : True }

SAS_output_options = {'output' : 'html5',
'style' : 'HTMLBlue'}

default = {'saspath' : '/sas_home/sas_install/SASFoundation/9.4/bin/sas_u8' }

ssh = {'saspath' : '/sas_home/sas_install/SASFoundation/9.4/bin/sas_en', 'ssh' : '/usr/bin/ssh', 'host' : '10.6.0.146', 'encoding': 'latin1', 'options' : ["-fullstimer"] }

iomlinux = {'java' : '/usr/bin/java', 'iomhost' : 'linux.iom.host', 'iomport' : 8591, }

iomwin = {'java' : '/usr/bin/java', 'iomhost' : 'windows.iom.host', 'iomport' : 8591, }

winlocal = {'java' : 'java', 'encoding' : 'windows-1252', }

winiomlinux = {'java' : 'java', 'iomhost' : 'linux.iom.host', 'iomport' : 8591, }

winiomwin = {'java' : 'java', 'iomhost' : 'windows.iom.host', 'iomport' : 8591, }

winiomIWA = {'java' : 'java', 'iomhost' : 'windows.iom.host', 'iomport' : 8591, 'sspi' : True }

iomcom = { 'iomhost' : 'mynode.mycompany.org', 'iomport' : 8591, 'provider': 'sas.iomprovider', 'encoding': 'windows-1252'}

httpsviya = {'url' : 'https://viya.deployment.com', 'context' : 'Data Mining compute context', 'authkey' : 'viya_user-pw', 'options' : ["fullstimer", "memsize=1G"] }

httpviya = {'url' : 'https://sastpw.rndk8s.openstack.sas.com:23456',

'port' : 23456, # can put different port here or ^ is it's not using the default port

        'context' : 'Data Mining compute context',
        'authkey' : 'viya_user-pw',
        'options' : ["fullstimer", "memsize=1G"]
        }
tomweber-sas commented 1 year ago

ok, so it seems they configured a number of configurations in there. They should have created a file named sascfg_personal.py in that same directory. The changes to sascfg.py will be overwritten if you update the deployment (if it contains any changes to that file). But, at the moment, it shows the saspath of /sas_home/sas_install/SASFoundation/9.4/bin/sas_u8. Which seems reasonable, but that configuration of SAS seems to be looking for the Socket Access method in the DBCS file structure, and not finding it (I have no idea if that's right or wrong just yet).

So, let's just try something. Can you copy that sascfg.py file to sascfg_personal.py in the same directory it's in? That will save pain if sascfg.py get's overwritten some day.

Then, just to see what happens. change the path in your sascfg_personal.py from default = {'saspath' : '/sas_home/sas_install/SASFoundation/9.4/bin/sas_u8'} to default = {'saspath' : '/sas_home/sas_install/SASFoundation/9.4/bin/sas_en'}

And then try to connect and run your code and lets just see what happens.

kwangccc commented 1 year ago

I will forward this and rerun, will update here after. Thank you so much!

tomweber-sas commented 1 year ago

Ok, I've tried to see what I find on a linux deployment here for the sas_u8 configuration, to see if that access method is there or what. It is found and it's in the dbcs directory, so that seems ok. The error from your system shows

OHHHHH, wait, I've seen this problem, I know what it is. I expect your configuration's fine and that this should work. I needed to look at the error closer.

Here's the error:

ERROR: Could not load /sas_home/sas_install/SASFoundation/9.4/dbcs/sasexe/sasxbamt (49 images loaded)
ERROR: libnsl.so.1: cannot open shared object file: No such file or directory

So, it's not that it can't find the file, it can't load it because there's an OS library dependency that can't be found: libnsl.so.1

So, issue the following command at a linux prompt on that machine. Oh, are you on that machine, or are you just in a web browser in Jupyter that's hosted for you from that machine?

So, have your IT go to that machine, and issue ldd /sas_home/sas_install/SASFoundation/9.4/dbcs/sasexe/sasxbamt

and it will look something like this:

        linux-vdso.so.1 (0x00007ffe86f84000)
        libnsl.so.1 => /lib64/libnsl.so.1 (0x00007f1c052a0000)
        libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f1c05080000)
        libcrypt.so.1 => /lib64/libcrypt.so.1 (0x00007f1c04e57000)
        libdl.so.2 => /lib64/libdl.so.2 (0x00007f1c04c53000)
        libm.so.6 => /lib64/libm.so.6 (0x00007f1c048d1000)
        libc.so.6 => /lib64/libc.so.6 (0x00007f1c0450c000)
        libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f1c04177000)
        libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f1c03f5f000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f1c056f5000)

except that for libnsl.so.1 => it will say Not Found or something like that (I forget exactly, but it won't have a path to it. So, for you to use the default config, using utf-8 and be able to use saspy right (sd2df, df2sd, probably others), they will need to install that version of libnsl.so on the system so that the sasxbamt (Socket Access method) can load and SAS will work right.

That is the problem, Tom

tomweber-sas commented 1 year ago

This is a SAS installation OS requirement, that may or may not be documented anywhere that they would have known about. But, that's the requirement for sasxbamt that was built for SAS9.4M7, as far as OS library requirements on the machine you install SAS on.

kwangccc commented 1 year ago

Tom, thank you so much! I will let them know the issue.

tomweber-sas commented 1 year ago

Cool, just let me know when you can try it out again. I'll keep this open till we find out! Hopefully there aren't others like this, but we'll see.

kwangccc commented 1 year ago

Hi Tom, our IT team installed the appropriate requirements, and SASPy is functioning. Thanks again for your help!

tomweber-sas commented 1 year ago

That's great! Glad they got that done quickly for you. I'll go ahead and close this out then. Let me know if you need anything else! Thanks, Tom