python-mscl 67.0.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.
- python_mscl-67.0.0/.github/workflows/build_wheels.yml +53 -0
- python_mscl-67.0.0/.gitignore +24 -0
- python_mscl-67.0.0/.python-version +1 -0
- python_mscl-67.0.0/LICENSE +21 -0
- python_mscl-67.0.0/PKG-INFO +83 -0
- python_mscl-67.0.0/README.md +64 -0
- python_mscl-67.0.0/build_helpers/__init__.py +0 -0
- python_mscl-67.0.0/build_helpers/release_downloader.py +72 -0
- python_mscl-67.0.0/build_helpers/release_extractor.py +113 -0
- python_mscl-67.0.0/hatch_build.py +116 -0
- python_mscl-67.0.0/pyproject.toml +60 -0
- python_mscl-67.0.0/src/python_mscl/__init__.py +5 -0
- python_mscl-67.0.0/src/python_mscl/py.typed +0 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
name: Build wheels
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
branches:
|
|
6
|
+
- '**' # Matches all branch names, for PRs
|
|
7
|
+
push:
|
|
8
|
+
branches:
|
|
9
|
+
- 'main' # Run tests on main branch
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
build-wheels:
|
|
13
|
+
name: Build wheels
|
|
14
|
+
runs-on: ${{ matrix.os }}
|
|
15
|
+
timeout-minutes: 5
|
|
16
|
+
strategy:
|
|
17
|
+
fail-fast: false
|
|
18
|
+
matrix:
|
|
19
|
+
os: [ubuntu-latest, windows-latest]
|
|
20
|
+
python-version: [3.9, 3.11, 3.13]
|
|
21
|
+
exclude:
|
|
22
|
+
- os: windows-latest
|
|
23
|
+
python-version: 3.9
|
|
24
|
+
- os: windows-latest
|
|
25
|
+
python-version: 3.13
|
|
26
|
+
|
|
27
|
+
steps:
|
|
28
|
+
- uses: actions/checkout@v4
|
|
29
|
+
|
|
30
|
+
- name: Install uv
|
|
31
|
+
uses: astral-sh/setup-uv@v5
|
|
32
|
+
with:
|
|
33
|
+
enable-cache: true
|
|
34
|
+
|
|
35
|
+
- name: Set up Python
|
|
36
|
+
uses: actions/setup-python@v5
|
|
37
|
+
with:
|
|
38
|
+
python-version: ${{ matrix.python-version }}
|
|
39
|
+
|
|
40
|
+
- name: Install the project
|
|
41
|
+
run: uv sync
|
|
42
|
+
|
|
43
|
+
- name: Build the wheel
|
|
44
|
+
run: uv build --wheel
|
|
45
|
+
|
|
46
|
+
- name: Initialize test environment
|
|
47
|
+
run: |
|
|
48
|
+
uv init --no-workspace test
|
|
49
|
+
cd test
|
|
50
|
+
uv add ../dist/*.whl
|
|
51
|
+
|
|
52
|
+
- name: Verify installation
|
|
53
|
+
run: uv run -- python -c "from python_mscl import mscl"
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Python-generated files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[oc]
|
|
4
|
+
build/
|
|
5
|
+
dist/
|
|
6
|
+
wheels/
|
|
7
|
+
*.egg-info
|
|
8
|
+
|
|
9
|
+
# Virtual environments
|
|
10
|
+
.venv
|
|
11
|
+
|
|
12
|
+
# Environment variables:
|
|
13
|
+
.env
|
|
14
|
+
|
|
15
|
+
# Exclude local .deb and .zip files from mscl:
|
|
16
|
+
mscl_release_assets/*.zip
|
|
17
|
+
mscl_release_assets/*.deb
|
|
18
|
+
|
|
19
|
+
# VSCode:
|
|
20
|
+
.vscode/
|
|
21
|
+
|
|
22
|
+
# Exclude build downloaded mscl files:
|
|
23
|
+
src/mscl/mscl.py
|
|
24
|
+
src/mscl/_mscl.so
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.13
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Harshil
|
|
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.
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: python-mscl
|
|
3
|
+
Version: 67.0.0
|
|
4
|
+
Summary: Easy to install python wrapper for the MSCL library.
|
|
5
|
+
Author-email: Harshil <37377066+harshil21@users.noreply.github.com>
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Classifier: Development Status :: 4 - Beta
|
|
8
|
+
Classifier: Intended Audience :: Developers
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
16
|
+
Classifier: Topic :: Scientific/Engineering
|
|
17
|
+
Requires-Python: >=3.9
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
|
|
20
|
+
# python-mscl
|
|
21
|
+
|
|
22
|
+
Unofficial Python package for the [Microstrain Communication Library](https://github.com/LORD-MicroStrain/MSCL/tree/master).
|
|
23
|
+
|
|
24
|
+
This library just makes it so that we can install the MSCL library using pip. Wheels are not provided. This will fetch the necessary files for your architecture and python
|
|
25
|
+
version, and then build the wheel for you.
|
|
26
|
+
|
|
27
|
+
It is therefore recommended to use a cache for your CI or package manager, unless you're okay with the ~20MB download every time you run your CI.
|
|
28
|
+
|
|
29
|
+
### Installation
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
pip install python-mscl
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Usage
|
|
36
|
+
|
|
37
|
+
```python
|
|
38
|
+
from python_mscl import mscl
|
|
39
|
+
|
|
40
|
+
# ... use the MSCL library as you normally would
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Windows support:
|
|
44
|
+
|
|
45
|
+
The latest mscl version (v67.0.0) only has a .zip for python 3.11. It has been confirmed that it does not work on other python versions (You would get an import error). However the build itself would still go through.
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
### Versioning system:
|
|
49
|
+
|
|
50
|
+
This repository follows the same versioning system as the MSCL library. This is reflected in the tags of this repository.
|
|
51
|
+
|
|
52
|
+
The version reflected in PyPI is as follows:
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
<MSCL_VERSION>.<REPO_VERSION>
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
E.g, there could be a version: `67.0.0.3` which would mean that the MSCL version is `67.0.0` and this is the third release of the python-mscl package.
|
|
59
|
+
|
|
60
|
+
## Local Development:
|
|
61
|
+
|
|
62
|
+
The below steps assume you have [`uv`](https://docs.astral.sh/uv/) installed.
|
|
63
|
+
|
|
64
|
+
1. Clone the repo and `cd` into it.
|
|
65
|
+
2. Optional: Create a .env file and insert your GITHUB_TOKEN= to make requests to the GitHub API.
|
|
66
|
+
3. Edit & run `uv run main.py` to fetch the latest tagged MSCL releases and extract them.
|
|
67
|
+
4. Run `uv build`, which will build the source distribution and wheel for your python
|
|
68
|
+
version and architecture.
|
|
69
|
+
|
|
70
|
+
Notes for me, the maintainer:
|
|
71
|
+
5. Optional: Run `uv publish` to publish the package to PyPI. To upload to TestPyPI, uncomment lines in `pyproject.toml`, and run `uv publish --index testpypi dist/*.tar.gz`.
|
|
72
|
+
6. Optional: To check if the package worked correctly: `uv add --index https://test.pypi.org/simple/ --index-strategy unsafe-best-match python-mscl` in a new uv project directory.
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
## Issues:
|
|
76
|
+
|
|
77
|
+
If you encounter any issues, please open an issue on this repository. I would have to
|
|
78
|
+
manually update this repository to the latest MSCL release. If it has been more than 48 hours since the latest release and I didn't update this repository, please open an issue.
|
|
79
|
+
|
|
80
|
+
## License
|
|
81
|
+
|
|
82
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
83
|
+
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# python-mscl
|
|
2
|
+
|
|
3
|
+
Unofficial Python package for the [Microstrain Communication Library](https://github.com/LORD-MicroStrain/MSCL/tree/master).
|
|
4
|
+
|
|
5
|
+
This library just makes it so that we can install the MSCL library using pip. Wheels are not provided. This will fetch the necessary files for your architecture and python
|
|
6
|
+
version, and then build the wheel for you.
|
|
7
|
+
|
|
8
|
+
It is therefore recommended to use a cache for your CI or package manager, unless you're okay with the ~20MB download every time you run your CI.
|
|
9
|
+
|
|
10
|
+
### Installation
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
pip install python-mscl
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
### Usage
|
|
17
|
+
|
|
18
|
+
```python
|
|
19
|
+
from python_mscl import mscl
|
|
20
|
+
|
|
21
|
+
# ... use the MSCL library as you normally would
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### Windows support:
|
|
25
|
+
|
|
26
|
+
The latest mscl version (v67.0.0) only has a .zip for python 3.11. It has been confirmed that it does not work on other python versions (You would get an import error). However the build itself would still go through.
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
### Versioning system:
|
|
30
|
+
|
|
31
|
+
This repository follows the same versioning system as the MSCL library. This is reflected in the tags of this repository.
|
|
32
|
+
|
|
33
|
+
The version reflected in PyPI is as follows:
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
<MSCL_VERSION>.<REPO_VERSION>
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
E.g, there could be a version: `67.0.0.3` which would mean that the MSCL version is `67.0.0` and this is the third release of the python-mscl package.
|
|
40
|
+
|
|
41
|
+
## Local Development:
|
|
42
|
+
|
|
43
|
+
The below steps assume you have [`uv`](https://docs.astral.sh/uv/) installed.
|
|
44
|
+
|
|
45
|
+
1. Clone the repo and `cd` into it.
|
|
46
|
+
2. Optional: Create a .env file and insert your GITHUB_TOKEN= to make requests to the GitHub API.
|
|
47
|
+
3. Edit & run `uv run main.py` to fetch the latest tagged MSCL releases and extract them.
|
|
48
|
+
4. Run `uv build`, which will build the source distribution and wheel for your python
|
|
49
|
+
version and architecture.
|
|
50
|
+
|
|
51
|
+
Notes for me, the maintainer:
|
|
52
|
+
5. Optional: Run `uv publish` to publish the package to PyPI. To upload to TestPyPI, uncomment lines in `pyproject.toml`, and run `uv publish --index testpypi dist/*.tar.gz`.
|
|
53
|
+
6. Optional: To check if the package worked correctly: `uv add --index https://test.pypi.org/simple/ --index-strategy unsafe-best-match python-mscl` in a new uv project directory.
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
## Issues:
|
|
57
|
+
|
|
58
|
+
If you encounter any issues, please open an issue on this repository. I would have to
|
|
59
|
+
manually update this repository to the latest MSCL release. If it has been more than 48 hours since the latest release and I didn't update this repository, please open an issue.
|
|
60
|
+
|
|
61
|
+
## License
|
|
62
|
+
|
|
63
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
64
|
+
|
|
File without changes
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"""Downloads the Github release assets for the mscl library."""
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
import requests
|
|
7
|
+
from github import Github
|
|
8
|
+
from github.GitRelease import GitRelease
|
|
9
|
+
from github.GitReleaseAsset import GitReleaseAsset
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class GithubDownloader:
|
|
13
|
+
"""Manages downloading the Github release assets for the mscl library, along with the
|
|
14
|
+
extracted files from this repository."""
|
|
15
|
+
|
|
16
|
+
def __init__(self):
|
|
17
|
+
self.github = Github(os.getenv("GITHUB_TOKEN"))
|
|
18
|
+
self.mscl_repo = "LORD-MicroStrain/MSCL"
|
|
19
|
+
self.python_mscl_repo = "harshil21/python-mscl"
|
|
20
|
+
self.latest_release = None
|
|
21
|
+
|
|
22
|
+
def get_latest_release(self) -> GitRelease:
|
|
23
|
+
"""Returns the latest stable release for the given repo."""
|
|
24
|
+
if self.latest_release:
|
|
25
|
+
return self.latest_release
|
|
26
|
+
|
|
27
|
+
releases = self.github.get_repo(self.mscl_repo).get_releases()
|
|
28
|
+
for release in releases:
|
|
29
|
+
if release.prerelease:
|
|
30
|
+
continue
|
|
31
|
+
if release.tag_name.startswith("v"):
|
|
32
|
+
self.latest_release = release
|
|
33
|
+
break
|
|
34
|
+
return self.latest_release
|
|
35
|
+
|
|
36
|
+
def download_release_assets(self, output_dir: str):
|
|
37
|
+
"""Downloads the release assets for the given repo and tag."""
|
|
38
|
+
release = self.get_latest_release()
|
|
39
|
+
output_path = Path(output_dir)
|
|
40
|
+
output_path.mkdir(parents=True, exist_ok=True)
|
|
41
|
+
|
|
42
|
+
asset: GitReleaseAsset
|
|
43
|
+
for asset in release.get_assets():
|
|
44
|
+
# Don't download the "Documentation" or "Examples"
|
|
45
|
+
if "Documentation" in asset.name or "Examples" in asset.name:
|
|
46
|
+
continue
|
|
47
|
+
# Don't download anything non-python:
|
|
48
|
+
if "Python" not in asset.name:
|
|
49
|
+
continue
|
|
50
|
+
# Only python 3 and above:
|
|
51
|
+
if "3" not in asset.name:
|
|
52
|
+
continue
|
|
53
|
+
|
|
54
|
+
self.download_asset(output_path, asset)
|
|
55
|
+
|
|
56
|
+
def download_asset(self, output_path: Path, asset: GitReleaseAsset) -> None:
|
|
57
|
+
response = requests.get(asset.browser_download_url, timeout=15)
|
|
58
|
+
asset_path = output_path / asset.name
|
|
59
|
+
asset_path.write_bytes(response.content)
|
|
60
|
+
|
|
61
|
+
def download_assets_from_folder(self, tag: str, folder_name: str) -> None:
|
|
62
|
+
"""Downloads all the files under the `folder_name` for the given tag, from the
|
|
63
|
+
root of the repository."""
|
|
64
|
+
|
|
65
|
+
repo = self.github.get_repo(self.python_mscl_repo)
|
|
66
|
+
contents = repo.get_contents(folder_name, ref=tag)
|
|
67
|
+
|
|
68
|
+
for content in contents:
|
|
69
|
+
if content.type == "file":
|
|
70
|
+
response = requests.get(content.download_url, timeout=15)
|
|
71
|
+
file_path = Path(content.name)
|
|
72
|
+
file_path.write_bytes(response.content)
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"""Extracts the .deb and .zip releases for the mscl library."""
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import subprocess
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
MSCL_VERSION = "v67.0.0"
|
|
8
|
+
"""The mscl version to extract."""
|
|
9
|
+
|
|
10
|
+
class ReleaseExtractor:
|
|
11
|
+
"""Will extract the .deb and .zip releases for the mscl library."""
|
|
12
|
+
|
|
13
|
+
def __init__(self):
|
|
14
|
+
self.asset_dir = Path("mscl_release_assets")
|
|
15
|
+
|
|
16
|
+
def extract_assets(self):
|
|
17
|
+
"""Extracts the .deb and .zip releases into the same directory."""
|
|
18
|
+
|
|
19
|
+
for file in self.asset_dir.iterdir():
|
|
20
|
+
if file.suffix == ".deb":
|
|
21
|
+
self.extract_deb(file)
|
|
22
|
+
elif file.suffix == ".zip":
|
|
23
|
+
self.extract_zip(file)
|
|
24
|
+
|
|
25
|
+
def extract_deb(self, file: Path):
|
|
26
|
+
"""Extracts the .deb release."""
|
|
27
|
+
cwd = Path().cwd()
|
|
28
|
+
|
|
29
|
+
# Create a directory to extract the .deb file. Syntax: mscl-<arch>-<python-ver>-<mscl-ver>
|
|
30
|
+
parts = file.stem.split("_")
|
|
31
|
+
arch, py_ver = parts[1], parts[2]
|
|
32
|
+
mscl_versioned_name = f"mscl-{arch}-{py_ver}-{MSCL_VERSION}"
|
|
33
|
+
mscl_versioned_dir = cwd / self.asset_dir / mscl_versioned_name
|
|
34
|
+
|
|
35
|
+
# If output directory exists, remove it:
|
|
36
|
+
if mscl_versioned_dir.exists():
|
|
37
|
+
os.system(f"rm -rf {mscl_versioned_dir}")
|
|
38
|
+
|
|
39
|
+
mscl_versioned_dir.mkdir(parents=True, exist_ok=True)
|
|
40
|
+
file_relative = file.absolute().relative_to(mscl_versioned_dir, walk_up=True)
|
|
41
|
+
|
|
42
|
+
# Extract the .deb file
|
|
43
|
+
subprocess.run(["ar", "x", str(file_relative)], cwd=mscl_versioned_dir, check=True)
|
|
44
|
+
|
|
45
|
+
# Extract the data.tar.gz file:
|
|
46
|
+
data_tar = "data.tar.gz"
|
|
47
|
+
|
|
48
|
+
subprocess.run(["tar", "-xzf", data_tar], cwd=mscl_versioned_dir, check=True)
|
|
49
|
+
|
|
50
|
+
found_mscl_py = list(mscl_versioned_dir.rglob("mscl.py"))
|
|
51
|
+
found_mscl_so = list(mscl_versioned_dir.rglob("_mscl.so"))
|
|
52
|
+
|
|
53
|
+
if not found_mscl_py or not found_mscl_so:
|
|
54
|
+
raise FileNotFoundError(f"Could not find mscl.py or _mscl.so in {mscl_versioned_dir}")
|
|
55
|
+
|
|
56
|
+
# Move the extracted files to the root of the mscl_versioned_dir:
|
|
57
|
+
mscl_py = found_mscl_py[0]
|
|
58
|
+
mscl_so = found_mscl_so[0]
|
|
59
|
+
|
|
60
|
+
mscl_py.rename(mscl_versioned_dir / mscl_py.name)
|
|
61
|
+
mscl_so.rename(mscl_versioned_dir / mscl_so.name)
|
|
62
|
+
|
|
63
|
+
# Delete the remaining files in mscl_versioned_dir:
|
|
64
|
+
for f in mscl_versioned_dir.iterdir():
|
|
65
|
+
if f.stem in (mscl_py.stem, mscl_so.stem):
|
|
66
|
+
continue
|
|
67
|
+
if f.is_dir():
|
|
68
|
+
os.system(f"rm -rf {f}")
|
|
69
|
+
else:
|
|
70
|
+
f.unlink()
|
|
71
|
+
|
|
72
|
+
def extract_zip(self, file: Path) -> None:
|
|
73
|
+
"""Extracts the .zip release."""
|
|
74
|
+
|
|
75
|
+
cwd = Path().cwd()
|
|
76
|
+
|
|
77
|
+
# Create a directory to extract the .zip file. Syntax: mscl-<arch>-<python-ver>-<mscl-ver>
|
|
78
|
+
parts = file.stem.split("_")
|
|
79
|
+
arch, py_ver = parts[2], parts[3]
|
|
80
|
+
mscl_versioned_name = f"mscl-Windows-{arch}-{py_ver}-{MSCL_VERSION}"
|
|
81
|
+
mscl_versioned_dir = cwd / self.asset_dir / mscl_versioned_name
|
|
82
|
+
|
|
83
|
+
# If output directory exists, remove it:
|
|
84
|
+
if mscl_versioned_dir.exists():
|
|
85
|
+
os.system(f"rm -rf {mscl_versioned_dir}")
|
|
86
|
+
|
|
87
|
+
mscl_versioned_dir.mkdir(parents=True, exist_ok=True)
|
|
88
|
+
file_relative = file.absolute().relative_to(mscl_versioned_dir, walk_up=True)
|
|
89
|
+
|
|
90
|
+
# Extract the .zip file
|
|
91
|
+
subprocess.run(["unzip", str(file_relative)], cwd=mscl_versioned_dir, check=True) # noqa: S603, S607
|
|
92
|
+
|
|
93
|
+
found_mscl_py = list(mscl_versioned_dir.rglob("mscl.py"))
|
|
94
|
+
found_mscl_pyd = list(mscl_versioned_dir.rglob("_mscl.pyd"))
|
|
95
|
+
|
|
96
|
+
if not found_mscl_py or not found_mscl_pyd:
|
|
97
|
+
raise FileNotFoundError(f"Could not find mscl.py or _mscl.pyd in {mscl_versioned_dir}")
|
|
98
|
+
|
|
99
|
+
# Move the extracted files to the root of the mscl_versioned_dir:
|
|
100
|
+
mscl_py = found_mscl_py[0]
|
|
101
|
+
mscl_pyd = found_mscl_pyd[0]
|
|
102
|
+
|
|
103
|
+
mscl_py.rename(mscl_versioned_dir / mscl_py.name)
|
|
104
|
+
mscl_pyd.rename(mscl_versioned_dir / mscl_pyd.name)
|
|
105
|
+
|
|
106
|
+
# Delete the remaining files in mscl_versioned_dir:
|
|
107
|
+
for f in mscl_versioned_dir.iterdir():
|
|
108
|
+
if f.stem in (mscl_py.stem, mscl_pyd.stem):
|
|
109
|
+
continue
|
|
110
|
+
if f.is_dir():
|
|
111
|
+
os.system(f"rm -rf {f}")
|
|
112
|
+
else:
|
|
113
|
+
f.unlink()
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"""Specifies a hatch build hook to create the wheel for mscl."""
|
|
2
|
+
|
|
3
|
+
import platform
|
|
4
|
+
import shutil
|
|
5
|
+
import sys
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
sys.path.insert(0, str(Path(__file__).parent))
|
|
9
|
+
|
|
10
|
+
from hatchling.builders.hooks.plugin.interface import BuildHookInterface
|
|
11
|
+
|
|
12
|
+
from build_helpers.release_downloader import GithubDownloader
|
|
13
|
+
|
|
14
|
+
MSCL_VERSION = "v67.0.0"
|
|
15
|
+
"""The mscl version to build the wheels of."""
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class CustomBuildHook(BuildHookInterface):
|
|
19
|
+
"""Build hook to build wheels from the extracted .deb/.zip files."""
|
|
20
|
+
|
|
21
|
+
def _python_tag(self) -> str:
|
|
22
|
+
"""Generate the Python tag (e.g., py39 for Python 3.9)."""
|
|
23
|
+
major = sys.version_info.major
|
|
24
|
+
minor = sys.version_info.minor
|
|
25
|
+
return f"cp{major}{minor}"
|
|
26
|
+
|
|
27
|
+
def _platform_tag(self) -> str:
|
|
28
|
+
"""Generate the platform tag (e.g., linux_x86_64)."""
|
|
29
|
+
return platform.system().lower() + "_" + platform.machine()
|
|
30
|
+
|
|
31
|
+
def initialize(self, version, build_data):
|
|
32
|
+
"""
|
|
33
|
+
Called before building the wheel/sdist.
|
|
34
|
+
We can download & extract the .deb here, and place
|
|
35
|
+
mscl.py and _mscl.so into src/mscl_pip/.
|
|
36
|
+
"""
|
|
37
|
+
if self.target_name != "wheel":
|
|
38
|
+
return
|
|
39
|
+
|
|
40
|
+
build_data["pure_python"] = False
|
|
41
|
+
self.app.display_info(f"Running on {version=} and {build_data=}")
|
|
42
|
+
self.app.display_info(self.target_name)
|
|
43
|
+
|
|
44
|
+
# --- STEP 1: Determine which python version and arch we are on: ---
|
|
45
|
+
# a) Python version:
|
|
46
|
+
# syntax: Python<MAJOR>.<MINOR>
|
|
47
|
+
|
|
48
|
+
py_version = f"Python{sys.version_info.major}.{sys.version_info.minor}"
|
|
49
|
+
|
|
50
|
+
# b) Architecture:
|
|
51
|
+
# possible values: amd64, arm64, armhf.
|
|
52
|
+
|
|
53
|
+
arch = platform.machine()
|
|
54
|
+
if arch == "x86_64":
|
|
55
|
+
mscl_arch = "amd64"
|
|
56
|
+
elif arch == "aarch64":
|
|
57
|
+
mscl_arch = "arm64"
|
|
58
|
+
elif arch == "armv7l":
|
|
59
|
+
mscl_arch = "armhf"
|
|
60
|
+
elif arch == "AMD64": # Windows
|
|
61
|
+
mscl_arch = "x64"
|
|
62
|
+
elif arch == "x86": # Windows
|
|
63
|
+
mscl_arch = "x86"
|
|
64
|
+
else:
|
|
65
|
+
raise RuntimeError(f"Unknown architecture: {arch}")
|
|
66
|
+
|
|
67
|
+
# --- STEP 2: Download the 2 mscl files (mscl.py and _mscl.so) from the git repo: ---
|
|
68
|
+
# Folder name: mscl-<mscl_arch>-<python-ver>-<mscl-ver> -> Linux
|
|
69
|
+
# Folder name: mscl-Windows-<mscl_arch>-<python-ver>-<mscl-ver> -> Windows
|
|
70
|
+
|
|
71
|
+
# a) Create the folder name:
|
|
72
|
+
|
|
73
|
+
if platform.system() == "Linux":
|
|
74
|
+
build_data["tag"] = f"{self._python_tag()}-{self._python_tag()}-{self._platform_tag()}"
|
|
75
|
+
folder_name = f"mscl-{mscl_arch}-{py_version}-{MSCL_VERSION}"
|
|
76
|
+
|
|
77
|
+
# Windows is best effort matching since there's only python 3.11 available for v67.0.0:
|
|
78
|
+
else:
|
|
79
|
+
if mscl_arch == "x64":
|
|
80
|
+
build_data["tag"] = "py3-none-win_amd64"
|
|
81
|
+
elif mscl_arch == "x86":
|
|
82
|
+
build_data["tag"] = "py3-none-win32"
|
|
83
|
+
folder_name = f"mscl-Windows-{mscl_arch}-Python3.11-{MSCL_VERSION}"
|
|
84
|
+
|
|
85
|
+
# b) Use PyGithub to download the files from the folder:
|
|
86
|
+
self.app.display_waiting(f"Downloading files for {folder_name}...")
|
|
87
|
+
|
|
88
|
+
gh = GithubDownloader()
|
|
89
|
+
gh.download_assets_from_folder(
|
|
90
|
+
tag=MSCL_VERSION,
|
|
91
|
+
folder_name=f"mscl_release_assets/{folder_name}",
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
self.app.display_success("Downloaded files successfully.")
|
|
95
|
+
|
|
96
|
+
# --- STEP 3: Copy the files ("_mscl.so" & "mscl.py") to the src/mscl/ directory: ---
|
|
97
|
+
# Move from root (i.e. cwd) to src/mscl
|
|
98
|
+
# Use shutil.move() to move the files.
|
|
99
|
+
|
|
100
|
+
self.remove_existing_files(Path("src/python_mscl/"), ["_mscl.so", "_mscl.pyd", "mscl.py"])
|
|
101
|
+
shutil.move("mscl.py", "src/python_mscl/")
|
|
102
|
+
if platform.system() == "Windows":
|
|
103
|
+
shutil.move("_mscl.pyd", "src/python_mscl/")
|
|
104
|
+
build_data["artifacts"] = ["_mscl.pyd", "mscl.py"]
|
|
105
|
+
else:
|
|
106
|
+
shutil.move("_mscl.so", "src/python_mscl/")
|
|
107
|
+
build_data["artifacts"] = ["_mscl.so", "mscl.py"]
|
|
108
|
+
|
|
109
|
+
self.app.display_success("Moved files to src/python_mscl/ successfully. Building wheel...")
|
|
110
|
+
|
|
111
|
+
def remove_existing_files(self, directory: Path, files: list[str]) -> None:
|
|
112
|
+
"""Remove the existing files from the directory."""
|
|
113
|
+
for file in files:
|
|
114
|
+
file_path = directory / file
|
|
115
|
+
if file_path.exists():
|
|
116
|
+
file_path.unlink()
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "python-mscl"
|
|
3
|
+
version = "67.0.0"
|
|
4
|
+
description = "Easy to install python wrapper for the MSCL library."
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
authors = [
|
|
7
|
+
{ name = "Harshil", email = "37377066+harshil21@users.noreply.github.com" }
|
|
8
|
+
]
|
|
9
|
+
requires-python = ">=3.9"
|
|
10
|
+
classifiers = [
|
|
11
|
+
"Development Status :: 4 - Beta",
|
|
12
|
+
"Intended Audience :: Developers",
|
|
13
|
+
"License :: OSI Approved :: MIT License",
|
|
14
|
+
"Programming Language :: Python :: 3",
|
|
15
|
+
"Programming Language :: Python :: 3.9",
|
|
16
|
+
"Programming Language :: Python :: 3.10",
|
|
17
|
+
"Programming Language :: Python :: 3.11",
|
|
18
|
+
"Programming Language :: Python :: 3.12",
|
|
19
|
+
"Programming Language :: Python :: 3.13",
|
|
20
|
+
"Topic :: Scientific/Engineering",
|
|
21
|
+
"Intended Audience :: Developers",
|
|
22
|
+
]
|
|
23
|
+
dependencies = []
|
|
24
|
+
|
|
25
|
+
[dependency-groups]
|
|
26
|
+
dev = ["ruff", "hatchling"]
|
|
27
|
+
|
|
28
|
+
[tool.hatch.build.targets.wheel]
|
|
29
|
+
packages = ["src/python_mscl"]
|
|
30
|
+
|
|
31
|
+
[tool.hatch.build.hooks.custom]
|
|
32
|
+
path = "hatch_build.py"
|
|
33
|
+
|
|
34
|
+
[tool.hatch.build.targets.sdist]
|
|
35
|
+
exclude = ["mscl_release_assets/", "uv.lock", "main.py", "src/python_mscl/_mscl.so",
|
|
36
|
+
"src/python_mscl/mscl.py"]
|
|
37
|
+
|
|
38
|
+
[build-system]
|
|
39
|
+
requires = ["hatchling", "requests", "pygithub"]
|
|
40
|
+
build-backend = "hatchling.build"
|
|
41
|
+
|
|
42
|
+
# [[tool.uv.index]]
|
|
43
|
+
# name = "testpypi"
|
|
44
|
+
# url = "https://test.pypi.org/simple/"
|
|
45
|
+
# publish-url = "https://test.pypi.org/legacy/"
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
# RUFF:
|
|
49
|
+
[tool.ruff]
|
|
50
|
+
line-length = 100
|
|
51
|
+
target-version = "py39"
|
|
52
|
+
show-fixes = true
|
|
53
|
+
exclude = ["mscl_release_assets/"]
|
|
54
|
+
|
|
55
|
+
[tool.ruff.lint]
|
|
56
|
+
ignore = ["ISC001", "S603", "S605", "S607", "PLR0912"]
|
|
57
|
+
select = ["E", "F", "I", "PL", "UP", "RUF", "PTH", "C4", "B", "PIE", "SIM", "RET", "RSE",
|
|
58
|
+
"G", "ISC", "PT", "ASYNC", "TCH", "SLOT", "PERF", "PYI", "FLY", "AIR", "Q", "INP",
|
|
59
|
+
"W", "YTT", "DTZ", "ARG", "T20", "FURB", "D100", "D101", "D300", "D418",
|
|
60
|
+
"D419", "S", "NPY"]
|
|
File without changes
|