feat: add psagentai agent with deployment and configuration
Initial project setup including the main agent script, configuration files, profile JSON state, systemd service unit, startup script, deployment documentation, and Python dependencies. Includes .env, venv/, and __pycache__/ which should likely be excluded via .gitignore to avoid committing secrets and artifacts.
This commit is contained in:
@@ -0,0 +1,154 @@
|
||||
"""
|
||||
`rich.progress` decorator for iterators.
|
||||
|
||||
Usage:
|
||||
>>> from tqdm.rich import trange, tqdm
|
||||
>>> for i in trange(10):
|
||||
... ...
|
||||
"""
|
||||
from warnings import warn
|
||||
|
||||
from rich.progress import (
|
||||
BarColumn, Progress, ProgressColumn, Text, TimeElapsedColumn, TimeRemainingColumn, filesize)
|
||||
|
||||
from .std import TqdmExperimentalWarning
|
||||
from .std import tqdm as std_tqdm
|
||||
|
||||
__author__ = {"github.com/": ["casperdcl"]}
|
||||
__all__ = ['tqdm_rich', 'trrange', 'tqdm', 'trange']
|
||||
|
||||
|
||||
class FractionColumn(ProgressColumn):
|
||||
"""Renders completed/total, e.g. '0.5/2.3 G'."""
|
||||
def __init__(self, unit_scale=False, unit_divisor=1000):
|
||||
self.unit_scale = unit_scale
|
||||
self.unit_divisor = unit_divisor
|
||||
super().__init__()
|
||||
|
||||
def render(self, task):
|
||||
"""Calculate common unit for completed and total."""
|
||||
completed = int(task.completed)
|
||||
# total is None when the iterable has no length (e.g. a generator)
|
||||
total = int(task.total) if task.total is not None else None
|
||||
base = total if total is not None else completed
|
||||
if self.unit_scale:
|
||||
unit, suffix = filesize.pick_unit_and_suffix(
|
||||
base,
|
||||
["", "K", "M", "G", "T", "P", "E", "Z", "Y"],
|
||||
self.unit_divisor,
|
||||
)
|
||||
else:
|
||||
unit, suffix = filesize.pick_unit_and_suffix(base, [""], 1)
|
||||
precision = 0 if unit == 1 else 1
|
||||
total_str = f"{total/unit:,.{precision}f}" if total is not None else "?"
|
||||
return Text(
|
||||
f"{completed/unit:,.{precision}f}/{total_str} {suffix}",
|
||||
style="progress.download")
|
||||
|
||||
|
||||
class RateColumn(ProgressColumn):
|
||||
"""Renders human readable transfer speed."""
|
||||
def __init__(self, unit="", unit_scale=False, unit_divisor=1000):
|
||||
self.unit = unit
|
||||
self.unit_scale = unit_scale
|
||||
self.unit_divisor = unit_divisor
|
||||
super().__init__()
|
||||
|
||||
def render(self, task):
|
||||
"""Show data transfer speed."""
|
||||
speed = task.speed
|
||||
if speed is None:
|
||||
return Text(f"? {self.unit}/s", style="progress.data.speed")
|
||||
if self.unit_scale:
|
||||
unit, suffix = filesize.pick_unit_and_suffix(
|
||||
speed,
|
||||
["", "K", "M", "G", "T", "P", "E", "Z", "Y"],
|
||||
self.unit_divisor,
|
||||
)
|
||||
else:
|
||||
unit, suffix = filesize.pick_unit_and_suffix(speed, [""], 1)
|
||||
precision = 0 if unit == 1 else 1
|
||||
return Text(f"{speed/unit:,.{precision}f} {suffix}{self.unit}/s",
|
||||
style="progress.data.speed")
|
||||
|
||||
|
||||
class tqdm_rich(std_tqdm): # pragma: no cover
|
||||
"""Experimental rich.progress GUI version of tqdm!"""
|
||||
# TODO: @classmethod: write()?
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""
|
||||
This class accepts the following parameters *in addition* to
|
||||
the parameters accepted by `tqdm`.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
progress : tuple, optional
|
||||
arguments for `rich.progress.Progress()`.
|
||||
options : dict, optional
|
||||
keyword arguments for `rich.progress.Progress()`.
|
||||
"""
|
||||
kwargs = kwargs.copy()
|
||||
kwargs['gui'] = True
|
||||
# convert disable = None to False
|
||||
kwargs['disable'] = bool(kwargs.get('disable', False))
|
||||
progress = kwargs.pop('progress', None)
|
||||
options = kwargs.pop('options', {}).copy()
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
if self.disable:
|
||||
return
|
||||
|
||||
warn("rich is experimental/alpha", TqdmExperimentalWarning, stacklevel=2)
|
||||
d = self.format_dict
|
||||
if progress is None:
|
||||
progress = (
|
||||
"[progress.description]{task.description}"
|
||||
"[progress.percentage]{task.percentage:>4.0f}%",
|
||||
BarColumn(bar_width=None),
|
||||
FractionColumn(
|
||||
unit_scale=d['unit_scale'], unit_divisor=d['unit_divisor']),
|
||||
"[", TimeElapsedColumn(), "<", TimeRemainingColumn(),
|
||||
",", RateColumn(unit=d['unit'], unit_scale=d['unit_scale'],
|
||||
unit_divisor=d['unit_divisor']), "]"
|
||||
)
|
||||
options.setdefault('transient', not self.leave)
|
||||
self._prog = Progress(*progress, **options)
|
||||
self._prog.__enter__()
|
||||
self._task_id = self._prog.add_task(self.desc or "", **d)
|
||||
|
||||
def close(self):
|
||||
if self.disable:
|
||||
return
|
||||
self.display() # print 100%, vis #1306
|
||||
super().close()
|
||||
self._prog.__exit__(None, None, None)
|
||||
|
||||
def clear(self, *_, **__):
|
||||
pass
|
||||
|
||||
def display(self, *_, **__):
|
||||
if not hasattr(self, '_task_id'):
|
||||
return
|
||||
self._prog.update(self._task_id, completed=self.n, description=self.desc)
|
||||
|
||||
def reset(self, total=None):
|
||||
"""
|
||||
Resets to 0 iterations for repeated use.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
total : int or float, optional. Total to use for the new bar.
|
||||
"""
|
||||
if hasattr(self, '_prog'):
|
||||
self._prog.reset(total=total)
|
||||
super().reset(total=total)
|
||||
|
||||
|
||||
def trrange(*args, **kwargs):
|
||||
"""Shortcut for `tqdm.rich.tqdm(range(*args), **kwargs)`."""
|
||||
return tqdm_rich(range(*args), **kwargs)
|
||||
|
||||
|
||||
# Aliases
|
||||
tqdm = tqdm_rich
|
||||
trange = trrange
|
||||
Reference in New Issue
Block a user