From 2f0f87ff4988d6ccb5659e9b2e5eb1aad343342c Mon Sep 17 00:00:00 2001 From: SundareshSankaran Date: Fri, 18 Apr 2025 11:12:43 -0400 Subject: [PATCH] Update Python Virtual Environments v2.0.0 - new folder for Create Signed-off-by: SundareshSankaran --- ...Python - Create a Virtual Environment.step | 1 + .../README.md | 86 +++++++++++++++++++ ...eate a Virtual Environment components.json | 52 +++++++++++ .../Python - Create a Virtual Environment.sas | 53 ++++++++++++ 4 files changed, 192 insertions(+) create mode 100644 Python - Create a Virtual Environment/Python - Create a Virtual Environment.step create mode 100644 Python - Create a Virtual Environment/README.md create mode 100644 Python - Create a Virtual Environment/extras/Python - Create a Virtual Environment components.json create mode 100644 Python - Create a Virtual Environment/extras/Python - Create a Virtual Environment.sas diff --git a/Python - Create a Virtual Environment/Python - Create a Virtual Environment.step b/Python - Create a Virtual Environment/Python - Create a Virtual Environment.step new file mode 100644 index 00000000..8f2d9f38 --- /dev/null +++ b/Python - Create a Virtual Environment/Python - Create a Virtual Environment.step @@ -0,0 +1 @@ +{"creationTimeStamp":"2022-10-15T16:09:21.746Z","modifiedTimeStamp":"2022-10-19T15:03:33.683Z","createdBy":"Sundaresh.Sankaran@sas.com","modifiedBy":"Sundaresh.Sankaran@sas.com","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 (sundaresh.sankaran@sas.com) and Ali Aiello (ali.aiello@sas.com) \\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"}} \ No newline at end of file diff --git a/Python - Create a Virtual Environment/README.md b/Python - Create a Virtual Environment/README.md new file mode 100644 index 00000000..06068d33 --- /dev/null +++ b/Python - Create a Virtual Environment/README.md @@ -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 + + + + + diff --git a/Python - Create a Virtual Environment/extras/Python - Create a Virtual Environment components.json b/Python - Create a Virtual Environment/extras/Python - Create a Virtual Environment components.json new file mode 100644 index 00000000..891d312d --- /dev/null +++ b/Python - Create a Virtual Environment/extras/Python - Create a Virtual Environment components.json @@ -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 (sundaresh.sankaran@sas.com) and Ali Aiello (ali.aiello@sas.com) \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": "" + } +} \ No newline at end of file diff --git a/Python - Create a Virtual Environment/extras/Python - Create a Virtual Environment.sas b/Python - Create a Virtual Environment/extras/Python - Create a Virtual Environment.sas new file mode 100644 index 00000000..83bc5f0d --- /dev/null +++ b/Python - Create a Virtual Environment/extras/Python - Create a Virtual Environment.sas @@ -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; + + + +