Skip to content

Update Python Virtual Environments v2.0.0 - new folder for Create #209

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"creationTimeStamp":"2022-10-15T16:09:21.746Z","modifiedTimeStamp":"2022-10-19T15:03:33.683Z","createdBy":"[email protected]","modifiedBy":"[email protected]","name":"Python - Create a Virtual Environment.step","displayName":"Python - Create a Virtual Environment.step","localDisplayName":"Python - Create a Virtual Environment.step","properties":{},"links":[{"method":"GET","rel":"self","href":"/dataFlows/steps/2971fefb-bfb5-4bbe-9832-1235358c671f","uri":"/dataFlows/steps/2971fefb-bfb5-4bbe-9832-1235358c671f","type":"application/vnd.sas.data.flow.step"},{"method":"GET","rel":"alternate","href":"/dataFlows/steps/2971fefb-bfb5-4bbe-9832-1235358c671f","uri":"/dataFlows/steps/2971fefb-bfb5-4bbe-9832-1235358c671f","type":"application/vnd.sas.data.flow.step.summary"},{"method":"GET","rel":"up","href":"/dataFlows/steps","uri":"/dataFlows/steps","type":"application/vnd.sas.collection","itemType":"application/vnd.sas.data.flow.step.summary"},{"method":"PUT","rel":"update","href":"/dataFlows/steps/2971fefb-bfb5-4bbe-9832-1235358c671f","uri":"/dataFlows/steps/2971fefb-bfb5-4bbe-9832-1235358c671f","type":"application/vnd.sas.data.flow.step","responseType":"application/vnd.sas.data.flow.step"},{"method":"DELETE","rel":"delete","href":"/dataFlows/steps/2971fefb-bfb5-4bbe-9832-1235358c671f","uri":"/dataFlows/steps/2971fefb-bfb5-4bbe-9832-1235358c671f"},{"method":"GET","rel":"transferExport","href":"/dataFlows/steps/2971fefb-bfb5-4bbe-9832-1235358c671f","uri":"/dataFlows/steps/2971fefb-bfb5-4bbe-9832-1235358c671f","responseType":"application/vnd.sas.transfer.object"},{"method":"PUT","rel":"transferImportUpdate","href":"/dataFlows/steps/2971fefb-bfb5-4bbe-9832-1235358c671f","uri":"/dataFlows/steps/2971fefb-bfb5-4bbe-9832-1235358c671f","type":"application/vnd.sas.transfer.object","responseType":"application/vnd.sas.summary"}],"metadataVersion":0.0,"version":2,"type":"code","flowMetadata":{"inputPorts":[],"outputPorts":[]},"ui":"{\n\t\"showPageContentOnly\": true,\n\t\"pages\": [\n\t\t{\n\t\t\t\"id\": \"page1\",\n\t\t\t\"type\": \"page\",\n\t\t\t\"label\": \"Parameters\",\n\t\t\t\"children\": [\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"venv\",\n\t\t\t\t\t\"type\": \"textfield\",\n\t\t\t\t\t\"label\": \"Provide a name for your virtual environment (note: provide the full path if you want to persist your virtual environment)\",\n\t\t\t\t\t\"placeholder\": \"venv\",\n\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"req\",\n\t\t\t\t\t\"type\": \"textfield\",\n\t\t\t\t\t\"label\": \"Enter the path to your requirements.txt file (or simply list your packages with a space between)\",\n\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"text1\",\n\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\"text\": \"Note: Creation of a virtual environment also activates the same.\",\n\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"id\": \"page2\",\n\t\t\t\"type\": \"page\",\n\t\t\t\"label\": \"About\",\n\t\t\t\"children\": [\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"text2\",\n\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\"text\": \"Python - Create a virtual environment\\n\\nThe \\\"Python - Create a virtual environment\\\" custom step helps users create a virtual Python environment, install a given set of packages, and work within the confines of the new Python environment for project or program-specific purposes.\\n\\nUsers may choose to persist the virtual environment folder for later reuse, by simply providing a full path to a persistent location, when asked to provide a name for the location (make sure to include the name for the virtualenv folder - i.e. /path/to/storage/venv). In such a case, please provide a path on a shared file system, which you expect to access through another SAS session later on. Most SAS Viya deployments may contain a /mnt/... folder location which serves this purpose.\\n\\nUsers also have an option to provide a requirements file consisting of packages which they would like pip-installed. Either provide a path to a requirements.txt file which contains a list of python packages (and optionally, specific versions), or provide a list of packages as a string, separated by a space.\\n\\nCreated / contact : Sundaresh Sankaran ([email protected]) and Ali Aiello ([email protected]) \\n\\nVersion : 1.0. (20MAY2022)\\n\\nFor more details, refer https://blogs.sas.com/content/subconsciousmusings/2022/05/16/python-a-la-carte/\",\n\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t}\n\t\t\t]\n\t\t}\n\t],\n\t\"syntaxversion\": \"1.3.0\",\n\t\"values\": {\n\t\t\"venv\": \"venv\",\n\t\t\"req\": \"\"\n\t}\n}","templates":{"SAS":"/* SAS templated code goes here */\n\n\n\nproc python;\n\nsubmit;\n\nimport os\nfrom virtualenv import cli_run\n\nvenv=SAS.symget(\"venv\")\n\npyt=os.environ[\"PROC_PYPATH\"]\nSAS.symput(\"MAIN_PYTH\",str(pyt))\n\ncli_run([venv])\nactivate_this_file = os.path.join(venv,\"bin\",\"activate_this.py\")\nexec(open(activate_this_file).read(), {'__file__': str(activate_this_file)})\nSAS.symput(\"TEMP_PYTH\",str(os.path.join(venv,\"bin\",\"python3\")))\n\n\n\nendsubmit;\n\nquit;\nproc python terminate;\nquit;\n\noptions set=PROC_PYPATH=\"&TEMP_PYTH.\";\n\n%put &TEMP_PYTH.;\n%put &MAIN_PYTH.;\n\nproc python;\nsubmit;\nimport os\npyt=SAS.symget(\"TEMP_PYTH\")\nprint(\"Hello World\")\nreq=SAS.symget(\"req\")\nif os.path.isfile(req):\n print(\"File provided\")\n os.system(\"{pyt} -m pip install -r {req}\".format(pyt=pyt,req=req))\nelse:\n print(\"List provided\")\n os.system(\"{pyt} -m pip install {req}\".format(pyt=pyt,req=req))\n\nendsubmit;\nquit;\n\n\n\n\n"}}
86 changes: 86 additions & 0 deletions Python - Create a Virtual Environment/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# SAS Studio Custom Steps for virtual Python environments

## Description
Package your Python-based analytics solutions in a portable, repeatable, and reusable manner. This repo contains **five** SAS Studio custom steps which help you create, activate, and switch between virtual Python environments for use within SAS Viya.

A general idea :

![General idea](./img/general-idea.png)

## User Interface

Refer the "About" tab on each of the individual steps for more details on what they are used for.

### Create a virtual environment
This step helps you create a virtual environment. Input arguments required :
1. A name provided for your virtual environment (which can optionally be expressed as a full path to a persistent location, for future retrieval)
2. Additional packages you would like installed inside this virtual environment. As instructions note, you can provide a space-delimited string, or a path to a requirements.txt file.

![Python - Create a virtual environment](./img/create-a-virtual-environment.png)

### Activate a virtual environment
This step helps you activate an existing virtual environment. It requires a single argument to a folder path pointing to your virtual environment.

![Python - Activate a virtual environment](./img/activate-a-virtual-environment.png)

### Freeze environment details
This step helps you save details of all the packages currently installed in your environment, to a requirements.txt. You can reuse this requirements.txt file for other environments or create a new virtual environment based on this definition. You provide a single argument pointing to the path where you want your requirements.txt to be saved.

![Python - Freeze requirement details](./img/freeze-requirement-details.png)

### Revert to original environment
This step switches a SAS Studio session, currently under a virtual Python environment, to the Python environment that was in operation earlier. This step does not require any arguments.

![Python - Revert to original Python environment](./img/revert-to-original-environment.png)

### Obtain requirements file from Project Directory
This step helps users generate a relevant, more compact requirements.txt for a project containing one or more Python programs. The resulting requirements.txt can be used for specifying configuration for a virtual environment meant for running the said project.

![Python - Obtain requirements from project directory](./img/obtain-requirements-from-project-directory.png)

## Requirements

1. A SAS Viya 4 environment (monthly release 2021.2.1 or later) with SAS Studio Flows
2. Python configured with the above environment (preferably using the [SAS Configurator for Open Source](https://go.documentation.sas.com/doc/en/itopscdc/v_016/itopswn/p19hj5ipftk86un1axa51rzr5mxv.htm))
3. Python [virtualenv](https://virtualenv.pypa.io/en/latest/installation.html) package installed in above Python environment (the base environment)


## Installation & Usage

Refer to the [steps](../README.md#getting-started---making-a-custom-step-from-this-repository-available-in-sas-studio) listed in the main README.md

When successfully uploaded, the following structure will be present in the Shared Section of your SAS Studio application - Custom Steps tab.

![SAS Studio view](./img/view-custom-steps.png)


## The WHY : Background information

Refer this [blog](https://blogs.sas.com/content/subconsciousmusings/2022/05/16/python-a-la-carte) for background. The ability to create and use virtual Python environments for use within SAS Viya helps data scientists create portable solutions, maintain solution integrity, and exploit the integration between SAS and Python to the fullest extent.

Watch this example!

[SAS & Open Source (Python) Integration : Better Together](https://www.youtube.com/watch?v=YVaX-A-ZsQ0&list=PLpe69msCs2C8IcarG0aEs_iKy4gyRSFPN&index=3)

[Creating virtual Python environments within SAS Studio.](https://youtu.be/UIYZf2bKcWw)

This repository contains 5 custom steps which are offered as examples of how you could create, activate, switch between, and package virtual Python environments from within SAS Viya applications and tools, such as SAS Studio. It makes use of [Custom Steps](https://go.documentation.sas.com/doc/en/webeditorcdc/v_006/webeditorug/n0b7ljqhka8lh5n12judc27x5gph.htm), a component within SAS Studio which help users package repeatable steps in an user-friendly manner.


## Change Log

* Version 2.0 (18APR2025)
- Separate folders in repository
- Refactored code to leverage venv
- Additional parameters

* Version 1.1 (12JUL2022)
- Added new Custom Step - "Python - Obtain requirements from project directory" : Ju1 12 2022

* Version 1.0 (20MAY2022)
- Renamed to "Python - " as per Wilbram's advice; shuffled order of About tab on "Freeze" : Jun 15 2022





Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
{
"showPageContentOnly": true,
"pages": [
{
"id": "page1",
"type": "page",
"label": "Parameters",
"children": [
{
"id": "venv",
"type": "textfield",
"label": "Provide a name for your virtual environment (note: provide the full path if you want to persist your virtual environment)",
"placeholder": "venv",
"required": false,
"visible": ""
},
{
"id": "req",
"type": "textfield",
"label": "Enter the path to your requirements.txt file (or simply list your packages with a space between)",
"placeholder": "",
"required": false,
"visible": ""
},
{
"id": "text1",
"type": "text",
"text": "Note: Creation of a virtual environment also activates the same.",
"visible": ""
}
]
},
{
"id": "page2",
"type": "page",
"label": "About",
"children": [
{
"id": "text2",
"type": "text",
"text": "Python - Create a virtual environment\n\nThe \"Python - Create a virtual environment\" custom step helps users create a virtual Python environment, install a given set of packages, and work within the confines of the new Python environment for project or program-specific purposes.\n\nUsers may choose to persist the virtual environment folder for later reuse, by simply providing a full path to a persistent location, when asked to provide a name for the location (make sure to include the name for the virtualenv folder - i.e. /path/to/storage/venv). In such a case, please provide a path on a shared file system, which you expect to access through another SAS session later on. Most SAS Viya deployments may contain a /mnt/... folder location which serves this purpose.\n\nUsers also have an option to provide a requirements file consisting of packages which they would like pip-installed. Either provide a path to a requirements.txt file which contains a list of python packages (and optionally, specific versions), or provide a list of packages as a string, separated by a space.\n\nCreated / contact : Sundaresh Sankaran ([email protected]) and Ali Aiello ([email protected]) \n\nVersion : 1.0. (20MAY2022)\n\nFor more details, refer https://blogs.sas.com/content/subconsciousmusings/2022/05/16/python-a-la-carte/",
"visible": ""
}
]
}
],
"syntaxversion": "1.3.0",
"values": {
"venv": "venv",
"req": ""
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/* SAS templated code goes here */



proc python;

submit;

import os
from virtualenv import cli_run

venv=SAS.symget("venv")

pyt=os.environ["PROC_PYPATH"]
SAS.symput("MAIN_PYTH",str(pyt))

cli_run([venv])
activate_this_file = os.path.join(venv,"bin","activate_this.py")
exec(open(activate_this_file).read(), {'__file__': str(activate_this_file)})
SAS.symput("TEMP_PYTH",str(os.path.join(venv,"bin","python3")))



endsubmit;

quit;
proc python terminate;
quit;

options set=PROC_PYPATH="&TEMP_PYTH.";

%put &TEMP_PYTH.;
%put &MAIN_PYTH.;

proc python;
submit;
import os
pyt=SAS.symget("TEMP_PYTH")
print("Hello World")
req=SAS.symget("req")
if os.path.isfile(req):
print("File provided")
os.system("{pyt} -m pip install -r {req}".format(pyt=pyt,req=req))
else:
print("List provided")
os.system("{pyt} -m pip install {req}".format(pyt=pyt,req=req))

endsubmit;
quit;