Skip to main content

PyLiveDev

pypi version MIT License

Python Live Development tool.

Description

I created PyLiveDev because I work a lot in the microservices/REST space and found constantly having to run/restart services while developing and keeping track of multiple logs in separate windows, to be, quite frankly, a pain in my ass.

Inspired by live updates while using create-react-app in development, I wanted to see if there was a way I could make a python program run multiple services and keep track of the files imported. This way if anything changed it could automatically restart those services and save time while developing. As a bonus, piping all stdout/stderr to one screen so I could immediately see if I wrote bad code or was returning something unexpected.

It works by you creating a JSON configuration file called .pylivedev in the root of your python project and adding an Object member for each unique process, then running pylivedev from the root of your project.

Install

foo@bar:~$ pip install pylivedev

Warning

If you are using PyLiveDev on a Linux kernel 2.6+, you may at some point run into an issue where you see red errors like the following:

File "some/path.py" could not be tracked: (24, 'inotify instance limit reached')

File "some/path.py" could not be tracked: (28, 'inotify watch limit reached')

This is due to limits in an underlying library. When this happens adjust the following settings in your /etc/sysctl.conf file (will require root access):

fs.inotify.max_user_instances=256
fs.inotify.max_user_watches=16384

The defaults are 128 and 8192, so adjust accordingly then reboot. Increase as necessary until PyLiveDev stops reporting issues tracking files.

Note, that if you use vscode, it will try to track every single file in a project, be aware of how many files/folders in your projects, and make sure you hide things like node_modules if you're using node in your projects. Many node based auto-build development systems, create-react-app, vite, nextjs, and others will also watch files, so it's a common problem for developers.

Run

foo@bar:~$ pylivedev

Configuration

{
	"rest": {
		"command": "rest",
		"mode": "module",
		"tracked": false,
		"python": "/venv/my_project/bin/python",
		"arguments": ["-v"],
		"additional_files": ["config.json"],
		"unbuffered": true,
		"verbose": false
	}
}
Name Type Mandatory Description
command String Yes The name of the script or module to run as a process. e.g. "services.rest", "main.py"
mode "module" | "script" | "exe" No Tells pylivedev whether you are trying to run a stand alone script, a python module, or a binary (or non-parsable) application. Defaults to "script".
tracked Boolean No When true, proccess is tracked via file changes. Use false for static or external modules. Defaults to true. Will be ignored if mode is set to "exe".
python String No The full path to the python intepreter to use to run your process. Defaults to the python interpreter running pylivedev.
arguments String[] No An array of additional arguments passed to the process.
additional_files String[] No An array of additional files to be watched/observed for changes.
unbuffered Boolean No Run the processed unbuffered, defaults to true.
verbose Boolean No Runs pylivedev in verbose mode to give more information on what is happening, what imports were found, what files have changed, etc. Defaults to false.

Defaults

You can also use the special __default__ member to store values that will be the same across processes. Anything in the proccess config will always overwrite the defaults.

{
	"__default__": {
		"python": "/venv/my_project/bin/python",
		"mode": "module",
		"additional_files": ["config.json"],
	},

	"main": {
		"command": "nodes.rest.main"
	},

	"admin": {
		"command": "nodes.rest.admin"
	},

	"external": {
		"command": "nodes.external"
	},

	"websocket": {
		"command": "daemons.websocket"
	}
}

The above would work for a file structure like the following

my_project/
|-- daemons/
	|-- __init__.py
	|-- websocket.py
|-- nodes/
	|-- rest/
		|-- __init__.py
		|-- admin.py
		|-- main.py
	|-- __init__.py
	|-- external.py
|-- records/
	|-- __init__.py
|-- .pylivedev
|-- config.json

If, for example, nodes/rest/main.py imported the following:

from time import time
from . import Rest
from records import User

class Main(Rest):
	pass

PyLiveDev would end up with the following list of files to watch/observe for changes

  • config.json
  • nodes/rest/main.py
  • nodes/rest/__init__.py
  • records/__init__.py

Any time any of these files is saved/changed on the system, PyLiveDev would shut down the "main" process, re-parse the module looking for imports, and then restart the process.

Note system and pip imports will not be added to the list, like time in the above example. In most cases system files don't change often and it would waste resources to watch them. If you update a pip library, or update python, it's best to shut down PyLiveDev [CRTL-C] and restart it.

Metadata

Release files for pylivedev 1.2.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pylivedev 1.2.2
File Size Uploaded Provenance Actions
pylivedev-1.2.2.tar.gz 15.0 kB Without provenance Details for pylivedev-1.2.2.tar.gz

Release files / pylivedev-1.2.2.tar.gz

Download URL pylivedev-1.2.2.tar.gz
Size 15.0 kB
Tags Source
SHA-256 checksum
How to use checksums
c85b66534133dc3bb68f17c52706ef7642b825807ac1a23df0034644c745be1f
BLAKE2b-256 checksum
How to use checksums
14e96d2c4346479354566f7e253d1a9abcfda6553bfe63fbb6f65ca46019cf5b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.8.0 colorama/0.4.4 importlib-metadata/4.6.4 keyring/23.5.0 pkginfo/1.8.2 readme-renderer/34.0 requests-toolbelt/0.9.1 requests/2.31.0 rfc3986/1.5.0 tqdm/4.65.0 urllib3/1.26.5 CPython/3.10.12

Security for pylivedev 1.2.2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page