Using Python Scripts in Home Assistant
Home Assistant supports several ways to write automations and custom code in Python. This guide explains the built-in python_scripts integration, as well as two popular advanced alternatives: AppDaemon and PyScript. We'll focus on practical, up-to-date advice for beginners - while highlighting strengths, limits, and best practices for each option.
1. Built-in Python Scripts (python_scripts integration)
Python scripts are a lightweight, sandboxed way to extend Home Assistant with simple Python logic. This feature is built into every Home Assistant install (OS, Supervised, Container, or Core) - no add-ons required.
- Supports: All install types. No extra dependencies.
- Best for: Quick, simple logic that's more powerful than YAML but doesn't require full-blown custom components.
- Not for: Long-running code, web access, or advanced Python libraries.
How to Enable Python Scripts
- Add python_script: to your configuration.yaml
python_script: - Create the scripts folder:
In your HA config directory (often /config/), create a folder called python_scripts. - Write your scripts:
Add .py files to python_scripts/. Each file becomes a callable script in HA. - Restart or reload:
Restart HA, or use the python_script.reload action in Developer Tools after adding/changing scripts.
Script Structure & Restrictions
-
Sandboxed: No
importstatements, no file/network access, and only a subset of Python is available. - Available variables:
hass: Control Home Assistant (set states, call services, fire events).data: Dictionary of arguments passed when calling the script.logger: Log messages (logger.info(),logger.warning(),logger.error()).output: Dictionary for returning values to automations (usingresponse_variablein scripts/automations).- Basic Python built-ins (
min,max,all,any,enumerate) and limitedtime/datetime.
-
No blocking or slow operations: Scripts must execute quickly and cannot use
sleepor long loops.
How to Call a Python Script
-
Each script becomes a service:
python_script.<filename>.
Example: If you createhello.py, callpython_script.hellofrom automations, scripts, or the Developer Tools > Services page. -
Pass arguments: Use the
data:field in your service call. These appear in your script as thedatadict. -
Returning values: Place results in the
outputdict. In automations/scripts, you can capture this using theresponse_variablefeature (added in recent HA releases).
Example: Hello World Python Script
Save this as python_scripts/hello.py:
name = data.get("name", "World")
logger.info(f"Hello, {name}!")
output["message"] = f"Hello, {name}!" - Call this via
python_script.hellowithdata: { name: "Alice" }. - The log will show "Hello, Alice!", and the output variable
messagewill be set to that value.
Making Scripts Friendly in the UI (services.yaml)
You can add a services.yaml in python_scripts/ to give your scripts nice names and argument descriptions in the UI. For details, see the HA docs.
Best Practices
- Keep scripts short and focused - use one script per logical task.
- Always use
logger.info()for debugging (make surelogger:is set to showinfoinconfiguration.yaml). - Use
data.get("param")for safe argument access. - Test scripts via Developer Tools before using in automations.
Limitations & Security
- No third-party libraries or arbitrary Python imports allowed.
- No file/network/database access - scripts can only interact with HA through
hass. - Scripts are atomic and quick - no persistent background jobs or blocking code.
- All errors are logged; make sure to check
home-assistant.logif scripts fail. - No plans to deprecate, but for complex logic, see below for alternatives.
2. AppDaemon (Advanced, Full Python Environment)
AppDaemon is a separate, full-featured Python environment for Home Assistant automations. It is perfect for complex automations, scheduling, and advanced use cases, but is more involved to set up than python_scripts.
- Supports: All platforms (Linux, Windows, etc.). Easy add-on for HA OS/Supervised, or install via Docker/pip elsewhere.
- Best for: Large or complex automations, or when you want to use third-party libraries and full Python.
- Not for: Small, one-off scripts or users who don't want to manage a separate service.
Setup Overview
- HA OS/Supervised: Install the AppDaemon add-on from the Community Add-ons store. Configure with your HA URL and token.
- Docker: Use the
acockburn/appdaemonimage. Mount a config folder and setHA_URLandTOKENas environment variables. - pip: Install in a separate Python environment (
pip install appdaemon), not in the same venv as HA.
Writing AppDaemon Apps
- Each app is a Python class extending
appdaemon.plugins.hass.Hass. - Define an
initialize()method to set up listeners or schedules. - Use
self.listen_state(),self.run_daily(), etc., to trigger your logic. - Call services and control entities with methods like
self.turn_on(),self.call_service(), etc.
AppDaemon Example: Scheduled Porch Light
from appdaemon.plugins.hass import Hass
class NightLight(Hass):
def initialize(self):
self.run_daily(self.run_lights, "19:00:00")
def run_lights(self, kwargs):
self.log("Turning on porch light")
self.turn_on("light.porch")
Best Practices & Security
- Each app runs in full Python - no sandbox! Be careful with untrusted code.
- Test and log thoroughly using
self.log(). - Avoid long blocking operations (like
time.sleep()in callbacks). - Keep secrets (like tokens) in AppDaemon's config, not in code.
3. PyScript (Custom Integration, Install via HACS)
PyScript is a modern, flexible way to write Python automations in Home Assistant. It supports more of Python, including modules, triggers, and decorators, but runs inside Home Assistant (not as a separate service). Install it from HACS or manually.
- Supports: Any HA install where you can use HACS (OS, Supervised, Container, or Core).
- Best for: More advanced Python automations, combining the convenience of in-HA code with most of Python's features.
- Not for: Users who want only built-in features, or those uncomfortable managing custom integrations.
Setup Overview
- Install PyScript from HACS > Integrations (or copy from GitHub).
- Add
pyscript:to yourconfiguration.yamland restart HA. - Create a
pyscript/folder in your config directory. Place.pyscripts here. - PyScript auto-reloads scripts on change.
Writing PyScript Scripts
- Define Python functions with the
@servicedecorator - these become callable HA services (pyscript.<function_name>). - Use
@state_trigger,@time_trigger, or@event_triggerdecorators to run functions automatically when states, times, or events change. - You can import your own modules from
pyscript/modules/. By default, most Python modules are restricted for safety - but you can enable them in config if you trust your code. - Supports async code,
task.sleep()for delays, and more.
Example: Motion-Triggered Hall Light
@state_trigger("sensor.motion == 'on'")
def motion_light():
light.turn_on(entity_id="light.hallway", brightness=200)
task.sleep(300)
light.turn_off(entity_id="light.hallway")
Best Practices & Security
- Use
log.info()for debugging. - Keep scripts organized with functions and submodules.
- Limit
allow_all_importsunless you fully trust your code (this prevents scripts from accessing the filesystem or system commands). - Use
requirements.txtto install extra Python libraries needed by your scripts (PyScript can auto-install these if allowed).
Which Should You Use?
- python_scripts: Best for quick, simple logic - minimal setup, but limited power.
- AppDaemon: Great for large, complex automations, especially those requiring third-party Python libraries, scheduling, or background jobs.
- PyScript: A good "middle ground" - write more expressive automations in Python, right inside Home Assistant, with modern features and HACS installation.
For most beginners, start with python_scripts to get a feel for automations, then move to PyScript or AppDaemon as your needs grow.