pipeline-eds 0.2.12__tar.gz → 0.2.14__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/PKG-INFO +1 -1
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/pyproject.toml +3 -2
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/src/pipeline/cli.py +36 -23
- pipeline_eds-0.2.14/src/pipeline/install_appdata.py +84 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/src/pipeline/workspace_manager.py +25 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/LICENSE +0 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/README.md +0 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/src/pipeline/__init__.py +0 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/src/pipeline/__main__.py +0 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/src/pipeline/api/__init__.py +0 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/src/pipeline/api/eds.py +0 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/src/pipeline/api/rjn.py +0 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/src/pipeline/api/status_api.py +0 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/src/pipeline/calls.py +0 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/src/pipeline/configrationmanager.py +0 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/src/pipeline/decorators.py +0 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/src/pipeline/env.py +0 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/src/pipeline/environment.py +0 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/src/pipeline/gui_fastapi_plotly_live.py +0 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/src/pipeline/gui_mpl_live.py +0 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/src/pipeline/helpers.py +0 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/src/pipeline/logging_setup.py +0 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/src/pipeline/pastehelpers.py +0 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/src/pipeline/philosophy.py +0 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/src/pipeline/plotbuffer.py +0 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/src/pipeline/points_loader.py +0 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/src/pipeline/queriesmanager.py +0 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/src/pipeline/time_manager.py +0 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/workspaces/default-workspace.toml +0 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/workspaces/eds_to_rjn/__init__.py +0 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/workspaces/eds_to_rjn/code/__init__.py +0 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/workspaces/eds_to_rjn/code/aggregator.py +0 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/workspaces/eds_to_rjn/code/collector.py +0 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/workspaces/eds_to_rjn/code/sanitizer.py +0 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/workspaces/eds_to_rjn/code/storage.py +0 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/workspaces/eds_to_rjn/configurations/config_time.toml +0 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/workspaces/eds_to_rjn/configurations/configuration.toml +0 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/workspaces/eds_to_rjn/exports/README.md +0 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/workspaces/eds_to_rjn/exports/aggregate/README.md +0 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/workspaces/eds_to_rjn/exports/aggregate/live_data - Copy.csv +0 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/workspaces/eds_to_rjn/exports/aggregate/live_data_EFF.csv +0 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/workspaces/eds_to_rjn/exports/aggregate/live_data_INF.csv +0 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/workspaces/eds_to_rjn/exports/export_eds_points_neo.txt +0 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/workspaces/eds_to_rjn/exports/manual_data_load_to_postman_wetwell.csv +0 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/workspaces/eds_to_rjn/exports/manual_data_load_to_postman_wetwell.xlsx +0 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/workspaces/eds_to_rjn/exports/manual_effluent.csv +0 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/workspaces/eds_to_rjn/exports/manual_influent.csv +0 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/workspaces/eds_to_rjn/exports/manual_wetwell.csv +0 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/workspaces/eds_to_rjn/history/time_sample.txt +0 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/workspaces/eds_to_rjn/imports/zdMaxson_idcsD321E_sid11003.toml +0 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/workspaces/eds_to_rjn/imports/zdMaxson_idcsFI8001_sid8528.toml +0 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/workspaces/eds_to_rjn/imports/zdMaxson_idcsM100FI_sid2308.toml +0 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/workspaces/eds_to_rjn/imports/zdMaxson_idcsM310LI_sid2382.toml +0 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/workspaces/eds_to_rjn/queries/default-queries.toml +0 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/workspaces/eds_to_rjn/queries/points-maxson.csv +0 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/workspaces/eds_to_rjn/queries/points-stiles.csv +0 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/workspaces/eds_to_rjn/queries/timestamps_success.json +0 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/workspaces/eds_to_rjn/scripts/__init__.py +0 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/workspaces/eds_to_rjn/scripts/daemon_runner.py +0 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/workspaces/eds_to_rjn/secrets/README.md +0 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/workspaces/eds_to_rjn/secrets/secrets-example.yaml +0 -0
- {pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/workspaces/eds_to_termux/..txt +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
[tool.poetry]
|
2
2
|
name = "pipeline-eds"
|
3
|
-
version = "0.2.
|
3
|
+
version = "0.2.14"
|
4
4
|
description = "The official API pipeline library for mulch-based projects. Key target: Emerson Ovation EDS REST API."
|
5
5
|
authors = ["George Clayton Bennett <george.bennett@memphistn.gov>"]
|
6
6
|
license = "BSD-3"
|
@@ -18,7 +18,8 @@ repository = "https://github.com/city-of-memphis-wastewater/pipeline"
|
|
18
18
|
#collector = "pipeline.collector:main"
|
19
19
|
#eds-client = "pipeline.api.eds:main"
|
20
20
|
#rjn-client = "pipeline.api.rjn:main"
|
21
|
-
pipeline = "pipeline.cli:app" # for installation of pipeline as a
|
21
|
+
pipeline = "pipeline.cli:app" # for installation of pipeline as a CLI. Ex: pipeline trend M100FI -s June3 -f June17
|
22
|
+
eds = "pipeline.cli:app" # alias eds for pipeline CLI
|
22
23
|
|
23
24
|
|
24
25
|
[tool.pytest.ini_options]
|
@@ -1,9 +1,4 @@
|
|
1
1
|
'''
|
2
|
-
import typer
|
3
|
-
from pathlib import Path
|
4
|
-
|
5
|
-
app = typer.Typer()
|
6
|
-
|
7
2
|
@app.command()
|
8
3
|
def list_workspaces(workspaces_dir: Path = Path("workspaces")):
|
9
4
|
"""List valid mulch workspaces in the given directory."""
|
@@ -14,37 +9,52 @@ def list_workspaces(workspaces_dir: Path = Path("workspaces")):
|
|
14
9
|
if path.is_dir() and (path / ".mulch").is_dir():
|
15
10
|
typer.echo(f"🪴 {path.name}")
|
16
11
|
|
17
|
-
@app.command()
|
18
|
-
def list_mulch_folders(start: Path = Path(".")):
|
19
|
-
"""Recursively find folders containing a .mulch/ directory."""
|
20
|
-
for path in start.rglob(".mulch"):
|
21
|
-
typer.echo(f"📁 {path.parent}")
|
22
|
-
|
23
|
-
@app.command()
|
24
|
-
def inspect(workspace: Path):
|
25
|
-
"""Show scaffold or metadata info from a workspace."""
|
26
|
-
metadata = workspace / ".mulch" / "mulch-scaffold.json"
|
27
|
-
if metadata.exists():
|
28
|
-
typer.echo(f"🔍 {workspace.name}: {metadata}")
|
29
|
-
typer.echo(metadata.read_text())
|
30
|
-
else:
|
31
|
-
typer.echo(f"No scaffold found in {workspace}")
|
32
12
|
'''
|
33
|
-
# src/pipeline/cli.py
|
34
|
-
|
35
13
|
import typer
|
36
14
|
import importlib
|
37
15
|
from pathlib import Path
|
16
|
+
from importlib.metadata import version, PackageNotFoundError
|
38
17
|
|
39
18
|
from pipeline.env import SecretConfig
|
40
19
|
#from pipeline.helpers import setup_logging
|
41
20
|
from pipeline.workspace_manager import WorkspaceManager
|
42
21
|
|
22
|
+
### Versioning
|
23
|
+
CLI_APP_NAME = "pipeline"
|
24
|
+
def print_version(value: bool):
|
25
|
+
if value:
|
26
|
+
try:
|
27
|
+
typer.secho(f"{CLI_APP_NAME} {PIPELINE_VERSION}",fg=typer.colors.GREEN, bold=True)
|
28
|
+
except PackageNotFoundError:
|
29
|
+
typer.echo("Version info not found")
|
30
|
+
raise typer.Exit()
|
31
|
+
try:
|
32
|
+
PIPELINE_VERSION = version(CLI_APP_NAME)
|
33
|
+
__version__ = version({CLI_APP_NAME})
|
34
|
+
except PackageNotFoundError:
|
35
|
+
PIPELINE_VERSION = "unknown"
|
36
|
+
|
37
|
+
try:
|
38
|
+
from importlib.metadata import version
|
39
|
+
__version__ = version({CLI_APP_NAME})
|
40
|
+
except PackageNotFoundError:
|
41
|
+
# fallback if running from source
|
42
|
+
try:
|
43
|
+
with open(Path(__file__).parent / "VERSION") as f:
|
44
|
+
__version__ = f.read().strip()
|
45
|
+
except FileNotFoundError:
|
46
|
+
__version__ = "dev"
|
47
|
+
|
48
|
+
### Pipeline CLI
|
49
|
+
|
43
50
|
app = typer.Typer(help="CLI for running pipeline workspaces.")
|
44
51
|
|
45
52
|
|
46
53
|
@app.callback(invoke_without_command=True)
|
47
|
-
def main(
|
54
|
+
def main(
|
55
|
+
ctx: typer.Context,
|
56
|
+
version: bool = typer.Option(None, "--version", callback=lambda v: print_version(v), is_eager=True, help="Show the version and exit.")
|
57
|
+
):
|
48
58
|
"""
|
49
59
|
Pipeline CLI – run workspaces built on the pipeline framework.
|
50
60
|
"""
|
@@ -52,6 +62,7 @@ def main(ctx: typer.Context):
|
|
52
62
|
typer.echo(ctx.get_help())
|
53
63
|
raise typer.Exit()
|
54
64
|
|
65
|
+
|
55
66
|
@app.command()
|
56
67
|
def run(
|
57
68
|
workspace: str = typer.Option(None, help="Workspace to run"),
|
@@ -104,6 +115,8 @@ def trend(
|
|
104
115
|
from pipeline.plotbuffer import PlotBuffer
|
105
116
|
from pipeline import gui_fastapi_plotly_live
|
106
117
|
from pipeline import environment
|
118
|
+
from pipeline.workspace_manager import WorkspaceManager
|
119
|
+
ws_dir = WorkspaceManager.ensure_workspace()
|
107
120
|
|
108
121
|
# must set up %appdata for pip/x installation. Use mulch or yeoman for this. And have a secrets filler.
|
109
122
|
if workspace is None:
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# install_appdata.py
|
2
|
+
import typer
|
3
|
+
from pathlib import Path
|
4
|
+
import sys
|
5
|
+
import os
|
6
|
+
import shutil
|
7
|
+
|
8
|
+
app = typer.Typer(help="Manage mulch-like pipeline workspace installation")
|
9
|
+
|
10
|
+
def setup():
|
11
|
+
platform = sys.platform
|
12
|
+
if platform.startswith("win"):
|
13
|
+
from mulch import reg_winreg
|
14
|
+
# Always build LocalAppData mulch folder first
|
15
|
+
|
16
|
+
# Copy files
|
17
|
+
source_dir = Path(__file__).parent # this is src/mulch/scripts/install
|
18
|
+
target_dir = Path(os.environ['LOCALAPPDATA']) / "pipeline"
|
19
|
+
target_dir.mkdir(parents=True, exist_ok=True)
|
20
|
+
|
21
|
+
copy_mulch_installation_files(source_dir, target_dir)
|
22
|
+
|
23
|
+
# Registry
|
24
|
+
reg_winreg.call()
|
25
|
+
reg_winreg.verify_registry() # deterministic check
|
26
|
+
|
27
|
+
print("Mulch context menu installed successfully.")
|
28
|
+
|
29
|
+
elif platform.startswith("linux"):
|
30
|
+
thunar_action_dir = Path.home() / ".local/share/file-manager/actions"
|
31
|
+
thunar_action_dir.mkdir(parents=True, exist_ok=True)
|
32
|
+
|
33
|
+
menu_items = [
|
34
|
+
("mulch-workspace.desktop", "mulch workspace"),
|
35
|
+
("mulch-seed.desktop", "mulch seed"),
|
36
|
+
]
|
37
|
+
|
38
|
+
for filename, label in menu_items:
|
39
|
+
src = Path(__file__).parent / filename
|
40
|
+
dest = thunar_action_dir / filename
|
41
|
+
if src.exists():
|
42
|
+
# Use copy2 to preserve metadata
|
43
|
+
shutil.copy2(src, dest)
|
44
|
+
os.chmod(dest, 0o755)
|
45
|
+
print(f"Installed `{label}` context menu item to {dest}")
|
46
|
+
else:
|
47
|
+
print(f"Skipping `{label}` context menu installation (no .desktop file found).")
|
48
|
+
|
49
|
+
elif platform == "darwin":
|
50
|
+
print("macOS detected: please implement context menu setup via Automator or Finder Service")
|
51
|
+
# You can extend this with AppleScript or Automator commands here
|
52
|
+
else:
|
53
|
+
raise RuntimeError(f"Unsupported platform for setup: {platform}")
|
54
|
+
|
55
|
+
def copy_mulch_installation_files(source_dir, target_dir):
|
56
|
+
required_files = [
|
57
|
+
"call-mulch-workspace.ps1",
|
58
|
+
"mulch-workspace.ps1",
|
59
|
+
"call-mulch-seed.ps1",
|
60
|
+
"mulch-seed.ps1",
|
61
|
+
"mulch-icon.ico",
|
62
|
+
".mulchvision"
|
63
|
+
]
|
64
|
+
missing_files = []
|
65
|
+
for f in required_files:
|
66
|
+
src = source_dir / f
|
67
|
+
if src.exists():
|
68
|
+
shutil.copy2(src, target_dir)
|
69
|
+
print(f"Copied {f} to {target_dir}")
|
70
|
+
else:
|
71
|
+
missing_files.append(f)
|
72
|
+
|
73
|
+
if missing_files:
|
74
|
+
raise FileNotFoundError(
|
75
|
+
f"Missing required files in {source_dir}: {', '.join(missing_files)}"
|
76
|
+
)
|
77
|
+
|
78
|
+
@app.command()
|
79
|
+
def install_appdata():
|
80
|
+
"""Install the mulch workspace and mulch seed right-click context menu items."""
|
81
|
+
setup()
|
82
|
+
|
83
|
+
if __name__ == "__main__":
|
84
|
+
app()
|
@@ -26,6 +26,8 @@ class WorkspaceManager:
|
|
26
26
|
SECRETS_YAML_FILE_NAME ='secrets.yaml'
|
27
27
|
SECRETS_EXAMPLE_YAML_FILE_NAME ='secrets-example.yaml'
|
28
28
|
DEFAULT_WORKSPACE_TOML_FILE_NAME = 'default-workspace.toml'
|
29
|
+
APP_NAME = "pipeline"
|
30
|
+
|
29
31
|
TIMESTAMPS_JSON_FILE_NAME = 'timestamps_success.json'
|
30
32
|
ROOT_DIR = Path(__file__).resolve().parents[2] # root directory
|
31
33
|
|
@@ -230,6 +232,29 @@ class WorkspaceManager:
|
|
230
232
|
def name(self):
|
231
233
|
return self.workspace_name
|
232
234
|
|
235
|
+
@classmethod
|
236
|
+
def get_appdata_dir(cls) -> Path:
|
237
|
+
"""Return platform-appropriate appdata folder."""
|
238
|
+
if os.name == "nt": # Windows
|
239
|
+
base = Path(os.getenv("APPDATA", Path.home() / "AppData" / "Roaming"))
|
240
|
+
elif os.name == "posix" and "ANDROID_ROOT" in os.environ: # Termux
|
241
|
+
base = Path.home() / ".local" / "share"
|
242
|
+
else: # macOS/Linux
|
243
|
+
base = Path(os.getenv("XDG_DATA_HOME", Path.home() / ".local" / "share"))
|
244
|
+
return base / cls.APP_NAME
|
245
|
+
|
246
|
+
@classmethod
|
247
|
+
def ensure_workspace(cls) -> Path:
|
248
|
+
"""Create workspace folder and default toml if missing."""
|
249
|
+
workspaces_dir = cls.get_appdata_dir() / "workspaces"
|
250
|
+
workspaces_dir.mkdir(parents=True, exist_ok=True)
|
251
|
+
|
252
|
+
default_file = workspaces_dir / cls.DEFAULT_WORKSPACE_TOML_FILE_NAME
|
253
|
+
if not default_file.exists():
|
254
|
+
default_file.write_text("# Default workspace config\n")
|
255
|
+
return workspaces_dir
|
256
|
+
|
257
|
+
|
233
258
|
def establish_default_workspace():
|
234
259
|
workspace_name = WorkspaceManager.identify_default_workspace_name()
|
235
260
|
logging.info(f"workspace_name = {workspace_name}")
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/workspaces/eds_to_rjn/configurations/config_time.toml
RENAMED
File without changes
|
{pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/workspaces/eds_to_rjn/configurations/configuration.toml
RENAMED
File without changes
|
File without changes
|
{pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/workspaces/eds_to_rjn/exports/aggregate/README.md
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/workspaces/eds_to_rjn/exports/export_eds_points_neo.txt
RENAMED
File without changes
|
File without changes
|
File without changes
|
{pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/workspaces/eds_to_rjn/exports/manual_effluent.csv
RENAMED
File without changes
|
{pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/workspaces/eds_to_rjn/exports/manual_influent.csv
RENAMED
File without changes
|
{pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/workspaces/eds_to_rjn/exports/manual_wetwell.csv
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/workspaces/eds_to_rjn/queries/default-queries.toml
RENAMED
File without changes
|
File without changes
|
File without changes
|
{pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/workspaces/eds_to_rjn/queries/timestamps_success.json
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{pipeline_eds-0.2.12 → pipeline_eds-0.2.14}/workspaces/eds_to_rjn/secrets/secrets-example.yaml
RENAMED
File without changes
|
File without changes
|