- BuildMaster
- Getting Started with BuildMaster
- Builds and Continuous Integration
- What is a "Build" in BuildMaster?
- Git and Source Control
- Git Pipelines and Workflows
- Build Scripts & Templates
- Packages & Dependencies
- Build Artifacts
- Automated Testing & Verification
- Deployment & Continuous Delivery
- What is a “Pipeline” in BuildMaster?
- CI Server (Jenkins, TeamCity, etc.) Integration
- Deployment Scripts & Templates
- Automatic Checks & Approval Gates
- Manual Deployment Steps and Tasks
- Databases
- Configuration Files
- Rollbacks
- Advanced CD Patterns
- Applications & Releases
- Connecting to your Servers with BuildMaster
- Scripting in BuildMaster
- Configuring for Your Team
- Docker/Containers
- Development Platforms
- Deployment Targets
- Tools & Service Integrations
- Reference
- BuildMaster API Endpoints & Methods
- Extending BuildMaster
- Built-in Functions & Variables
- Applications
- Builds
- Configuration Files
- Containers
- Credentials
- Databases
- Deployables
- Environments
- Executions
- Files
- General
- JSON
- Linux
- Lists
- Maps
- Math
- Nuget
- Packages
- Pipelines
- PowerShell
- Python
- Releases
- Servers
- Strings
- XML
- Built-in Operations
- Batch
- BuildMaster
- Configuration Files
- Databases
- DotNet
- Files
- Firewall
- General
- Apply-Template
- Attach Package
- Build
- Checkout-Code
- Close-Issue
- Concatenate-Files
- Copy-Files
- Create-Directory
- Create-File
- Create-Issue
- Create-Issue
- Create-IssueComment
- Create-Package
- Create-ZipFile
- Delete-Files
- Download-Asset
- Download-Http
- Ensure-Directory
- Ensure-File
- Ensure-HostsEntry
- Ensure-Metadata
- Ensure-Milestone
- Ensure-Package
- Ensure-Release
- Ensure-Tag
- Exec
- Execute Python Script
- Execute VSTest Tests
- Get-Http
- Install-Package
- OSCall
- OSExec
- Post-Http
- Push-PackageFile
- PYCall
- PYEnsure
- Query-Package
- Remediate-Drift
- Rename-File
- Repackage
- Replace-Text
- Send-Email
- Set-FileAttributes
- Set-Variable
- SHEnsure
- Sleep
- Transfer-Files
- Transition-Issues
- Upload-Assets
- Upload-Http
- Upload-ReleaseAssets
- Git
- IIS
- Nuget
- PowerShell
- ProGet
- Python
- Registry
- Servers
- Services
- Shell
- Windows
- Administration
- Installation & Upgrading
- ProGet
- Getting Started with ProGet
- Packages: Managing & Tracking
- Feeds Types & Third-Party Packages
- What is a "Feed" in ProGet?
- What is a "Connector" in ProGet?
- NuGet (.NET)
- PowerShell
- Chocolatey (Windows/Machine)
- RubyGems (ruby)
- Visual Studio Extension (.vsix)
- Maven (Java)
- npm (Node.js)
- Bower (JavaScript)
- Debian (Apt)
- Helm (Kubernetes)
- PyPI (Python)
- Conda (Python)
- RPM (Yum)
- Alpine (APK)
- CRAN (R)
- pub (Dart/Flutter)
- Terraform Modules
- Other Feed Types
- Universal Packages & Feeds
- UPack Overview
- Universal Packages
- Virtual Packages
- Tools and Libraries
- Universal Package Registry
- Downloads & Source Code
- Universal Feed API
- Asset Directories & File Storage
- Docker and Containers
- Replication & Feed Mirroring
- Software Composition Analysis (SCA)
- Security and Access Controls
- Cloud Storage (Amazon S3, Azure Blob)
- Administration
- Installation & Upgrading
- API Endpoints & Methods
- Otter
- Getting Started with Otter
- Orchestration & Server Automation
- Connecting to your Servers with Otter
- Collecting & Verifying Configuration
- Drift Remediation / Configuration as Code
- Scripting in Otter
- Configuring for Your Team
- Installation & Upgrading
- Administration & Maintenance
- Reference
- Otter API Reference
- OtterScript Reference
- Built-in Functions & Variables
- Executions
- Files
- General
- JSON
- Linux
- Lists
- Maps
- Math
- PowerShell
- Python
- Servers
- Strings
- XML
- Built-in Operations
- Batch
- Docker
- DotNet
- Files
- Firewall
- General
- Apply-Template
- Collect Debian Packages
- Collect RPM Packages
- Collect-InstalledPackages
- Concatenate-Files
- Copy-Files
- Create-Directory
- Create-File
- Create-Package
- Create-ZipFile
- Delete-Files
- Download-Asset
- Download-Http
- Ensure-Directory
- Ensure-File
- Ensure-HostsEntry
- Ensure-Metadata
- Ensure-Package
- Exec
- Execute Python Script
- Get-Http
- Install-Package
- OSCall
- OSExec
- Post-Http
- Push-PackageFile
- PYCall
- PYEnsure
- Query-Package
- Remediate-Drift
- Rename-File
- Repackage
- Replace-Text
- Send-Email
- Set-FileAttributes
- Set-Variable
- SHEnsure
- Sleep
- Transfer-Files
- Upload-Assets
- Upload-Http
- IIS
- Otter
- PowerShell
- ProGet
- Python
- Registry
- Servers
- Services
- Shell
- Windows
- Installation & Maintenance
- Windows (Inedo Hub)
- What is the Inedo Hub?
- Configuring & Maintaining Inedo Products
- Offline Installation (no Internet access)
- HOWTO: Install on Windows
- HOWTO: Upgrade or Downgrade with the Inedo Hub
- HOWTO: Install Pre-release Product Versions
- HOWTO: Configure Your Inedo Product to Run As a Windows Domain Account
- Silent/Automated Installation Guide
- Legacy (Traditional) Installer
- Linux (Docker)
- Manual Installation
- High Availability & Load Balancing
- LDAP/AD Integration
- IIS & Web Hosting on Windows
- Logging & Analytics
- SAML Authentication
- Upgrading your Inedo Product
- Managing Agents and Servers
- Backing Up & Restoring
- Installation Configuration Files
- SQL Server & Inedo Products
- Windows (Inedo Hub)
- Inedo Agent
- What is the Inedo Agent?
- Installation & Upgrading
- Downloads & Release Notes
- Maintenance & Configuration
- Internal Architecture
- MyInedo
- OtterScript (Execution Engine)
- Reference
- OtterScript
- Inedo Execution Engine
- Operations & Functions
- Text Templating
- Resource Pools
- Runtime Variables
- Advanced Scenarios & Features
- Statements and Blocks
- Romp (Discontinued)
- Using Romp
- Installing, Configuring, and Maintaining
- Romp CLI Reference
- Package Layout
- Downloads & Source Code
- Extensibility
- Inedo SDK
Python (.py) Scripting
As of v3.0.19, Otter can seamlessly integrate with Python, whether that means running your existing scripts across dozens of servers, leveraging scripts built by the community, or a custom combination of both.
Prerequisites
The only prerequisite is to have Python3 installed on a server. Windows and Linux are both supported, and Otter will usually be able to detect its location automatically.
If Python could not be automatically located, you will have to create a server-scoped variable named $PythonPath
in Otter that contains the full path to python (or python.exe on Windows).
Uploading Python Scripts to Otter
The easiest way to execute a Python script in Otter is to start by uploading an existing script. Just click the Add Script button on the Scripts page and select Upload. Your script will then be available to use either directly or from OtterScript using the PYCall
operation.
Executing Inline
If you just want to execute a short Python script, or if you want to use OtterScript variable replacement to build out your script, you can use the PYExec
operation:
PYExec >>print('Hello world from Otter!')>>;
Drift Detection & Remediation
Use PYVerify
to enable detecting invalid server configuration with a Python script.
Example: Python Script to Verify that a File Exists
'''
Verifies that a file exists.
AhParameters:
filePath (text): full path of file to verify
AhConfigKey:
$filePath
AhDesiredValue:
True
AhCurrentValue:
$fileExists
'''
import os;
import os.path;
print(f'Checking to see if {filePath} exists...')
fileExists = os.path.exists(filePath)
if(fileExists):
print(f'{filePath} exists.')
else:
print(f'{filePath} does not exist.')
You can use PYEnsure
to perform verification as with PYVerify
but also add the ability to correct any detected configuration problems.
Example: Python Script to Ensure that a File Exists
'''
Ensures that a file exists.
AhParameters:
filePath (text): full path of the file to ensure
AhExecMode:
execMode
AhConfigKey:
$filePath
AhDesiredValue:
True
AhCurrentValue:
$fileExists
'''
import os;
import os.path;
if(execMode == 'Collect'):
print(f'Collect mode; checking to see if {filePath} exists...')
fileExists = os.path.exists(filePath)
if(fileExists):
print(f'{filePath} exists.')
else:
print(f'{filePath} does not exist.')
else:
print(f'Creating {filePath}...')
os.makedirs(os.path.dirname(filePath), exist_ok=True)
with open(filePath, 'w') as f:
f.write('hello dears')
fileExists = True
print(f'{filePath} created.')
Technical Details
Otter uses the standard Python3 interpreter to execute your scripts. The script is executed using Python's exec
, allowing it to access variables declared as inputs in the AhParameters
section of the docstring, and Otter also hooks into Python's logging system, allowing logging.info/warning/etc
calls in Python to be captured with the appropriate log levels in Otter. Output values are read after exec
returns.