eezyml 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.
- eezyml-0.1.0/PKG-INFO +4 -0
- eezyml-0.1.0/eezy_ml.py +176 -0
- eezyml-0.1.0/eezyml.egg-info/PKG-INFO +4 -0
- eezyml-0.1.0/eezyml.egg-info/SOURCES.txt +7 -0
- eezyml-0.1.0/eezyml.egg-info/dependency_links.txt +1 -0
- eezyml-0.1.0/eezyml.egg-info/entry_points.txt +2 -0
- eezyml-0.1.0/eezyml.egg-info/top_level.txt +1 -0
- eezyml-0.1.0/pyproject.toml +7 -0
- eezyml-0.1.0/setup.cfg +4 -0
eezyml-0.1.0/PKG-INFO
ADDED
eezyml-0.1.0/eezy_ml.py
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
import subprocess
|
|
3
|
+
import sys
|
|
4
|
+
import tempfile
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
import shutil
|
|
7
|
+
|
|
8
|
+
TEMPLATE_LIBRARIES = [
|
|
9
|
+
"scikit-learn==1.6.1",
|
|
10
|
+
"datasets==4.0.0",
|
|
11
|
+
"flask==3.1.3",
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def find_project_dir():
|
|
16
|
+
"""Return the directory containing init.py, starting from cwd upward."""
|
|
17
|
+
current = Path.cwd()
|
|
18
|
+
for directory in [current, *current.parents]:
|
|
19
|
+
if (directory / "init.py").exists():
|
|
20
|
+
return directory
|
|
21
|
+
return None
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def get_python(project_dir):
|
|
25
|
+
"""Return the venv Python executable if present, otherwise fall back to sys.executable."""
|
|
26
|
+
venv_python = project_dir / ".venv" / "Scripts" / "python.exe"
|
|
27
|
+
if venv_python.exists():
|
|
28
|
+
return str(venv_python)
|
|
29
|
+
return sys.executable
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def cmd_run_init():
|
|
33
|
+
project_dir = find_project_dir()
|
|
34
|
+
if project_dir is None:
|
|
35
|
+
print("Error: Could not find init.py. Run 'eezy create <dir>' first.", file=sys.stderr)
|
|
36
|
+
sys.exit(1)
|
|
37
|
+
python = get_python(project_dir)
|
|
38
|
+
print(f"Running init.py in {project_dir} (python: {python})...")
|
|
39
|
+
result = subprocess.run([python, str(project_dir / "init.py")], cwd=project_dir)
|
|
40
|
+
sys.exit(result.returncode)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def cmd_start(host="localhost", port=5000):
|
|
44
|
+
project_dir = find_project_dir()
|
|
45
|
+
if project_dir is None:
|
|
46
|
+
print("Error: Could not find init.py. Run 'eezy create <dir>' first.", file=sys.stderr)
|
|
47
|
+
sys.exit(1)
|
|
48
|
+
|
|
49
|
+
model_path = project_dir / "model" / "model.joblib"
|
|
50
|
+
if not model_path.exists():
|
|
51
|
+
print(
|
|
52
|
+
"Error: Model not found. Perhaps, you haven't run 'eezy init' yet.\n"
|
|
53
|
+
" Run 'eezy init' to download data and load/train the model first.",
|
|
54
|
+
file=sys.stderr,
|
|
55
|
+
)
|
|
56
|
+
sys.exit(1)
|
|
57
|
+
|
|
58
|
+
server_url = f"http://{host}:{port}"
|
|
59
|
+
python = get_python(project_dir)
|
|
60
|
+
print(f"Starting inference server from {project_dir} (python: {python})...")
|
|
61
|
+
server_env = {**__import__('os').environ, "SERVER_HOST": "0.0.0.0", "SERVER_PORT": str(port)}
|
|
62
|
+
server_proc = subprocess.Popen(
|
|
63
|
+
[python, str(project_dir / "server.py")],
|
|
64
|
+
cwd=project_dir,
|
|
65
|
+
env=server_env,
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
import time
|
|
69
|
+
import urllib.request
|
|
70
|
+
import urllib.error
|
|
71
|
+
|
|
72
|
+
print(f"Waiting for server to be ready at {server_url}...")
|
|
73
|
+
for _ in range(20):
|
|
74
|
+
try:
|
|
75
|
+
urllib.request.urlopen(f"{server_url}/health", timeout=1)
|
|
76
|
+
break
|
|
77
|
+
except (urllib.error.URLError, OSError):
|
|
78
|
+
time.sleep(0.5)
|
|
79
|
+
else:
|
|
80
|
+
print("Error: Server did not start in time.", file=sys.stderr)
|
|
81
|
+
server_proc.terminate()
|
|
82
|
+
sys.exit(1)
|
|
83
|
+
|
|
84
|
+
print("Server is ready. Running tests...\n")
|
|
85
|
+
test_env = {**__import__('os').environ, "SERVER_URL": server_url}
|
|
86
|
+
test_result = subprocess.run(
|
|
87
|
+
[python, str(project_dir / "test.py")],
|
|
88
|
+
cwd=project_dir,
|
|
89
|
+
env=test_env,
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
print(f"\nTest {'passed' if test_result.returncode == 0 else 'failed'}.")
|
|
93
|
+
print("Server is running. Press Ctrl+C to stop.")
|
|
94
|
+
try:
|
|
95
|
+
server_proc.wait()
|
|
96
|
+
except KeyboardInterrupt:
|
|
97
|
+
print("\nShutting down server...")
|
|
98
|
+
server_proc.terminate()
|
|
99
|
+
server_proc.wait()
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def cmd_create(target_dir, use_venv=True):
|
|
103
|
+
repo_url = "https://github.com/not-ekalabya/eezy-ml.git"
|
|
104
|
+
|
|
105
|
+
print("The following libraries will be available in the project:")
|
|
106
|
+
for lib in TEMPLATE_LIBRARIES:
|
|
107
|
+
print(f" - {lib}")
|
|
108
|
+
print()
|
|
109
|
+
print(f"Cloning /template from {repo_url} into {target_dir}...")
|
|
110
|
+
|
|
111
|
+
with tempfile.TemporaryDirectory() as tmp:
|
|
112
|
+
tmp_path = Path(tmp)
|
|
113
|
+
|
|
114
|
+
result = subprocess.run(["git", "clone", "--no-checkout", repo_url, tmp])
|
|
115
|
+
if result.returncode != 0:
|
|
116
|
+
print("Error: git clone failed.", file=sys.stderr)
|
|
117
|
+
sys.exit(result.returncode)
|
|
118
|
+
|
|
119
|
+
subprocess.run(["git", "-C", tmp, "config", "core.sparseCheckout", "true"], check=True)
|
|
120
|
+
(tmp_path / ".git" / "info" / "sparse-checkout").write_text("template/\n")
|
|
121
|
+
subprocess.run(["git", "-C", tmp, "checkout"], check=True)
|
|
122
|
+
|
|
123
|
+
template_src = tmp_path / "template"
|
|
124
|
+
target_path = Path(target_dir)
|
|
125
|
+
target_path.mkdir(parents=True, exist_ok=True)
|
|
126
|
+
|
|
127
|
+
for item in template_src.iterdir():
|
|
128
|
+
dest = target_path / item.name
|
|
129
|
+
if dest.exists():
|
|
130
|
+
shutil.rmtree(dest) if dest.is_dir() else dest.unlink()
|
|
131
|
+
shutil.copytree(item, dest) if item.is_dir() else shutil.copy2(item, dest)
|
|
132
|
+
|
|
133
|
+
print(f"Project initialized in ./{target_dir}")
|
|
134
|
+
|
|
135
|
+
if use_venv:
|
|
136
|
+
venv_path = Path(target_dir) / ".venv"
|
|
137
|
+
print(f"\nCreating virtual environment at {venv_path}...")
|
|
138
|
+
subprocess.run([sys.executable, "-m", "venv", str(venv_path)], check=True)
|
|
139
|
+
|
|
140
|
+
pip = venv_path / "Scripts" / "pip.exe"
|
|
141
|
+
requirements = Path(target_dir) / "requirements.txt"
|
|
142
|
+
if requirements.exists():
|
|
143
|
+
print("Installing dependencies...")
|
|
144
|
+
subprocess.run([str(pip), "install", "-r", str(requirements)], check=True)
|
|
145
|
+
|
|
146
|
+
print(f"Virtual environment ready. Activate with: {venv_path}\\Scripts\\activate")
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def main():
|
|
150
|
+
parser = argparse.ArgumentParser(prog="eezy")
|
|
151
|
+
subparsers = parser.add_subparsers(dest="command")
|
|
152
|
+
|
|
153
|
+
create_parser = subparsers.add_parser("create", help="Scaffold a new eezy-ml project from the template")
|
|
154
|
+
create_parser.add_argument("target_dir", help="Target directory name")
|
|
155
|
+
create_parser.add_argument("--no-venv", action="store_true", help="Skip virtual environment creation")
|
|
156
|
+
|
|
157
|
+
subparsers.add_parser("init", help="Download data and train the model (runs init.py)")
|
|
158
|
+
start_parser = subparsers.add_parser("start", help="Start the inference server and run tests")
|
|
159
|
+
start_parser.add_argument("--host", default="localhost", help="Server host (default: localhost)")
|
|
160
|
+
start_parser.add_argument("--port", type=int, default=5000, help="Server port (default: 5000)")
|
|
161
|
+
|
|
162
|
+
args = parser.parse_args()
|
|
163
|
+
|
|
164
|
+
if args.command == "create":
|
|
165
|
+
cmd_create(args.target_dir, use_venv=not args.no_venv)
|
|
166
|
+
elif args.command == "init":
|
|
167
|
+
cmd_run_init()
|
|
168
|
+
elif args.command == "start":
|
|
169
|
+
cmd_start(host=args.host, port=args.port)
|
|
170
|
+
else:
|
|
171
|
+
parser.print_help()
|
|
172
|
+
sys.exit(1)
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
if __name__ == "__main__":
|
|
176
|
+
main()
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
eezy_ml
|
eezyml-0.1.0/setup.cfg
ADDED