PythonTools.psm1


Function Get-PythonEnvironmentRoot
{

$VirtualEnvironmentRoot = Join-Path -Path $Env:USERPROFILE -ChildPath '.virtualenvs'
$VirtualEnvironmentRoot

}

Function Enter-PythonEnvironment
{

<#
.SYNOPSIS
    Enter a Python virtual environment.
 
.DESCRIPTION
    The Enter-PythonEnvironment enters into a named Python environment.
 
.PARAMETER Name
    Name of the virtual environment.
 
.PARAMETER ChangeDirectory
    Change location to the environment directory.
 
.INPUTS
  System.String
 
.OUTPUTS
  None
 
.NOTES
    Version: 1.00
    Author: David Wallace
    Updated: -
    First Released: 21 Oct 2018
 
 
    Version History
    --------------
 
    1.0 (21 Oct 2018)
 
    * Initial Release
 
.EXAMPLE
  C:\PS> Enter-PythonEnvironment -Name MyEnv
 
  Description
  -----------
 
   Enters the Python virtual environment named MyEnv.
 
#>


[CmdLetBinding(SupportsShouldProcess, ConfirmImpact='High')]
Param (
        [Parameter (Mandatory=$True,Position=1)]
        [String] $Name,
        [Switch] $ChangeDirectory
        )

$ErrorActionPreference = 'Stop'

$VirtualEnvironmentRoot = Get-PythonEnvironmentRoot
$VirtualEnvironmentPath = Join-Path -Path $VirtualEnvironmentRoot -ChildPath $Name


If (Test-Path $VirtualEnvironmentPath)
    {
        If ($Env:VIRTUAL_ENV)
            {
                Throw 'Already in virtual environment, use Exit-PythonEnvironment!'
            }
        else
            {
                Copy-Item -Path Function:prompt -Destination Function:_OLD_VIRTUAL_PROMPT -Force
                $ActivatePath = Join-Path -Path $VirtualEnvironmentPath -ChildPath 'Scripts\Activate.ps1'
                . $ActivatePath
                & python.exe --version

                If ($ChangeDirectory)
                    {
                        Set-Location -Path $VirtualEnvironmentPath
                    }

            }
    }
else
    {
        Throw "The virtual environment $Name can not be found!"
    }


}

New-Alias -Name workon -Value Enter-PythonEnvironment
Export-ModuleMember -Alias '*' -Function Enter-PythonEnvironment

Function Exit-PythonEnvironment
{

<#
.SYNOPSIS
    Exit the active Python virtual environment.
 
.DESCRIPTION
    The Exit-PythonEnvironment exits the active Python environment.
 
.INPUTS
  System.String
 
.OUTPUTS
  None
 
.NOTES
    Version: 1.00
    Author: David Wallace
    Updated: -
    First Released: 21 Oct 2018
 
 
    Version History
    --------------
 
    1.0 (21 Oct 2018)
 
    * Initial Release
 
.EXAMPLE
  C:\PS> Exit-PythonEnvironment
 
  Description
  -----------
 
   Exits the active Python virtual environment.
 
#>


$ErrorActionPreference = 'Stop'

Copy-Item -Path Function:_OLD_VIRTUAL_PROMPT -Destination Function:prompt -ErrorAction SilentlyContinue
Remove-Item -Path Function:\_OLD_VIRTUAL_PROMPT -ErrorAction SilentlyContinue

If ($Env:_OLD_VIRTUAL_PATH_PYTHONHOME)
    {
        $Env:PYTHONHOME = $Env:_OLD_VIRTUAL_PATH_PYTHONHOME
    }

If ($Env:_OLD_VIRTUAL_PATH)
    {
        $Env:_OLD_VIRTUAL_PATH = $Null
    }

$Env:VIRTUAL_ENV = $Null

}

New-Alias -Name deactivate -Value Exit-PythonEnvironment
Export-ModuleMember -Alias '*' -Function Exit-PythonEnvironment

Function Get-PythonEnvironment
{

<#
.SYNOPSIS
    Removes an exisitng Python virtual environment.
 
.DESCRIPTION
    The Remove-PythonEnvironment removes an exisitng Python virtual environment.
 
.PARAMETER Name
    Name of the virtual environment.
 
.PARAMETER Detailed
    Displays detailed information of Python environment.
 
.INPUTS
  System.String
 
.OUTPUTS
  None
 
.NOTES
    Version: 1.00
    Author: David Wallace
    Updated: -
    First Released: 21 Oct 2018
 
 
    Version History
    --------------
 
    1.0 (21 Oct 2018)
 
    * Initial Release
 
.EXAMPLE
  C:\PS> Get-PythonEnvironment
 
  Description
  -----------
 
  Displays all Python environments.
 
.EXAMPLE
  C:\PS> Get-PythonEnvironment -Name MyEnv -Detailed
 
  Description
  -----------
 
  Displays detailed information on Python environment named "MyEnv"
#>


[CmdLetBinding(SupportsShouldProcess, ConfirmImpact='High')]
Param (
        [Parameter (Position=1)]
        [String] $Name,
        [Switch] $Detailed
        )

$ErrorActionPreference = 'Stop'

$VirtualEnvironmentRoot = Get-PythonEnvironmentRoot


If ($Name)
    {
        $Result = Get-Item -Path $(Join-Path -Path $VirtualEnvironmentRoot -ChildPath $Name) | Where-Object -FilterScript { $_.PSIsContainer }
    }
else
    {
        $Result = Get-ChildItem -Path $VirtualEnvironmentRoot| Where-Object -FilterScript { $_.PSIsContainer }
    }

If ($Detailed)
    {
        $DetailedResult = @()

        ForEach ($Env in $Result)
            {
                $DetailedResult += [PSCustomObject] @{
                                                        'Name' = $Env.BaseName
                                                        'Version' =$(Try{$(& $(Join-Path -Path $VirtualEnvironmentRoot -ChildPath "$($Env.BaseName)\Scripts\python.exe") --version 2>&1).Replace('Python ','')}Catch{$_.Exception.Message.Replace('Python ','')})
                                                    }

            }

        $DetailedResult
    }
else
    {
        $Result | Select-Object -Property Name
    }

}

New-Alias -Name lsvirtualenv -Value Get-PythonEnvironment
Export-ModuleMember -Alias '*' -Function Get-PythonEnvironment

Function Invoke-PythonScript
{

<#
.SYNOPSIS
    Executes Python script from PowerShell.
 
.DESCRIPTION
    The Invoke-PythonScript cmdlet executes Python script from PowerShell.
 
.PARAMETER Path
    The path of the Python script to execute.
 
.PARAMETER ConvertJsonOutput
    Returns Converts JSON output from the Python Script to a PSObject.
 
.INPUTS
  System.String
 
.OUTPUTS
  System.String
 
.NOTES
    Version: 1.00
    Author: David Wallace
    Updated: -
    First Released: 21 Oct 2018
 
 
    Version History
    --------------
 
    1.0 (21 Oct 2018)
 
    * Initial Release
 
.EXAMPLE
  C:\PS> Invoke-PythonScript -FilePath myscript.py
 
  Description
  -----------
 
   Executes a script using the python interpreter.
 
.EXAMPLE
  C:\PS> Invoke-PythonScript -FilePath myscript.py -ConvertJsonOutput
 
  Description
  -----------
 
   Converts Python script json output to a Powershell Object.
 
 
#>


[CmdLetBinding()]
Param (
        [Parameter (Mandatory=$True,Position=1)]
        [String] $Path,
        [Switch] $ConvertJsonOutput
        )

$ErrorActionPreference = 'Stop'

$PythonOutput = python.exe $(Get-Command -Name $Path).Source

If ($ConvertJsonOutput)
  {
    $PythonOutput | ConvertFrom-Json
  }
Else
  {
    $PythonOutput
  }

}

New-Alias -Name ipy -Value Invoke-PythonScript
Export-ModuleMember -Alias '*' -Function Invoke-PythonScript

Function New-PythonEnvironment
{

<#
.SYNOPSIS
    Creates a new Python virtual environment.
 
.DESCRIPTION
    The New-PythonEnvironment cmdlet creates a new Python virtual environment.
 
.PARAMETER Name
    Name of the virtual environment.
 
.PARAMETER Version
    Python version of the virtual environment.
 
.INPUTS
  System.String
 
.OUTPUTS
  None
 
.NOTES
    Version: 1.00
    Author: David Wallace
    Updated: -
    First Released: 21 Oct 2018
 
 
    Version History
    --------------
 
    1.0 (21 Oct 2018)
 
    * Initial Release
 
.EXAMPLE
  C:\PS> New-PythonEnvironment -Name MyEnv
 
  Description
  -----------
 
   Creates a new Python virtual environment named MyEnv.
 
#>


[CmdLetBinding()]
Param (
        [Parameter (Mandatory=$True,Position=1)]
        [String] $Name,
        [Parameter (Position=2)]
        [String] $Version = '3'
        )

$ErrorActionPreference = 'Stop'

$VirtualEnvironmentRoot = Get-PythonEnvironmentRoot
$VirtualEnvironmentPath = Join-Path -Path $VirtualEnvironmentRoot -ChildPath $Name

Switch($Version[0])
    {
        '2' {$ModuleName = 'virtualenv'}
        default {$ModuleName = 'venv'}
    }

If (Test-Path $VirtualEnvironmentPath)
    {
        Throw "The virtual environment $Name already exists!"
    }

If ($Version -eq 2)
    {
        py.exe -$Version -m pip install $ModuleName
    }

py.exe -$Version -m $ModuleName $VirtualEnvironmentPath

}

New-Alias -Name mkvirtualenv -Value New-PythonEnvironment
Export-ModuleMember -Alias '*' -Function New-PythonEnvironment

Function Remove-PythonEnvironment
{

<#
.SYNOPSIS
    Removes an exisitng Python virtual environment.
 
.DESCRIPTION
    The Remove-PythonEnvironment removes an exisitng Python virtual environment.
 
.PARAMETER Name
    Name of the virtual environment.
 
.INPUTS
  System.String
 
.OUTPUTS
  None
 
.NOTES
    Version: 1.00
    Author: David Wallace
    Updated: -
    First Released: 21 Oct 2018
 
 
    Version History
    --------------
 
    1.0 (21 Oct 2018)
 
    * Initial Release
 
.EXAMPLE
  C:\PS> Remove-PythonEnvironment -Name MyEnv
 
  Description
  -----------
 
   Removes the existing Python virtual environment named MyEnv.
 
#>


[CmdLetBinding(SupportsShouldProcess, ConfirmImpact='High')]
Param (
        [Parameter (Mandatory=$True,Position=1)]
        [String] $Name
        )

$ErrorActionPreference = 'Stop'

$VirtualEnvironmentRoot = Get-PythonEnvironmentRoot
$VirtualEnvironmentPath = Join-Path -Path $VirtualEnvironmentRoot -ChildPath $Name

If (Test-Path $VirtualEnvironmentPath)
    {

        If ($Env:VIRTUAL_ENV -eq $VirtualEnvironmentPath)
            {
                Throw 'Virtual environment in use, use Exit-PythonEnvironment!'
            }
        Else
            {
                If ($PSCmdlet.ShouldProcess("Removing virtual path $VirtualEnvironmentPath"))
                    {
                        Remove-Item -Path $VirtualEnvironmentPath -Recurse
                    }

            }
    }
Else
    {
       Throw "Python environment $Name can not be found!"
    }

}

New-Alias -Name rmvirtualenv -Value Remove-PythonEnvironment
Export-ModuleMember -Alias '*' -Function Remove-PythonEnvironment