wowool-sdk-cpp 3.4.5__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.
@@ -0,0 +1,14 @@
1
+ include wowool/plugin/wowool_plugin.hpp
2
+ include sdk_version.txt
3
+ include version.txt
4
+ include install_requires.txt
5
+ include install_requires_wowool.txt
6
+ include pre_setup.py
7
+ include common_setup.py
8
+ global-exclude *.dylib
9
+ global-exclude *.so
10
+ global-exclude *.dll
11
+ exclude wowool/package/lib/wow
12
+ exclude wowool/package/lib/woc
13
+ exclude wowool/package/lib/afst
14
+ include long_description.md
@@ -0,0 +1,33 @@
1
+ Metadata-Version: 2.4
2
+ Name: wowool-sdk-cpp
3
+ Version: 3.4.5
4
+ Summary: Wowool NLP Toolkit C++ SDK Python Bindings
5
+ Author: Wowool
6
+ Requires-Python: >=3.11
7
+ Description-Content-Type: text/markdown
8
+ Dynamic: author
9
+ Dynamic: description
10
+ Dynamic: description-content-type
11
+ Dynamic: requires-python
12
+ Dynamic: summary
13
+
14
+ # The Wowool NLP CPP Bindings
15
+
16
+ ## Introduction
17
+
18
+ This package contains the cpp bindings of the wowool-sdk and should not be install as a separated package, install the wowool-sdk instead which contains this package.
19
+
20
+ ## License
21
+
22
+ In both cases you will need to acquirer a license file at https://www.wowool.com
23
+
24
+ ### Non-Commercial
25
+
26
+ This library is licensed under the GNU AGPLv3 for non-commercial use.
27
+ For commercial use, a separate license must be purchased.
28
+
29
+ ### Commercial license Terms
30
+
31
+ 1. Grants the right to use this library in proprietary software.
32
+ 2. Requires a valid license key
33
+ 3. Redistribution in SaaS requires a commercial license.
@@ -0,0 +1,79 @@
1
+ from pathlib import Path
2
+ import os
3
+ import shutil
4
+
5
+
6
+ def copy_with_lnk(src, dst):
7
+ dst = Path(dst)
8
+ src = Path(src)
9
+
10
+ if os.path.islink(src):
11
+ linkto = os.readlink(src)
12
+
13
+ # Remove existing destination if it exists
14
+ if os.path.lexists(dst):
15
+ os.unlink(dst)
16
+
17
+ try:
18
+ # Try to determine if the link is relative or absolute
19
+ target_path = Path(linkto)
20
+ if not target_path.is_absolute():
21
+ # If relative, maintain the same relative path
22
+ dst.parent.mkdir(parents=True, exist_ok=True)
23
+ dir_fd = os.open(dst.parent, os.O_RDONLY)
24
+ os.symlink(linkto, dst, dir_fd=dir_fd)
25
+ os.close(dir_fd)
26
+ if not os.path.islink(dst):
27
+ raise RuntimeError(f"Failed to create symlink {dst} -> {linkto}")
28
+
29
+ else:
30
+ # If absolute, we need to determine the new absolute path
31
+ # or just copy the file directly as a fallback
32
+
33
+ target_file = src.parent / linkto if not os.path.isabs(linkto) else Path(linkto)
34
+ if target_file.exists():
35
+ # Just copy the target file directly instead of creating a symlink
36
+ shutil.copy2(target_file, dst)
37
+ else:
38
+ # Create a symlink anyway, might work in some environments
39
+ os.symlink(linkto, dst)
40
+
41
+ except Exception as ex:
42
+ print(f"Error creating symlink: {ex}")
43
+ raise ex
44
+ else:
45
+ # Regular file copy
46
+ shutil.copy2(src, dst)
47
+
48
+
49
+ def copy_to_package_folder(site_packages: Path, wow_sdk_folder: Path, bin_folders: Path, inc_folders: Path, lib_folders: Path):
50
+ """
51
+ Copy the files to the package folder
52
+ """
53
+ print(f"[WOW] site_packages: {site_packages=}")
54
+ try:
55
+ wowool_package_lib = site_packages / "wowool" / "package" / "lib"
56
+ print(f"[WOW] wowool_package_lib: {wowool_package_lib=}")
57
+ wowool_package_lib.mkdir(parents=True, exist_ok=True)
58
+
59
+ for fn in bin_folders.glob("*"):
60
+ print(f"[WOW] bin: {fn.name}")
61
+ copy_with_lnk(fn, wowool_package_lib / fn.name)
62
+
63
+ for fn in lib_folders.glob("*"):
64
+ copy_with_lnk(fn, wowool_package_lib / fn.name)
65
+
66
+ print(f"[WOW] Folders : WOWOOL_STAGE: {wow_sdk_folder=} {inc_folders=} {lib_folders=}")
67
+ if lib_folders.exists() and inc_folders.exists():
68
+ os.environ["WOWOOL_STAGE"] = str(wow_sdk_folder)
69
+ # WOWOOL_STAGE = wow_sdk_folder
70
+ print("wowool.package folder:", wowool_package_lib)
71
+ else:
72
+ print(
73
+ """[WOWOOL] You will need to set the WOWOOL_STAGE folder, to build the native package.
74
+ This should be in your environment ..../wowool/package"""
75
+ )
76
+ exit(-1)
77
+ except Exception as ex:
78
+ print(f"""[WOWOOL] {ex} Could not copy tile to stage folder""")
79
+ raise ex
File without changes
File without changes
@@ -0,0 +1,20 @@
1
+ # The Wowool NLP CPP Bindings
2
+
3
+ ## Introduction
4
+
5
+ This package contains the cpp bindings of the wowool-sdk and should not be install as a separated package, install the wowool-sdk instead which contains this package.
6
+
7
+ ## License
8
+
9
+ In both cases you will need to acquirer a license file at https://www.wowool.com
10
+
11
+ ### Non-Commercial
12
+
13
+ This library is licensed under the GNU AGPLv3 for non-commercial use.
14
+ For commercial use, a separate license must be purchased.
15
+
16
+ ### Commercial license Terms
17
+
18
+ 1. Grants the right to use this library in proprietary software.
19
+ 2. Requires a valid license key
20
+ 3. Redistribution in SaaS requires a commercial license.
@@ -0,0 +1,241 @@
1
+ import os
2
+ import shutil
3
+ from pathlib import Path
4
+ import platform
5
+ from logging import getLogger
6
+ import subprocess
7
+ import json
8
+
9
+ logger = getLogger(__name__)
10
+
11
+ this_dir = Path(__file__).parent
12
+ fusion_root = None
13
+ fusion_root = this_dir
14
+
15
+ pi = platform.system()
16
+ tar_ext = "tar.gz" if pi != "Windows" else "zip"
17
+ app_ext = "" if pi != "Windows" else ".exe"
18
+ SO_EXT = ".so" if pi != "Windows" else ".pyd"
19
+ native_so_prefix = "lib" if pi != "Windows" else ""
20
+ if pi == "Windows":
21
+ NATIVE_SO_EXT = ".dll"
22
+ elif pi == "Darwin":
23
+ NATIVE_SO_EXT = ".dylib"
24
+ else:
25
+ NATIVE_SO_EXT = ".so"
26
+
27
+
28
+ def get_origin_keyword():
29
+ if platform.system() == "Darwin":
30
+ return "@loader_path"
31
+ elif platform.system() == "Linux":
32
+ return "$ORIGIN"
33
+
34
+
35
+ def call_subprocess(cmd_params):
36
+ cmd = " ".join(cmd_params)
37
+ try:
38
+ subprocess.run(cmd, shell=True, check=True)
39
+ except subprocess.CalledProcessError as ex:
40
+ logger.exception(f"Cannot run [{cmd}], {ex}")
41
+
42
+
43
+ def get_all_rpaths(filename):
44
+ if platform.system() == "Darwin":
45
+ cmd = ["otool", "-l", str(filename)]
46
+ if not filename.exists():
47
+ raise RuntimeError(f"File not there yet {filename}")
48
+ rpathlist = [line.strip() for line in subprocess.check_output(cmd).decode().split("\n")]
49
+ rpaths = []
50
+ pidx = -1
51
+ for idx, line in enumerate(rpathlist):
52
+ if line.startswith("cmd LC_RPATH"):
53
+ pidx = idx + 2
54
+ elif idx == pidx:
55
+ rpaths.append(line.split(" ")[1])
56
+ return rpaths
57
+ else:
58
+ assert False, "Not implemented for given platform."
59
+
60
+
61
+ def remove_all_build_rpaths(filename):
62
+ if platform.system() == "Darwin":
63
+ build_paths = get_all_rpaths(filename)
64
+ for build_path in build_paths:
65
+ try:
66
+ cmd_params = ["install_name_tool", "-delete_rpath", str(build_path), str(filename)]
67
+ call_subprocess(cmd_params)
68
+ except Exception as ex:
69
+ logger.error(f"Failed to remove rpath {build_path} from {filename}: {ex}")
70
+ pass
71
+
72
+ assert len(get_all_rpaths(filename)) == 0
73
+
74
+
75
+ def remove_rpath(filename):
76
+ if platform.system() == "Darwin":
77
+ remove_all_build_rpaths(filename)
78
+ elif platform.system() == "Linux":
79
+ cmd_params = [
80
+ "patchelf",
81
+ "--remove-rpath",
82
+ str(filename),
83
+ ]
84
+ call_subprocess(cmd_params)
85
+
86
+
87
+ def set_rpath_origin(filename):
88
+ if platform.system() == "Darwin":
89
+ cmd_params = ["install_name_tool", "-add_rpath", get_origin_keyword(), str(filename)]
90
+ call_subprocess(cmd_params)
91
+ elif platform.system() == "Linux":
92
+ cmd_params = [
93
+ "patchelf",
94
+ "--force-rpath",
95
+ "--set-rpath",
96
+ f"\\{get_origin_keyword()}",
97
+ str(filename),
98
+ ]
99
+ call_subprocess(cmd_params)
100
+
101
+
102
+ def prep_build_setup(wow_stage: Path):
103
+ """
104
+ Prepare the source folders
105
+ """
106
+ logger.info(f"----------------- begin prepping {wow_stage}---------------------")
107
+
108
+ this_repo = Path(this_dir)
109
+ package_lxware_folder = this_repo / "wowool" / "package" / "lxware"
110
+ package_lib_folder = this_repo / "wowool" / "package" / "lib"
111
+
112
+ logger.debug(f"{this_repo}")
113
+
114
+ os.makedirs(package_lxware_folder, exist_ok=True)
115
+
116
+ stage_bin_folder = wow_stage / "bin"
117
+ stage_lib_folder = wow_stage / "lib"
118
+
119
+ icu_lib_folder = stage_lib_folder
120
+
121
+ tir_config_fn = wow_stage / "config.json"
122
+ if tir_config_fn.exists():
123
+ with open(tir_config_fn) as fh:
124
+ tir_config = json.load(fh)
125
+ TIR_VERSION = tir_config["version"]
126
+
127
+ sdk_version_fn = this_dir / "sdk_version.txt"
128
+ with open(sdk_version_fn) as fh:
129
+ current_sdk_version = fh.read().strip()
130
+
131
+ if current_sdk_version != TIR_VERSION:
132
+ raise ValueError(
133
+ f"""!!! The native python SDK requires version'{current_sdk_version}' of the cpp SDK, but found the version '{TIR_VERSION}' in {stage_lib_folder}\nChange {sdk_version_fn.stem}"""
134
+ )
135
+ else:
136
+ assert fusion_root
137
+ tir_version = this_dir / "sdk_version.txt"
138
+ if tir_version.exists():
139
+ with open(tir_version, "r") as fh:
140
+ TIR_VERSION = fh.read().strip()
141
+ else:
142
+ TIR_VERSION = os.environ["TIR_VERSION"]
143
+
144
+ # change the rpath for the end package to used $ORIGIN
145
+ pattern = f"*{NATIVE_SO_EXT}"
146
+ native_linux_pattern = f"*{NATIVE_SO_EXT}.{TIR_VERSION}"
147
+
148
+ platform_name = platform.system()
149
+ if "Windows" == platform_name:
150
+ icu_files = ["icudt.lib", "icuuc.lib"]
151
+ elif "Darwin" == platform_name:
152
+ icu_files = ["libicudata.dylib", "libicuuc.dylib"]
153
+ else:
154
+ icu_files = ["libicudata.so", "libicuuc.so"]
155
+
156
+ logger.info(f"{TIR_VERSION=} {package_lib_folder=} {native_linux_pattern=}")
157
+
158
+ package_lib_folder.mkdir(parents=True, exist_ok=True)
159
+ logger.info(f"copying native libs {stage_lib_folder} --> {package_lib_folder=} {package_lib_folder.exists()=}")
160
+ try:
161
+ for fn in stage_lib_folder.glob(native_linux_pattern):
162
+ target_fn = package_lib_folder / fn.name
163
+ logger.info(f"copy {fn} --> {target_fn}")
164
+
165
+ if fn.is_symlink():
166
+ logger.info(f"{fn} is symlink, skipping")
167
+ continue
168
+ shutil.copy2(fn, target_fn)
169
+ logger.info(f"[ok] copy {fn} --> {target_fn}")
170
+ # remove_rpath(target_fn)
171
+ # set_rpath_origin(target_fn)
172
+ except Exception as ex:
173
+ logger.error(f"Failed to copy native lib {ex}")
174
+ raise ex
175
+
176
+ logger.info(f"copying {stage_lib_folder=} to {package_lib_folder=} {package_lib_folder.exists()=}")
177
+ for fn in stage_lib_folder.glob(pattern):
178
+ target_fn = package_lib_folder / fn.name
179
+ if target_fn.name.startswith("_"):
180
+ continue
181
+ if fn.is_symlink():
182
+ # do not copy symlinks.
183
+ # shutil.copy2(fn, package_lib_folder / fn.name , follow_symlinks=False )
184
+ pass
185
+ else:
186
+ if target_fn.exists():
187
+ target_fn.unlink()
188
+ target_fn.parent.mkdir(parents=True, exist_ok=True)
189
+ logger.info(f"!!!!! COPY3 {fn} --> {target_fn}")
190
+ shutil.copy2(fn, target_fn)
191
+
192
+ # copy icu
193
+ logger.info("----------------- before ---------------------")
194
+ for fn in package_lib_folder.glob("**/*"):
195
+ logger.info(f"package: {fn}")
196
+
197
+ for fn in icu_files:
198
+ target_fn = package_lib_folder / fn
199
+ shutil.copy2(icu_lib_folder / fn, target_fn)
200
+ # remove_rpath(target_fn)
201
+ # set_rpath_origin(target_fn)
202
+
203
+ if "Windows" == platform_name:
204
+ # for windows we also need to copy the dll
205
+ bin_files = [[fn] for fn in stage_bin_folder.glob("*.dll")]
206
+ bin_files.append([stage_bin_folder / "wow.exe", "wow++.exe"])
207
+ bin_files.append([stage_bin_folder / "woc.exe", "woc++.exe"])
208
+ bin_files.append([stage_bin_folder / "afst.exe", "afst++.exe"])
209
+ else:
210
+ bin_files = []
211
+ bin_files.append([stage_bin_folder / "wow", "wow++"])
212
+ bin_files.append([stage_bin_folder / "woc", "woc++"])
213
+ bin_files.append([stage_bin_folder / "afst", "afst++"])
214
+
215
+ for fn in bin_files:
216
+ if len(fn) == 1:
217
+ target_fn = package_lib_folder / fn[0].name
218
+ else:
219
+ target_fn = package_lib_folder / fn[1]
220
+
221
+ shutil.copy2(fn[0], target_fn)
222
+ remove_rpath(target_fn)
223
+ logger.info(f"set_rpath_origin {target_fn}")
224
+ set_rpath_origin(target_fn)
225
+ logger.info("----------------- end prepping ---------------------")
226
+ for fn in package_lib_folder.glob("**/*"):
227
+ if "__pycache_" not in str(fn):
228
+ logger.info(f"package: {fn}")
229
+
230
+
231
+ def post_build_setup(stage: Path):
232
+ """
233
+ Prepare the source folders
234
+ """
235
+
236
+ print("post_build ... ")
237
+ files = [fn for fn in stage.glob(f"lib/*{NATIVE_SO_EXT}")]
238
+ for fn in files:
239
+ print(f"post_build : remove rpaths {fn}")
240
+ remove_rpath(fn)
241
+ set_rpath_origin(fn)
@@ -0,0 +1,16 @@
1
+ [tool.black]
2
+ line-length = 140
3
+
4
+ [tool.pytest.ini_options]
5
+ pythonpath = [
6
+ "."
7
+ ]
8
+ testpaths= [ "tests/wowool/native/core" ]
9
+
10
+ addopts = [
11
+ "--import-mode=importlib"
12
+ ]
13
+
14
+ [build-system]
15
+ requires = ["setuptools >= 65.5.0" , "requests"]
16
+ build-backend = "setuptools.build_meta"
@@ -0,0 +1 @@
1
+ 3.1.2
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+