Source code for duck.processes

"""
Module for retrieving or saving all processes created by Duck.

Attributes:
- `set_main_pid`: Saves the main application process ID in json file.

Notes:
- When opening a file, an exclusive lock is acquired to avoid race conditions.
	
Process JSON Format:

```json
{
	"process-name": {
	    "id": "xxx",
	    "other-data": "xxx"
    },
	"another-process": {
	    "id": "xxx",
	}
}
```
"""
import os
import json

from duck.settings import SETTINGS
from duck.utils.filelock import open_and_lock
from duck.utils.path import joinpaths


BASE_DIR = str(SETTINGS["BASE_DIR"]).rstrip("/")
FILENAME = ".processes.json"


[docs] def set_process_data(name: str, data: dict, clear_existing_data=False) -> str: """ Saves the process data in json file. Returns: str: The json file in which the process data was saved. """ json_file = joinpaths(BASE_DIR, FILENAME) old_data = {} mode = "w" if not "pid" in data: raise KeyError("Key `pid` required in data.") if os.path.isfile(json_file): # file exists if not clear_existing_data: with open_and_lock(json_file, "r") as json_fd: old_data = json.load(json_fd) else: mode = "a" # mode to create new file if old_data: old_process_data = old_data.get(name) if old_process_data: old_process_data.update(data) data = old_process_data old_data[name] = data # save new process data with open_and_lock(json_file, mode) as json_fd: json.dump(old_data, json_fd) return json_file
[docs] def get_process_data(name) -> dict: """ Retrieves the process data from json file. """ json_file = joinpaths(BASE_DIR, FILENAME) old_data = {} if not os.path.isfile(json_file): # file doesn't exist raise KeyError(f"No record found for process with name '{name}' ") with open_and_lock(json_file, "r") as json_fd: try: old_data = json.load(json_fd) except json.JSONDecodeError: pass if not name in old_data.keys(): raise KeyError(f"No record found for process with name '{name}' ") return old_data.get(name)
[docs] def get_all_processes_data() -> dict: """ Returns all processes data saved in json file. """ json_file = joinpaths(BASE_DIR, FILENAME) if not os.path.isfile(json_file): # file doesn't exist return {} with open_and_lock(json_file, "r") as json_fd: old_data = json.load(json_fd) return old_data
[docs] def clear_processes_data(): """ Clears all processes data in json file. """ json_file = joinpaths(BASE_DIR, FILENAME) if os.path.isfile(json_file): # file exists with open_and_lock(json_file, "w") as json_fd: json.dump({}, json_fd)
[docs] def delete_process_data(name: str) -> dict: """ Deletes the process data in json file. Returns: dict: The deleted process data """ json_file = joinpaths(BASE_DIR, FILENAME) if os.path.isfile(json_file): # file exists with open_and_lock(json_file, "r") as json_fd: old_data = json.load(json_fd) if name not in old_data.keys(): raise KeyError( f"Deletion failed: No record found for process with name '{name}'" ) data = old_data.pop(name) with open_and_lock(json_file, "w") as json_fd: json.dump(old_data, json_fd) return data