-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgenerateRequirements.py
executable file
·127 lines (105 loc) · 4.08 KB
/
generateRequirements.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#!/usr/bin/env python3
import argparse
import urllib.request
import json
try:
import tomli
except ImportError:
from pip._vendor import tomli
def get_latest_version():
url = "https://api.github.com/repos/logspace-ai/langflow/releases/latest"
response = urllib.request.urlopen(url)
data = json.loads(response.read())
return data["name"]
def get_latest_pyproject():
# TODO: Use latest version
#
# Temporarily disabling this as it's missing langflow dependencies
#
# url = f"https://raw.githubusercontent.com/logspace-ai/langflow/{get_latest_version()}/pyproject.toml"
#
# Use dev branch for now
url = "https://raw.githubusercontent.com/logspace-ai/langflow/dev/pyproject.toml"
response = urllib.request.urlopen(url)
data = response.read()
return data.decode("utf-8")
def load_toml():
return tomli.loads(get_latest_pyproject())
def write_requirements(dependencies, output_path):
with open(output_path, "w") as file:
for dep, version in dependencies.items():
file.write(f"{dep}{version}\n")
def convert_dependency_version(version):
if isinstance(version, dict):
version = version.get("version", "")
if "^" in version:
# Caret requirements
parts = version.replace("^", "").split(".")
if parts[0] == "0":
if parts[1] == "0":
return f">={version.replace('^', '')},<0.0.{str(int(parts[2])+1)}"
return f">={version.replace('^', '')},<0.{str(int(parts[1])+1)}.0"
return f">={version.replace('^', '')},<{str(int(parts[0])+1)}.0.0"
elif "~" in version:
# Tilde requirements
parts = version.replace("~", "").split(".")
if len(parts) == 3:
return f">={version.replace('~', '')},<{parts[0]}.{str(int(parts[1])+1)}.0"
elif len(parts) == 2:
return f">={version.replace('~', '')},<{parts[0]}.{str(int(parts[1])+1)}"
else:
return f">={version.replace('~', '')},<{str(int(parts[0])+1)}.0.0"
elif "*" in version:
# Wildcard requirements
parts = version.split(".")
if len(parts) == 2:
return f">={parts[0]}.0.0,<{str(int(parts[0])+1)}.0.0"
elif len(parts) == 3:
return f">={version.replace('*', '0')},<{parts[0]}.{str(int(parts[1])+1)}.0"
else:
return ">=0.0.0"
elif "," in version:
# Multiple requirements
return ",".join(
[convert_dependency_version(v.strip()) for v in version.split(",")]
)
elif any(op in version for op in [">=", "<=", ">", "<", "!=", "=="]):
# Inequality and Exact requirements
return version
else:
# Assume exact version if none of the above
return f"=={version}"
def convert_pyproject_to_requirements(output_path):
pyproject = load_toml()
dependencies = pyproject["tool"]["poetry"]["dependencies"]
extras = pyproject["tool"]["poetry"]["extras"]
dep_lines = {}
for name, dep in dependencies.items():
if "pywin32" in name:
continue
if name != "python" and not isinstance(dep, dict):
version = convert_dependency_version(dep)
dep_lines[name] = version
elif isinstance(dep, dict):
version = convert_dependency_version(dep.get("version", ""))
dep_lines[name] = version
for _, deps in extras.items():
for dep in deps:
if dep not in dep_lines: # avoid duplicate entries
dep_version = dependencies.get(dep, "")
if dep_version:
version = convert_dependency_version(dep_version)
dep_lines[dep] = version
write_requirements(dep_lines, output_path)
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="Convert pyproject.toml to requirements.txt."
)
parser.add_argument(
"--out",
dest="output_path",
default="requirements.txt",
help="Path to the output requirements.txt file.",
)
args = parser.parse_args()
convert_pyproject_to_requirements(args.output_path)