In Part 2 of The Director’s Cut of my SAS Innovate 2026 presentation on 6 ways you can run Python in SAS Viya, we’re going to continue with our theme of places where Python programmers like to be. More specifically: VS Code and Notebooks.
Part 1 talked about SAS® Viya® Workbench, an independent development environment that is designed with Python in mind. From this point forward, we’re going to talk about how you can program with Python in a shared, enterprise SAS Viya environment; plus, how you can do this in SAS 9.4 as well. Don’t worry, we love you too. You’re also invited to the Python party.
To save you some time, I’m going to ask you two questions:
- Can you install VS Code on your laptop, terminal server, or secure environment?
- Can you install the SAS Extension for VS Code?
If you said yes to both, or you know you can make both happen, read on. Otherwise, you’re headed to browserland, where SAS Data and AI Studio (previously SAS Studio) will be a better fit. If that’s you, pop on over to Part 3 (coming soon).
Let’s dive in.
Code here, run there
The SAS Extension for VS Code is free on the VS Code Marketplace and open source on GitHub for you to analyze, fork, or improve. When you install the extension, you simply create a new connection profile from the command palette (Ctrl + Shift + P) and walk through the guided setup process to add a new SAS connection:
- Enter a profile name
- Choose your environment type (Viya or 9.4)
- Enter the URL of your environment
- Hit enter to choose the default job execution context
- Hit enter again to use the default client ID
- If prompted, open the link to your browser, copy and paste the authorization code
That’s it. You’re now connected to SAS Viya and can run code or create new SAS Notebooks. But here’s the cool thing:
Your code executes and your data is processed all in SAS Viya.
Code execution and data processing occur within SAS Viya and through the libraries, databases, and other resources connected to it. Your IT department will be happy about that.
Meanwhile, you get to use a familiar IDE with all your favorite extensions, agents, and other VS Code goodies to assist you with programming. You’ll be happy about that.
It’s a win-win for everyone.
SAS Notebooks: similar name, same rhyme
If you’re coding in Python, you probably want to use a notebook. SAS Notebooks are designed with that in mind. If you use Jupyter Notebooks, then you already know how to use SAS Notebooks. You get Markdown, cells, inline output, execution time, and plenty of the things you expect from a notebook. And yep, they all use the same shortcuts. Hit b to create a new cell below, hit a to create one above, press Shift+Enter to run a cell, etc. You know what to do already.
When you first make a SAS Notebook, it will default to using a SAS cell. Go look on over to the bottom right of that cell and click SAS on the language selector, then look at the top of the screen.
Click Python and type:
print('Hello world!')
Congratulations. You’re now running Python in SAS with VS Code, and you didn’t need to type PROC once.
Cool. You can print stuff and run Python code. That’s all fine and nice, but what about graphics?
That’s there, too. If you’re a fan of matplotlib or seaborn, you’ll be happy to know that you can get inline graphics easily. There is one important difference: instead of plt.show(), you need to use a callback method called SAS.show(). Here’s an example:
import pandas as pd import seaborn as sns from matplotlib import pyplot as plt df = pd.read_csv('https://support.sas.com/documentation/onlinedoc/viya/exampledatasets/hmeq.csv') plt.clf() sns.heatmap(df.select_dtypes(include='number').corr()) SAS.show(plt) |
If you take a look at your inline output, you’ll see this:
It even works on Pandas DataFrames:
SAS.show(df)
This is but one of many different callback methods that come with SAS Viya.
Don’t call it a callback… actually, yes, call it that.
I’ve used the word “callback” a few times now. What does that mean? Well, it has nothing to do with LL Cool J. These are special methods that are built into SAS Viya that allow Python to call back and talk with SAS. Remember, Python and SAS are two completely different engines, and neither knows what the other is doing unless you tell them.
Think of callbacks as a bridge between two separate execution engines. Python and SAS do not automatically share state, data, or variables, so callback methods let you explicitly pass information and instructions between them.
For you SAS programmers, it’s somewhat analogous to the SAS macro facility and the DATA step: there are functions to bridge them together, but otherwise, they work in their own unique worlds. That’s what these callback methods are for.
You can do a lot of other things, such as:
- sd2df(): Convert SAS datasets to Pandas DataFrames
- df2sd(): Convert Pandas DataFrames to SAS datasets
- sasfnc(): Run SAS functions from Python and retrieve the results
- submit(): Run arbitrary SAS code
- symget(): Get the value of a SAS macro variable
- symput(): Create a SAS macro variable
- showMLA(): Create graphical output from sasviya.ml model details
- Control log output
If some of those look familiar to you, it’s because you might have seen them in the saspy package. We’ll talk about that in Part 6 (coming later).
The two methods to convert SAS datasets to and from Python are simple ways to work with your data, but they perform data transfer in the background and can occasionally require some post-processing to ensure columns are correct. Both methods have options to help with that. Instead, why not just use an open data format like Parquet or DuckDB?
Python just became your next PROC SQL
SAS programmers know that they can bounce between the DATA step and PROC SQL, choosing whichever is better suited for the problem at hand. Python is now your third option, and the best way for you to take advantage of that is by using an open data format. When you work with open table and database formats like Parquet or DuckDB, you don’t need to convert from one format to another.
Take a look at these three cells here.
Cell 1 – Python: We read from a Parquet file, hmeq.parquet, build a model using sasviya.ml, then export it as an Analytic Store (also called an ASTORE, a representation of the model’s trained state used for scoring).
df = pl.read_parquet(dir_path / 'data' / 'hmeq.parquet') X = df.drop(['BAD']) y = df['BAD'] X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42) model = GradientBoostingClassifier(random_state=42) model.fit(X_train, y_train) model.export(dir_path / 'models' / 'hmeq_gboost_model.astore') |
Cell 2 – SAS: We load the model into memory and score it against the same full Parquet file with PROC ASTORE, then output the results back to Parquet.
libname pq parquet "&dir_path/data"; proc astore; upload store = "&dir_path/models/hmeq_gboost_model.astore" rstore = hmeq_gboost_model ; score rstore = hmeq_gboost_model data = pq.hmeq out = pq.hmeq_scored ; run; |
Cell 3 – SQL: We query the resulting probabilities and model decisions using SQL.
select monotonic() as ID , P_BAD1 label='Probability of Default' format=percent8.2 , CASE(strip(I_BAD)) when('1') then 'Default' else 'Good' END as P_Default label='Prediction' from pq.hmeq_scored(obs=25) |
Python and SAS both worked with the exact same table. Not only that, but we even took advantage of sasviya.ml which can process Polars DataFrames directly. We could have done this with DuckDB, too, by giving model.fit() and an embedded DuckDB query.
sas7bdat? More like sas7bdat’s not all there is.
Another example: updating table metadata
Have you ever gotten a table that looks like this?
| COLUMN_A | COLUMN_B | COLUMN_C | COLUMN_D | COLUMN_E |
| FOO | 100 | 2026-02-10 | ACTIVE | 42 |
| BAR | 200 | 2026-03-15 | PENDING | 67 |
| BAZ | 300 | 2026-04-19 | COMPLETE | 68 |
SAS doesn’t care about column or variable case, so it doesn’t matter there. But Python most certainly does. It’s easier to make sure every column name is the same case as you bounce between both SAS and Python. Personally, I like lowercase and snake-case because NO ONE LIKES IT WHEN YOUR DATA IS YELLING AT YOU.
Let’s compare how you do it between SAS and Python.
SAS
%macro lowcase_cols(lib, data); proc sql noprint; select name into :cols separated by '|' from dictionary.columns where libname=upcase("&lib") AND memname=upcase("&data") ; quit; proc datasets lib=&lib; modify &data; rename %do i = 1 %to %sysfunc(countw(&cols, |)); %let col = %scan(cols, &i, |); %let tmp = _tmp&i; &col = &tmp &tmp = %lowcase(&col) %end; ; quit; %mend; %lowcase_cols(libname, dataset); |
Python
import polars as pl import os lf = pl.scan_parquet('data.parquet') lf = lf.rename(str.lower) lf.sink_parquet('data_lower.parquet') os.replace('data_lower.parquet', 'data.parquet') |
I think Polars, Pandas, and DuckDB make it very easy to do this right out of the box, and that’s exactly the type of thing I’d reach for with small to medium data. But when you’re looking for extreme efficiency, SAS has no issue renaming those columns in place on tables so long as the table format has mutable metadata.
The days of sending CSV files to and from your SAS colleagues are long gone.
Everyone works from the same open formats, which means you choose the language that works best for the scenario, letting you focus more on solving the crux of the problem rather than how to do something that one language just isn’t great at.
Get your notebook ready to schedule
Okay, so you’ve got this nifty notebook, and it all runs exactly like you want it to. You’re ready to test this thing out on some real data, get it out into Viya, and eventually, production. You’ve got two options:
- Convert your notebook into a SAS program
- Convert your notebook into a code flow
Whichever you choose is entirely up to you, and both are equally simple.
Convert a SAS Notebook to a SAS program
To convert your notebook into a SAS program, do the following:
- Go to the top of your notebook and select the three ellipses
- Click “Export”
- Save the file
- Done!
Open up the file and you’ll see something interesting.
Python programmers, shield your eyes.
That’s right. You’ve discovered the secret. The extension is wrapping your Python code for you in PROC PYTHON. Bet you didn’t see that coming, didn’t you?
You can take this code exactly as-is and configure it to run on a schedule. There’s nothing else you need to do with the code. Oh, and all of your markdown is preserved as comments. How cool is that?
This is just one of the ways in which we’re making Python programmers feel right at home in SAS Viya. You get to program in a notebook without seeing the word PROC, and SAS can still work with your code exactly as you wrote it. No drama, no fuss. Everyone’s happy.
Convert a SAS Notebook to a flow
You also have the option to convert your code into a code flow within SAS Data and AI Studio. Here’s how you do it:
- Make sure your notebook is saved to SAS Content (the top-left section on the left side of the extension). You can upload it to this folder if needed by right-clicking and selecting “Upload.”
- Right-click your notebook and select “Convert to Flow…” and give it a name.
- Open up SAS Studio and check out the code flow it created.
And…
Boom! Check that out. All your cells are now code steps connected in a single flow.
You can control the output format of this, too. Go to your preferences (Ctrl + Shift + P → search for Preferences) and change the conversion mode to Swimlane if that’s more your style.
Whichever method you prefer, you can schedule this code flow right there in SAS Viya. You can also start adding in some low-code/no-code options from the plethora of steps available in SAS Data and AI Studio. Or maybe instead you want to connect it to Apache Airflow for scheduling, because yeah, you totally can do that. It’s all up to you.
How about SAS 9.4?
Boy, do I have good news for you. PROC PYTHON is now available in SAS 9.4 M9 as a hotfix. Download it with the SAS Hot Fix Analysis, Download and Deployment Tool, install it, follow the configuration instructions, and get programming. Once you have that all ready to go, fire up VS Code with the SAS extension.
When you create a new connection, instead select your relevant SAS 9.4 install. For example, if you have SAS on your laptop, choose SAS 9.4 (local).
Once your connection is established, create a new Python cell and start programming away. That’s it! That’s all you need to do. Everything works just as you would expect, which makes migrating your SAS Notebook from executing in SAS 9.4 to SAS Viya much easier.
Let’s wrap on up.
If you’re a Python programmer in SAS Viya, the SAS Extension for VS Code is one of the first places you should look. It’s natural, easy to use, secure, flexible, and open source (very strong hint: we would love to see you contribute to it; I am contributing, too!). If you have agents, copilots, or other extensions you have in VS Code, you’ll be able to use them. For example, I use GitHub Copilot a lot. Its autocomplete practically reads my mind and is like magic. That’s a huge help when I am programming within the extension.
SAS Viya is designed to have IDE flexibility. We know where Python programmers like to work, and we want to meet you where you are. For those who have limited IDE options, we still want to meet you where you are.
VS Code is not available in every organization, and not every developer is allowed to install it. That is exactly why this series covers so many approaches.
In Part 3, we’ll look at how to work with Python in SAS Data and AI Studio entirely from your browser, with no local installation required. You’ll see how to mix Python, SQL, and SAS, incorporate no-code drag-and-drop steps, and use SAS Viya Copilot Code Assist.
See you there.
Is the SAS Extension for VS Code free and open source?
Yes, the SAS Extension for VS Code is free and open source. The source code is available in the sassoftware repository on GitHub.
Developers can review the source code, report issues, suggest improvements, fork their own version, and contribute changes through pull requests.
Are my code and data secure when I use the SAS Extension for VS Code?
SAS Viya is secure by design. When connected to SAS Viya, the extension runs code and processes data within the SAS Viya environment rather than transferring data to VS Code for local processing.
You can save source code locally, including in a Git-enabled directory, but code execution and data processing remain in SAS Viya. Connections to external databases, libraries, and other resources are managed through the SAS Viya environment configured by your administrator. Temporary SAS data sets, in-memory DataFrames, and other objects created during execution also remain within the SAS Viya environment.
Your organization’s actual security posture depends on how SAS Viya, VS Code, authentication, authorization, and external connections are configured. For details about your environment, speak with your SAS Viya administrator.
Does the SAS Extension for VS Code require administrator configuration in SAS Viya?
No, the SAS Extension for VS Code does not require SAS Viya configuration that is specific to the extension. However, the SAS Viya Copilot extension has an additional access requirement.
To use the SAS Viya Copilot extension with the SAS Extension, your administrator must add you to the GenAI VSCode Users custom group in your SAS Viya deployment.
Do I need to write PROC PYTHON to use Python in the SAS Extension for VS Code?
No, you do not need to write PROC PYTHON when using a Python code block in a SAS Notebook in VS Code.
For each code block, use the language selector in the lower-right corner to choose one of the supported languages:
When you select Python, R, or SQL, write code using the native syntax of that language. The SAS Extension for VS Code wraps the code in the required SAS procedure automatically. You can work in the language you know without manually adding the corresponding SAS procedure.
Can I schedule a SAS Notebook for production use?
Yes, code from a SAS Notebook can be prepared for scheduling by exporting the notebook as a SAS program or converting the saved code into a SAS Studio flow. To export a notebook as a SAS program:
- Select the ellipsis menu in the upper-right corner of the notebook.
- Export the notebook code as a SAS file.
To convert code into a SAS Studio flow:
- Save the code to SAS Content.
- Right-click the saved file.
- Select Convert to Flow…
The exported code can run without changes to the code itself. Scheduling, permissions, credentials, and access to required resources must still be configured appropriately in the target SAS Viya environment.
Do SAS Notebooks support Python graphics from Matplotlib and Seaborn?
Yes, SAS Notebooks support inline Python graphics created with libraries such as Matplotlib and Seaborn.
Use the SAS.show(plt) callback method to display a Python figure inline in the notebook. You can also use SAS.show(df) to display supported Python DataFrames as SAS ODS output.
Can I use Python, R, SQL, and SAS in the same SAS Notebook?
Yes, a single SAS Notebook can contain Python, R, SQL, and SAS code blocks. You can select a language separately for each code block and use the language best suited to each task.
Open data formats can also help different languages exchange data. For example, SAS Viya provides LIBNAME engines for working with Parquet and DuckDB.
Does SAS Viya include the sasviya Python package?
Yes, the sasviya Python package is available with SAS Viya, but an administrator must install it into a Python environment.
A SAS administrator should include the sasviya package when creating or configuring a Python environment. For installation and configuration requirements, see the SAS documentation for configuring Python integration with SAS Viya.
Can I use Python with SAS 9.4 in the SAS Extension for VS Code?
Yes, you can use Python code blocks in the SAS Extension for VS Code with SAS 9.4 when PROC PYTHON support has been configured. The SAS Extension for VS Code supports connections to SAS 9.4 through local, IOM, and SSH connection types.
For running Python in SAS 9.4M9 and above, review the following resources:
Your SAS administrator may need to install the required hot fix and configure PROC PYTHON before Python code blocks can run successfully.













