Skip to content

Releases: sassoftware/saspy

V3.7.4

10 Aug 20:13
Compare
Choose a tag to compare

This release has just two enhancements. The first is to support embedded quotes in SAS variable and table names. SAS supports this via the n-literal syntax (which SASPy has always used in it's code gen). For example: 'other"name'n or "other''name"n. or 'other''name'n
you can't tell here (embeded quotes are a pain everywhere), but some of those are 2 single quotes a some one double quote ... (took me 30 min just to get these examples to resolve in this editor!)

The n-literal syntax supports all kinds of things, not just quotes; blanks, special chars,...
So saspy has generated that syntax all along, but I misses the embedded quotes case and it tangles up parsing because they require special handling compared to anything else in the n-lit syntax (have to double single quotes, double quote single quotes, . bla bla bla).
So this version should handle all of this appropriately. Here's a SAS example using this:

data "cars''2"n; set sashelp.cars( rename=( Make='Make''s'n Model='Model"''s'n Cylinders="Cylinder''s"n horsepower="HP''s"n ) ); run;

For methods that take table or variable names explicitly, you can use Python string syntax to provide then; no need for the n-lit syntax; I generate the corect SAS code for those. But some methods take arbitrary string that are embedded directly into the code w/ no massaging from SASPy (no idea what the syntax is to be able to do so), so for those cases, you have to provide correct SAS (including n-literal as necessary) syntax yourself:

For known table or variable name just use Python string syntax for embedded quotes
cars = sas.sasdata("cars'2")
cars.heatmap('msrp',"hp's")

For arbitrary strings that are just included into the code, use SAS syntax
cars.where(''' "HP's"n > 400 ''').head()
stat_results = stat.reg(model=" 'hp''s'n = 'Cylinder''s'n EngineSize ",data=cars)

The other enhancement is is specific to Viya 4 (the HTTP access method), for authenticating to Viya. Originally user/pw were the only way. Right before SGF 2021, SSO (Single Sign On) was implemented which uses a client_it, client_secret and authcode, and a client_id/secret was created for SASPy which now ships w/ Viya 4, so all you actually need to do is just provide the authcode, which is like when you log onto a secure account and it text's you a code to type in to prove it's your, even though you've already authenticated, as an extra security mechanism. So that's already there. But what's new in this release is another variation on that.

The HTTP access to Viya 4 now support providing a JWT witch is an authentication token from other than SASLogon, which (if both systems are configured to share), can be used to acquire the SASLongon authentication token that is required for all API calls into Viya. This allows, for instance, an Azure ML instance to connect to Viya by providing the Azure auth token to saspy which then uses that (as opposed to user/pw or authcode) to get the SASLogon auth token. This config option is jwt= on the SASsesion() method. Support for passing a SASLogon token directly in is also available (meaning you've already somehow made calls to SASLogon yourself, or some other tool, and have a valid authtoken), via authtoken= on the SASsession() method. Both of these are really expected to be used under the covers by other tools/processes, but can be used by advanced users who can interface to the authenticating providers and acquire these tokens themselves directly.

V3.7.3

03 Aug 19:36
Compare
Choose a tag to compare

This release has a few enhancements. The IOM access method uses the Java IOM client (some jars files), and the log4j.jar in that is pretty old; 1.2. That version if past EOL, and raises flags on some security scans. So, I've upgraded to 2.12, which isn't the absolute newest, but it's close and the highest version that still supports Java7; one higher and Java8 is the minimum. Since saspy still supports back to Java7, and it isn't EOL till end of this year, I've gone w/ log4j 2.12. Maybe upgrade it in the future after java7 is dead.

Another cool thing is a user contributed script (see it in the new saspy/scripts dir, and pr #392 ) for batch submitting a .sas file, similar to how you could batch submit a .sas file with SAS from the command line. Check it out.

Another little enhancements is the the char_lengths parm of df2sd, which now accepts only the subset of columns you want to overrise; the others get calculated per usual. Before you had to provide the whole list.

There's a fix for SAS other missing values ('.A'-'.Z' and '._') from issue #390, so now those are all NaN,s when transferred, as they should have been.

Some doc changes for things, and that's about it.

V3.7.2

02 Jun 19:17
Compare
Choose a tag to compare

This is a minor release with just a couple of enhancements. One is a user contribution to enhance the saslib() method to support assigning concatenated libraries. That's a nice enhancement; just provide a list of paths instead of a single one and viola; you've got a concatenated libref. There's also a new configurations key on the HTTP access method; 'inactive'. The compute service in Viya has a 15 minute inactivity time out, by default, for a Session. This option allows you to set the number of minutes for this inactivity timeout. The default for this new option, however, is configured to be 120 minutes (2 hours), so you get that benefit without even needing to set this yourself. If you've had an HTTP Session and stepped away for 15 minutes then got a 404 on the next thing you submit, this will be a welcome improvement.

V3.7.1

12 May 17:47
Compare
Choose a tag to compare

This release has enhancements for the HTTP Access Method which connects to SAS in an Viya deployment. Prior to this release, only user/pw authentication was available. But there is a different mechanism for connecting in a SSO (Single Sign On) configurations of Viya. This requires 'clients' to be defined which provide scope and authorization groupings, ... An admin creates these as part of post-deployment so that an end user can then use their credentials to acquire one time auth codes used to signon (instead of their user/pw), based upon the client_id and client_secret previously set up. There are new config definition keys for these attributes and prompting in place when necessary for the authcode if it's not provided on the SASsession() method.

V3.7.0

12 May 04:33
Compare
Choose a tag to compare

This release has some major performance enhancements to the sasdata2dataframe (sd2df) methods in all 3 access methods; STDIO (including over SSH), IOM, and HTTTP. This is for all 3 methods as well; MEM, CSV, DISK. In fact, MEM and DISK are now one in the same, with 40% improvements in DISK for remote cases which means virtually infinite improvement for MEM for large datasets. MEM was too slow for large data, which is why CSV and DISK were implemented. Now, CSV and DISK aren't needed, but of course, are still there, and just work faster. MEM is still the default, and is now as fast. The key to this is that I no longer actually write the data being streamed over from SAS to a disk file, to then call pandas read_csv() to read the file and create the dataframe. Instead, I directly stream the data into read_csv() with no disk overhead and a direct feed into read_csv(). There is only one case where disk is still used, as that's just a bit faster. That is IOM Local with CSV. In that case, SAS has to write the csv file to disk before being able to stream it, so in that case, skipping that and just pointing read_csv() at the file is a little faster. All other cases I've tested are faster with this new scheme. So, this release is the performance release for moving SAS data to Pandas.

V3.6.7

26 Apr 14:35
e87fdd3
Compare
Choose a tag to compare

This version has a user requested enhancement to issue a warning where there is an ERROR in the SASLOG. This is done using the 'warnings' module, which is part of (and documented in) the Python standard Library. You can configure warnings to have these be issued never/sometimes/always, or even throw exceptions. It's actually kinda cool. I've also added some examples in the Advanced Topics section of the doc. A warning will also now be issued when df2sd() identifies that there is an index (row label) not the default of RangeIndex. This is when you've set_index() to a column. In this case, that indexed column isn't a dataframe.column anymore, so it wouldn't be transferred over to the SAS data set. This warning lets you know that column won't be transferred. You can simply use df2sd(df.reset_index(), ...) to allow that column to be transferred.
There is also a fix for the STDIO over SSH from a Windows client where reading the log and lst could get 'out of sequence' and result in missing output and partial xml being displayed. So that is fixed in there too.
There's also one more enhancement request in here for the disconnect() method in the IOM Access Method's Remote case. Upon disconnecting, the token needed to reconnect is now provided via an attribute off of the SASsession object; sas.reconuri. This can be now be provided via on the SASsession() method to be able to reconnect from a different Python process, via: sas = saspy.SASsession(reconuri=''), where you need to use the value from the previous session. this is not needed in the usual case where you're reconnecting from the same session; that still works as it always has. This is only for a situation where you have a new Python process you're using and want to reconnect.

V3.6.6

11 Mar 19:11
Compare
Choose a tag to compare

This release just has a couple fixes for MVS; connecting to a Workspace server running on MVS (Mainframe), via Remote IOM. I had caused a regression at some time w/ sd2df() and sd2df_DSIK(), as well as a type issue w/ encodings. This fixes all that and enhances the encoding validation code to support the default 1047 encoding to use cp500 which is all that is really needed for what little transcoding is required. So, the default just works w/out you needing to specify the encoding.

V3.6.5

15 Feb 14:51
Compare
Choose a tag to compare

This release just has some minor fixes and changes. There are a number or places in the HTTP access method I've needed to add checks to catch unexpected failures and disconnects and such, and provide a better exception; all failure cases, just better messages. A couple fixes for issues that were found since last release. I stripped FF (Form Feed) chars out of the log, as they are just annoying in terminal mode, and they keep the log from being displayed in some UI/IDEs. Unless you're sending the output to an actual line printer, you don't need them. I also changed the default value for method= in submitLST() from 'listonly' to 'listorlog', as, after hundreds of times using the method, I only ever want it to be 'listorlog'. The symmetry of 'listonly', with submitLOG(); getting the log or nothing, and the LST or nothing, was highly overrated. I don't use submitLST() if I don't expect to get output. And if I don't get output, I then go look at the LOG to see why! So, I switched the default to be the one that's realistically useful. You could say that's a breaking change, but I'd argue it's a fixing change :) I should have made that the default to start with. That's about it for this version.

V3.6.4

18 Dec 19:51
Compare
Choose a tag to compare

This release has three new features. Two new methods to compliment dirlist() and file_info() for server side file system access: file_copy() and file_delete(). Those are pretty self explanatory, and are in the API doc.
The other new feature is from Issue #353, adding the ability to use the STDIO over SSH (only over SSH) from a Windows client. STDIO (SSH or not) can only access a stand alone Linux SAS install. But this feature allows the Python process to be on a windows
client as opposed to a Linux client; which has been the requirement since I first wrote it.

V3.6.2

04 Dec 20:28
Compare
Choose a tag to compare

This release just has a few fixes/enhancements. One fix is to the HTTP access method, disabling the encoding option. Unlike the other access methods, where saspy has to transcode everything between pythons utf-8 and the SAS session encoding, the HTTP API being used requires everything to be utf-8 and it transcodes to/from SAS session encoding. Easy fix for saspy, and it's in here in this release.
There's a new user contributed method, validvarname, which renames the columns of your dataframe to match the SAS 'validvarname' constraints for however that option is set. This would be used prior to passing that dataframe to df2sd(). So now if you have that set to a more restrictive value, you can use this method to convert your column names to be compliant. This is something Access Engines do, based up the option setting, when accessing database table, which allow names that don't comply.
There are a couple other fixes, one in COM to fix a case where only missing values in a numeric SAS data set becomes a char type in the dataframe instead of numeric when importing in sd2df(). And another to allow overrides for index_col= and engine=, also in sd2df. These had been hard coded in sd2df, but can not be user specified.