wpipe-mcp 0.1.0__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.
- wpipe_mcp-0.1.0/LICENSE +21 -0
- wpipe_mcp-0.1.0/PKG-INFO +9 -0
- wpipe_mcp-0.1.0/README.md +61 -0
- wpipe_mcp-0.1.0/pyproject.toml +16 -0
- wpipe_mcp-0.1.0/setup.cfg +4 -0
- wpipe_mcp-0.1.0/src/__init__.py +1 -0
- wpipe_mcp-0.1.0/src/wpipe_mcp/__init__.py +1 -0
- wpipe_mcp-0.1.0/src/wpipe_mcp/catalog.py +97 -0
- wpipe_mcp-0.1.0/src/wpipe_mcp/server.py +156 -0
- wpipe_mcp-0.1.0/src/wpipe_mcp/templates.py +86 -0
- wpipe_mcp-0.1.0/src/wpipe_mcp.egg-info/PKG-INFO +9 -0
- wpipe_mcp-0.1.0/src/wpipe_mcp.egg-info/SOURCES.txt +14 -0
- wpipe_mcp-0.1.0/src/wpipe_mcp.egg-info/dependency_links.txt +1 -0
- wpipe_mcp-0.1.0/src/wpipe_mcp.egg-info/entry_points.txt +2 -0
- wpipe_mcp-0.1.0/src/wpipe_mcp.egg-info/requires.txt +3 -0
- wpipe_mcp-0.1.0/src/wpipe_mcp.egg-info/top_level.txt +2 -0
wpipe_mcp-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 William Rodriguez
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
wpipe_mcp-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# 🦅 wpipe-mcp
|
|
2
|
+
|
|
3
|
+
[](https://github.com/wisrovi/wpipe-mcp)
|
|
4
|
+
[](LICENSE)
|
|
5
|
+
[](https://modelcontextprotocol.io)
|
|
6
|
+
|
|
7
|
+
**Transform your AI Agents into expert WPipe Architects.**
|
|
8
|
+
|
|
9
|
+
`wpipe-mcp` is a professional Model Context Protocol (MCP) server that bridges the gap between AI Agents (Claude, Gemini, OpenCode) and the **wisrovi SUITE**. It empowers agents to search, design, and deploy high-performance pipelines following industry-standard patterns.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## ✨ Key Features
|
|
14
|
+
|
|
15
|
+
- **🔍 Expert Catalog Search**: Query over 100+ production-ready steps from Official and Community registries.
|
|
16
|
+
- **🏗️ Professional Scaffolding**: Deploy complete project structures with LTS patterns (Class-based states, Typed Context, Pydantic).
|
|
17
|
+
- **📘 Architect's Manual**: Built-in expertise that teaches agents how to build pipelines exactly like a Senior Engineer.
|
|
18
|
+
- **💻 Unified CLI**: Manage your MCP service with simple commands: `run`, `start`, `stop`, and `config`.
|
|
19
|
+
- **🛡️ Privacy First**: 100% local execution via `stdio` or `SSE`.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## 🚀 Quick Start
|
|
24
|
+
|
|
25
|
+
### 1. Installation
|
|
26
|
+
Clone the repository and run the automated installer:
|
|
27
|
+
```bash
|
|
28
|
+
./installer.sh
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### 2. Integration
|
|
32
|
+
Get your agent-specific configuration block:
|
|
33
|
+
```bash
|
|
34
|
+
wpipe-mcp config
|
|
35
|
+
```
|
|
36
|
+
Copy the output into your agent's configuration file (e.g., `claude_desktop_config.json`).
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## 🛠️ CLI Usage
|
|
41
|
+
|
|
42
|
+
| Command | Description |
|
|
43
|
+
| :--- | :--- |
|
|
44
|
+
| `wpipe-mcp run` | Start the server in `stdio` mode (default for agents). |
|
|
45
|
+
| `wpipe-mcp start` | Start as an SSE server in the background. |
|
|
46
|
+
| `wpipe-mcp stop` | Stop the background server. |
|
|
47
|
+
| `wpipe-mcp config` | Generate JSON configuration for AI agents. |
|
|
48
|
+
| `wpipe-mcp help` | Show available tools and commands. |
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## 📂 Project Structure
|
|
53
|
+
- `src/wpipe_mcp/`: Core server logic and tools.
|
|
54
|
+
- `src/wpipe_mcp/catalog.py`: Real-time GitHub catalog synchronization.
|
|
55
|
+
- `src/wpipe_mcp/templates.py`: Professional boilerplate definitions.
|
|
56
|
+
- `examples/`: Sample implementations and use cases.
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## 📄 License
|
|
61
|
+
MIT License - Crafted with ❤️ by **William Rodriguez** (wisrovi).
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "wpipe-mcp"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "MCP Server for WPipe Architecting"
|
|
5
|
+
dependencies = [
|
|
6
|
+
"mcp[cli]>=1.0.0",
|
|
7
|
+
"fastmcp>=0.1.0",
|
|
8
|
+
"pydantic>=2.0.0"
|
|
9
|
+
]
|
|
10
|
+
|
|
11
|
+
[project.scripts]
|
|
12
|
+
wpipe-mcp = "wpipe_mcp.server:main"
|
|
13
|
+
|
|
14
|
+
[build-system]
|
|
15
|
+
requires = ["setuptools>=61.0"]
|
|
16
|
+
build-backend = "setuptools.build_meta"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from . import *
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .controller import Basemodel
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import urllib.request
|
|
3
|
+
import logging
|
|
4
|
+
|
|
5
|
+
# Configuración de logging básica
|
|
6
|
+
logging.basicConfig(level=logging.INFO)
|
|
7
|
+
logger = logging.getLogger(__name__)
|
|
8
|
+
|
|
9
|
+
class StepsCatalog:
|
|
10
|
+
"""
|
|
11
|
+
Manages the synchronization of available steps from the wisrovi SUITE.
|
|
12
|
+
Synchronizes from GitHub just like the VS Code extension.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
# URLs synchronized with the VS Code extension
|
|
16
|
+
OFFICIAL_URL = "https://raw.githubusercontent.com/wisrovi/wpipe-steps/001-DEVELOPMENT/steps_catalog.json"
|
|
17
|
+
COMMUNITY_URL = "https://raw.githubusercontent.com/wisrovi/wpipe-plugins/001-DEVELOPMENT/steps_catalog.json"
|
|
18
|
+
|
|
19
|
+
def __init__(self):
|
|
20
|
+
self.cached_steps = []
|
|
21
|
+
self._load_initial_catalog()
|
|
22
|
+
|
|
23
|
+
def _fetch_url(self, url: str) -> list:
|
|
24
|
+
try:
|
|
25
|
+
req = urllib.request.Request(url, headers={'User-Agent': 'wpipe-mcp'})
|
|
26
|
+
with urllib.request.urlopen(req, timeout=5) as response:
|
|
27
|
+
if response.status == 200:
|
|
28
|
+
return json.loads(response.read().decode('utf-8'))
|
|
29
|
+
except Exception as e:
|
|
30
|
+
logger.warning(f"Failed to fetch catalog from {url}: {e}")
|
|
31
|
+
return []
|
|
32
|
+
|
|
33
|
+
def refresh_catalog(self) -> list:
|
|
34
|
+
"""Fetch latest steps from both official and community repositories."""
|
|
35
|
+
official = self._fetch_url(self.OFFICIAL_URL)
|
|
36
|
+
community = self._fetch_url(self.COMMUNITY_URL)
|
|
37
|
+
|
|
38
|
+
# Merge and mark origin
|
|
39
|
+
all_steps = []
|
|
40
|
+
for s in official:
|
|
41
|
+
s['origin'] = 'Official'
|
|
42
|
+
all_steps.append(s)
|
|
43
|
+
for s in community:
|
|
44
|
+
s['origin'] = 'Community'
|
|
45
|
+
all_steps.append(s)
|
|
46
|
+
|
|
47
|
+
if all_steps:
|
|
48
|
+
self.cached_steps = all_steps
|
|
49
|
+
logger.info(f"Catalog refreshed: {len(self.cached_steps)} steps found.")
|
|
50
|
+
|
|
51
|
+
return self.cached_steps
|
|
52
|
+
|
|
53
|
+
def search(self, query: str) -> list:
|
|
54
|
+
"""Filters cataloged steps based on a search query keyword."""
|
|
55
|
+
if not self.cached_steps:
|
|
56
|
+
self.refresh_catalog()
|
|
57
|
+
|
|
58
|
+
query_lower = query.lower()
|
|
59
|
+
results = []
|
|
60
|
+
for step in self.cached_steps:
|
|
61
|
+
# Match against multiple fields
|
|
62
|
+
fields = [
|
|
63
|
+
step.get('name', ''),
|
|
64
|
+
step.get('func_name', ''),
|
|
65
|
+
step.get('namespace', ''),
|
|
66
|
+
step.get('description', ''),
|
|
67
|
+
step.get('category', '')
|
|
68
|
+
]
|
|
69
|
+
if any(query_lower in str(f).lower() for f in fields):
|
|
70
|
+
results.append(step)
|
|
71
|
+
return results
|
|
72
|
+
|
|
73
|
+
def _load_initial_catalog(self):
|
|
74
|
+
"""Initial load with hardcoded fallbacks if offline."""
|
|
75
|
+
self.cached_steps = [
|
|
76
|
+
{
|
|
77
|
+
"name": "http_request",
|
|
78
|
+
"func_name": "HttpRequestStep",
|
|
79
|
+
"namespace": "wpipe_steps.connectivity.http",
|
|
80
|
+
"description": "Resilient HTTP client for REST APIs",
|
|
81
|
+
"category": "Connectivity",
|
|
82
|
+
"origin": "Official"
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"name": "postgresql_query",
|
|
86
|
+
"func_name": "PostgreSQLQueryStep",
|
|
87
|
+
"namespace": "wpipe_steps.databases.postgresql",
|
|
88
|
+
"description": "Database worker with connection pooling",
|
|
89
|
+
"category": "Databases",
|
|
90
|
+
"origin": "Official"
|
|
91
|
+
}
|
|
92
|
+
]
|
|
93
|
+
# Attempt an immediate refresh
|
|
94
|
+
try:
|
|
95
|
+
self.refresh_catalog()
|
|
96
|
+
except:
|
|
97
|
+
pass
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import sys
|
|
3
|
+
import argparse
|
|
4
|
+
import subprocess
|
|
5
|
+
import signal
|
|
6
|
+
import json
|
|
7
|
+
import logging
|
|
8
|
+
from mcp.server.fastmcp import FastMCP
|
|
9
|
+
from wpipe_mcp.catalog import StepsCatalog
|
|
10
|
+
from wpipe_mcp.templates import TemplateGenerator
|
|
11
|
+
|
|
12
|
+
# Setup logging
|
|
13
|
+
logging.basicConfig(level=logging.INFO, format='%(levelname)s: %(message)s')
|
|
14
|
+
logger = logging.getLogger(__name__)
|
|
15
|
+
|
|
16
|
+
# PID file for background service
|
|
17
|
+
PID_FILE = os.path.expanduser("~/.wpipe_mcp.pid")
|
|
18
|
+
|
|
19
|
+
# Create the primary FastMCP Server instance
|
|
20
|
+
mcp = FastMCP("wpipe-mcp-server")
|
|
21
|
+
catalog = StepsCatalog()
|
|
22
|
+
|
|
23
|
+
# --- Tools ---
|
|
24
|
+
|
|
25
|
+
@mcp.tool()
|
|
26
|
+
def search_wpipe_step(query: str) -> str:
|
|
27
|
+
"""Search for existing pipeline steps in official and community catalogs."""
|
|
28
|
+
results = catalog.search(query)
|
|
29
|
+
if not results:
|
|
30
|
+
return f"No custom step matching '{query}' was found. Recommend building a native WPipe Class-based Step."
|
|
31
|
+
|
|
32
|
+
response = "Found production-ready architectural steps in wisrovi SUITE:\n\n"
|
|
33
|
+
for s in results:
|
|
34
|
+
response += f"🚀 [{s.get('origin', 'Unknown')}] {s.get('func_name', s.get('label'))}\n"
|
|
35
|
+
response += f" - Description: {s.get('description', 'N/A')}\n"
|
|
36
|
+
response += f" - Namespace: {s.get('namespace', 'N/A')}\n\n"
|
|
37
|
+
return response
|
|
38
|
+
|
|
39
|
+
@mcp.tool()
|
|
40
|
+
def deploy_wpipe_scaffolding(target_dir: str, project_name: str = "wpipe_project", pipeline_type: str = "standard") -> str:
|
|
41
|
+
"""Deploys a professional WPipe project structure with class-based states."""
|
|
42
|
+
try:
|
|
43
|
+
if not os.path.isabs(target_dir):
|
|
44
|
+
return "Error: target_dir must be an absolute path."
|
|
45
|
+
|
|
46
|
+
for folder in TemplateGenerator.get_folders(pipeline_type):
|
|
47
|
+
os.makedirs(os.path.join(target_dir, folder), exist_ok=True)
|
|
48
|
+
|
|
49
|
+
blueprints = TemplateGenerator.get_files_blueprint(pipeline_type, project_name)
|
|
50
|
+
for rel_path, content in blueprints.items():
|
|
51
|
+
full_path = os.path.join(target_dir, rel_path)
|
|
52
|
+
os.makedirs(os.path.dirname(full_path), exist_ok=True)
|
|
53
|
+
with open(full_path, "w", encoding="utf-8") as f:
|
|
54
|
+
f.write(content)
|
|
55
|
+
|
|
56
|
+
return f"Success: WPipe architecture '{project_name}' deployed at {target_dir}"
|
|
57
|
+
except Exception as e:
|
|
58
|
+
return f"Error: {str(e)}"
|
|
59
|
+
|
|
60
|
+
@mcp.tool()
|
|
61
|
+
def get_wpipe_architect_manual() -> str:
|
|
62
|
+
"""Expert manual for building high-performance pipelines (wisrovi standard)."""
|
|
63
|
+
return (
|
|
64
|
+
"WPIPE ARCHITECT MANUAL\n"
|
|
65
|
+
"1. Prefer Class-based States (@step).\n"
|
|
66
|
+
"2. Use Typed Context (PipelineContext/Pydantic).\n"
|
|
67
|
+
"3. Apply @to_obj on __call__.\n"
|
|
68
|
+
"4. Always use tracking_db for forensics."
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
# --- CLI Actions ---
|
|
72
|
+
|
|
73
|
+
def run_stdio():
|
|
74
|
+
"""Runs the MCP server in stdio mode (standard for agents)."""
|
|
75
|
+
mcp.run(transport="stdio")
|
|
76
|
+
|
|
77
|
+
def run_sse():
|
|
78
|
+
"""Runs the MCP server in SSE mode."""
|
|
79
|
+
mcp.run(transport="sse")
|
|
80
|
+
|
|
81
|
+
def start_background():
|
|
82
|
+
"""Starts the SSE server in the background."""
|
|
83
|
+
if os.path.exists(PID_FILE):
|
|
84
|
+
print("Server is already running or PID file exists.")
|
|
85
|
+
return
|
|
86
|
+
|
|
87
|
+
# In a real scenario, we would use a proper daemon library,
|
|
88
|
+
# but for simplicity, we use subprocess.
|
|
89
|
+
proc = subprocess.Popen(
|
|
90
|
+
[sys.executable, "-m", "wpipe_mcp.server", "run-sse"],
|
|
91
|
+
stdout=open(os.path.expanduser("~/wpipe_mcp.log"), "a"),
|
|
92
|
+
stderr=subprocess.STDOUT,
|
|
93
|
+
preexec_fn=os.setpgrp
|
|
94
|
+
)
|
|
95
|
+
with open(PID_FILE, "w") as f:
|
|
96
|
+
f.write(str(proc.pid))
|
|
97
|
+
print(f"wpipe-mcp started in background (SSE mode) with PID {proc.pid}")
|
|
98
|
+
|
|
99
|
+
def stop_background():
|
|
100
|
+
"""Stops the background SSE server."""
|
|
101
|
+
if not os.path.exists(PID_FILE):
|
|
102
|
+
print("No background server running.")
|
|
103
|
+
return
|
|
104
|
+
|
|
105
|
+
with open(PID_FILE, "r") as f:
|
|
106
|
+
pid = int(f.read())
|
|
107
|
+
|
|
108
|
+
try:
|
|
109
|
+
os.kill(pid, signal.SIGTERM)
|
|
110
|
+
print(f"Stopped server with PID {pid}")
|
|
111
|
+
except ProcessLookupError:
|
|
112
|
+
print("Process not found.")
|
|
113
|
+
finally:
|
|
114
|
+
os.remove(PID_FILE)
|
|
115
|
+
|
|
116
|
+
def print_config():
|
|
117
|
+
"""Prints the JSON configuration for agents."""
|
|
118
|
+
path = subprocess.check_output(["which", "wpipe-mcp"]).decode().strip()
|
|
119
|
+
config = {
|
|
120
|
+
"mcpServers": {
|
|
121
|
+
"wpipe-mcp": {
|
|
122
|
+
"command": path,
|
|
123
|
+
"args": ["run"],
|
|
124
|
+
"env": {}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
print(json.dumps(config, indent=2))
|
|
129
|
+
|
|
130
|
+
# --- Main Entry Point ---
|
|
131
|
+
|
|
132
|
+
def main():
|
|
133
|
+
parser = argparse.ArgumentParser(description="wpipe-mcp: WPipe Architect MCP Server")
|
|
134
|
+
parser.add_argument("command", nargs="?", default="run",
|
|
135
|
+
choices=["run", "run-sse", "start", "stop", "config", "help"],
|
|
136
|
+
help="Command to execute (default: run)")
|
|
137
|
+
|
|
138
|
+
args = parser.parse_args()
|
|
139
|
+
|
|
140
|
+
if args.command == "run":
|
|
141
|
+
run_stdio()
|
|
142
|
+
elif args.command == "run-sse":
|
|
143
|
+
run_sse()
|
|
144
|
+
elif args.command == "start":
|
|
145
|
+
start_background()
|
|
146
|
+
elif args.command == "stop":
|
|
147
|
+
stop_background()
|
|
148
|
+
elif args.command == "config":
|
|
149
|
+
print_config()
|
|
150
|
+
elif args.command == "help":
|
|
151
|
+
parser.print_help()
|
|
152
|
+
else:
|
|
153
|
+
parser.print_help()
|
|
154
|
+
|
|
155
|
+
if __name__ == "__main__":
|
|
156
|
+
main()
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# Advanced scaffolding templates for professional WPipe development
|
|
2
|
+
|
|
3
|
+
class TemplateGenerator:
|
|
4
|
+
"""Provides professional boilerplate for WPipe projects following wisrovi standards."""
|
|
5
|
+
|
|
6
|
+
@staticmethod
|
|
7
|
+
def get_supported_types() -> list:
|
|
8
|
+
return ["standard", "ai_vision_mlops"]
|
|
9
|
+
|
|
10
|
+
@staticmethod
|
|
11
|
+
def get_folders(pipeline_type: str) -> list:
|
|
12
|
+
if pipeline_type == "ai_vision_mlops":
|
|
13
|
+
return ["config", "src", "src/inference", "src/training", "src/training/tasks", "src/states", "datasets", "tests", ".wpipe"]
|
|
14
|
+
return ["config", "src", "src/steps", "src/states", "tests", ".wpipe"]
|
|
15
|
+
|
|
16
|
+
@staticmethod
|
|
17
|
+
def get_files_blueprint(pipeline_type: str, project_name: str = "wpipe_project") -> dict:
|
|
18
|
+
"""Returns filenames and their professional template content."""
|
|
19
|
+
|
|
20
|
+
# Professional Class-based State Template
|
|
21
|
+
state_template = (
|
|
22
|
+
"from wpipe import step, to_obj, PipelineContext\n"
|
|
23
|
+
"from pydantic import Field\n"
|
|
24
|
+
"from typing import Any\n\n"
|
|
25
|
+
"class MyContext(PipelineContext):\n"
|
|
26
|
+
" \"\"\"Typed context for the pipeline.\"\"\"\n"
|
|
27
|
+
" data: dict = Field(default_factory=dict)\n"
|
|
28
|
+
" status: str = \"init\"\n\n"
|
|
29
|
+
"@step(\n"
|
|
30
|
+
" name=\"process_data\",\n"
|
|
31
|
+
" version=\"v1.0\",\n"
|
|
32
|
+
" retry_count=3,\n"
|
|
33
|
+
" retry_delay=0.1,\n"
|
|
34
|
+
" tags=[\"processing\"]\n"
|
|
35
|
+
")\n"
|
|
36
|
+
"class ProcessDataStep:\n"
|
|
37
|
+
" \"\"\"Professional class-based step with typed context.\"\"\"\n"
|
|
38
|
+
" def __init__(self, config_param: str = \"default\"):\n"
|
|
39
|
+
" self.config_param = config_param\n\n"
|
|
40
|
+
" @to_obj(MyContext)\n"
|
|
41
|
+
" def __call__(self, ctx: MyContext) -> Any:\n"
|
|
42
|
+
" # Your logic here\n"
|
|
43
|
+
" ctx.status = \"completed\"\n"
|
|
44
|
+
" return ctx\n"
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
# Main Pipeline Template
|
|
48
|
+
pipeline_template = (
|
|
49
|
+
"import os\n"
|
|
50
|
+
"from wpipe import Pipeline\n"
|
|
51
|
+
"from wpipe.exception.api_error import ProcessError\n"
|
|
52
|
+
"from src.states.process_step import ProcessDataStep\n\n"
|
|
53
|
+
"def create_pipeline():\n"
|
|
54
|
+
" pipeline = Pipeline(\n"
|
|
55
|
+
" pipeline_name=\"{name}\",\n"
|
|
56
|
+
" tracking_db=\"output/tracking.db\",\n"
|
|
57
|
+
" collect_system_metrics=True,\n"
|
|
58
|
+
" verbose=True\n"
|
|
59
|
+
" )\n\n"
|
|
60
|
+
" pipeline.set_steps([\n"
|
|
61
|
+
" ProcessDataStep(config_param=\"prod\")\n"
|
|
62
|
+
" ])\n"
|
|
63
|
+
" return pipeline\n\n"
|
|
64
|
+
"if __name__ == \"__main__\":\n"
|
|
65
|
+
" pipeline = create_pipeline()\n"
|
|
66
|
+
" try:\n"
|
|
67
|
+
" result = pipeline.run({{\"data\": \"init\"}})\n"
|
|
68
|
+
" print(f\"Pipeline completed: {result}\")\n"
|
|
69
|
+
" except ProcessError as e:\n"
|
|
70
|
+
" print(f\"Pipeline failed: {e}\")\n"
|
|
71
|
+
).format(name=project_name)
|
|
72
|
+
|
|
73
|
+
blueprints = {
|
|
74
|
+
"requirements.txt": "wpipe>=1.0.0\nwdecorators>=2.0.0\npydantic>=2.0.0\n",
|
|
75
|
+
"README.md": f"# {project_name.upper()}\n\nProfessional architecture built with **wpipe**.\n",
|
|
76
|
+
"src/states/__init__.py": "from .process_step import ProcessDataStep\n",
|
|
77
|
+
"src/states/process_step.py": state_template,
|
|
78
|
+
"main.py": pipeline_template,
|
|
79
|
+
"wpipe.config.json": '{\n "enableBackupFile": true,\n "maxSearchFiles": 500\n}\n'
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if pipeline_type == "ai_vision_mlops":
|
|
83
|
+
blueprints["requirements.txt"] += "wyolo>=1.0.0\nwtrain>=1.0.0\ncelery>=5.3.0\n"
|
|
84
|
+
# Add vision specific boilerplate...
|
|
85
|
+
|
|
86
|
+
return blueprints
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
src/__init__.py
|
|
5
|
+
src/wpipe_mcp/__init__.py
|
|
6
|
+
src/wpipe_mcp/catalog.py
|
|
7
|
+
src/wpipe_mcp/server.py
|
|
8
|
+
src/wpipe_mcp/templates.py
|
|
9
|
+
src/wpipe_mcp.egg-info/PKG-INFO
|
|
10
|
+
src/wpipe_mcp.egg-info/SOURCES.txt
|
|
11
|
+
src/wpipe_mcp.egg-info/dependency_links.txt
|
|
12
|
+
src/wpipe_mcp.egg-info/entry_points.txt
|
|
13
|
+
src/wpipe_mcp.egg-info/requires.txt
|
|
14
|
+
src/wpipe_mcp.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|