fitsolver-client 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.
- fitsolver_client-0.1.0/PKG-INFO +103 -0
- fitsolver_client-0.1.0/README.md +88 -0
- fitsolver_client-0.1.0/fitsolver_client/__init__.py +128 -0
- fitsolver_client-0.1.0/fitsolver_client.egg-info/PKG-INFO +103 -0
- fitsolver_client-0.1.0/fitsolver_client.egg-info/SOURCES.txt +8 -0
- fitsolver_client-0.1.0/fitsolver_client.egg-info/dependency_links.txt +1 -0
- fitsolver_client-0.1.0/fitsolver_client.egg-info/top_level.txt +1 -0
- fitsolver_client-0.1.0/pyproject.toml +32 -0
- fitsolver_client-0.1.0/setup.cfg +4 -0
- fitsolver_client-0.1.0/setup.py +23 -0
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: fitsolver-client
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Minimal ctypes client for the FitSolver C ABI (fitsolver_lib)
|
|
5
|
+
Author: Fantastic Division
|
|
6
|
+
Project-URL: Homepage, https://github.com/FantasticDivision/Solver
|
|
7
|
+
Project-URL: Source, https://github.com/FantasticDivision/Solver
|
|
8
|
+
Keywords: bin-packing,packing,fitsolver,logistics
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Topic :: Scientific/Engineering
|
|
13
|
+
Requires-Python: >=3.9
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
|
|
16
|
+
# fitsolver-client
|
|
17
|
+
|
|
18
|
+
A minimal, dependency-free `ctypes` client for the FitSolver C ABI
|
|
19
|
+
(`fitsolver_lib`). JSON in, JSON out -- the same contract as
|
|
20
|
+
`fitsolver.solve()`, but without needing a compiled CPython extension.
|
|
21
|
+
|
|
22
|
+
## Install
|
|
23
|
+
|
|
24
|
+
### As a normal dependency (portal team, deployments)
|
|
25
|
+
|
|
26
|
+
Released wheels **vendor the native `fitsolver_lib`** inside the package,
|
|
27
|
+
so there is nothing else to build or configure:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
pip install fitsolver-client
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
# requirements.txt / pyproject.toml
|
|
35
|
+
fitsolver-client==0.1.0
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
One wheel is published per OS (Linux `manylinux_2_28`, macOS x86_64 +
|
|
39
|
+
arm64, Windows x64); each is valid for every Python >= 3.9. See
|
|
40
|
+
`.github/workflows/wheels.yml` for how they are built and published.
|
|
41
|
+
|
|
42
|
+
### From a local checkout (multi-repo development)
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
pip install -e path/to/FantasticSolver/python/fitsolver_client \
|
|
46
|
+
--config-settings editable_mode=compat
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
`editable_mode=compat` writes a plain-path `.pth` instead of an import
|
|
50
|
+
hook, so editors / Pylance resolve `import fitsolver_client` statically.
|
|
51
|
+
An editable install has no vendored library; it uses your local `build/`
|
|
52
|
+
(see below), so a `cmake --build` is picked up with no reinstall.
|
|
53
|
+
|
|
54
|
+
## The shared library
|
|
55
|
+
|
|
56
|
+
Resolution order at the first `solve()` call:
|
|
57
|
+
|
|
58
|
+
1. `FITSOLVER_LIB_PATH` -- exact path to the `.dll` / `.so` / `.dylib`.
|
|
59
|
+
2. `FITSOLVER_REPO_ROOT` -- looked up under `<root>/build/`.
|
|
60
|
+
3. A `build/` directory found by walking up from this package's location
|
|
61
|
+
(covers `pip install -e` from inside a FitSolver checkout).
|
|
62
|
+
4. `fitsolver_client/_libs/` -- the copy vendored into a release wheel.
|
|
63
|
+
|
|
64
|
+
Importing the package never fails on its own; only `solve()` does, with
|
|
65
|
+
`SolverUnavailableError`, if none of the above resolve.
|
|
66
|
+
|
|
67
|
+
To build the library for a local checkout:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
cmake -B build
|
|
71
|
+
cmake --build build --config Release --target fitsolver_lib
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Building a wheel by hand
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
cmake --build build --config Release --target fitsolver_lib
|
|
78
|
+
python python/fitsolver_client/tools/vendor_lib.py --build-dir build
|
|
79
|
+
python -m build --wheel python/fitsolver_client
|
|
80
|
+
# optional: normalise the tag to py3-none-<platform>
|
|
81
|
+
python -m wheel tags --python-tag py3 --abi-tag none \
|
|
82
|
+
--platform-tag win_amd64 --remove python/fitsolver_client/dist/*.whl
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Usage
|
|
86
|
+
|
|
87
|
+
```python
|
|
88
|
+
import fitsolver_client
|
|
89
|
+
|
|
90
|
+
response = fitsolver_client.solve({
|
|
91
|
+
"items": [
|
|
92
|
+
{"ItemCode": "ITM-001", "ItemReference": "Widget A",
|
|
93
|
+
"Width": 100, "Length": 200, "Depth": 50, "Weight": 1.0},
|
|
94
|
+
],
|
|
95
|
+
"boxes": [
|
|
96
|
+
{"Reference": "SML", "Width": 150, "Length": 150, "Depth": 150,
|
|
97
|
+
"MaxWeight": 8.5},
|
|
98
|
+
],
|
|
99
|
+
})
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
See the FitSolver README's "Request / response JSON schema" section for the
|
|
103
|
+
exact shape of the request and response dicts.
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# fitsolver-client
|
|
2
|
+
|
|
3
|
+
A minimal, dependency-free `ctypes` client for the FitSolver C ABI
|
|
4
|
+
(`fitsolver_lib`). JSON in, JSON out -- the same contract as
|
|
5
|
+
`fitsolver.solve()`, but without needing a compiled CPython extension.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
### As a normal dependency (portal team, deployments)
|
|
10
|
+
|
|
11
|
+
Released wheels **vendor the native `fitsolver_lib`** inside the package,
|
|
12
|
+
so there is nothing else to build or configure:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
pip install fitsolver-client
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
# requirements.txt / pyproject.toml
|
|
20
|
+
fitsolver-client==0.1.0
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
One wheel is published per OS (Linux `manylinux_2_28`, macOS x86_64 +
|
|
24
|
+
arm64, Windows x64); each is valid for every Python >= 3.9. See
|
|
25
|
+
`.github/workflows/wheels.yml` for how they are built and published.
|
|
26
|
+
|
|
27
|
+
### From a local checkout (multi-repo development)
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
pip install -e path/to/FantasticSolver/python/fitsolver_client \
|
|
31
|
+
--config-settings editable_mode=compat
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
`editable_mode=compat` writes a plain-path `.pth` instead of an import
|
|
35
|
+
hook, so editors / Pylance resolve `import fitsolver_client` statically.
|
|
36
|
+
An editable install has no vendored library; it uses your local `build/`
|
|
37
|
+
(see below), so a `cmake --build` is picked up with no reinstall.
|
|
38
|
+
|
|
39
|
+
## The shared library
|
|
40
|
+
|
|
41
|
+
Resolution order at the first `solve()` call:
|
|
42
|
+
|
|
43
|
+
1. `FITSOLVER_LIB_PATH` -- exact path to the `.dll` / `.so` / `.dylib`.
|
|
44
|
+
2. `FITSOLVER_REPO_ROOT` -- looked up under `<root>/build/`.
|
|
45
|
+
3. A `build/` directory found by walking up from this package's location
|
|
46
|
+
(covers `pip install -e` from inside a FitSolver checkout).
|
|
47
|
+
4. `fitsolver_client/_libs/` -- the copy vendored into a release wheel.
|
|
48
|
+
|
|
49
|
+
Importing the package never fails on its own; only `solve()` does, with
|
|
50
|
+
`SolverUnavailableError`, if none of the above resolve.
|
|
51
|
+
|
|
52
|
+
To build the library for a local checkout:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
cmake -B build
|
|
56
|
+
cmake --build build --config Release --target fitsolver_lib
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Building a wheel by hand
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
cmake --build build --config Release --target fitsolver_lib
|
|
63
|
+
python python/fitsolver_client/tools/vendor_lib.py --build-dir build
|
|
64
|
+
python -m build --wheel python/fitsolver_client
|
|
65
|
+
# optional: normalise the tag to py3-none-<platform>
|
|
66
|
+
python -m wheel tags --python-tag py3 --abi-tag none \
|
|
67
|
+
--platform-tag win_amd64 --remove python/fitsolver_client/dist/*.whl
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Usage
|
|
71
|
+
|
|
72
|
+
```python
|
|
73
|
+
import fitsolver_client
|
|
74
|
+
|
|
75
|
+
response = fitsolver_client.solve({
|
|
76
|
+
"items": [
|
|
77
|
+
{"ItemCode": "ITM-001", "ItemReference": "Widget A",
|
|
78
|
+
"Width": 100, "Length": 200, "Depth": 50, "Weight": 1.0},
|
|
79
|
+
],
|
|
80
|
+
"boxes": [
|
|
81
|
+
{"Reference": "SML", "Width": 150, "Length": 150, "Depth": 150,
|
|
82
|
+
"MaxWeight": 8.5},
|
|
83
|
+
],
|
|
84
|
+
})
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
See the FitSolver README's "Request / response JSON schema" section for the
|
|
88
|
+
exact shape of the request and response dicts.
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"""Minimal ctypes client for the FitSolver C ABI (fitsolver_lib).
|
|
2
|
+
|
|
3
|
+
Deliberately thin: pure Python, no build step for the caller. A wheel
|
|
4
|
+
built for distribution vendors the native fitsolver_lib shared library
|
|
5
|
+
inside the package (fitsolver_client/_libs/), so `pip install
|
|
6
|
+
fitsolver-client` is self-contained -- no CMake, no env vars.
|
|
7
|
+
|
|
8
|
+
Library location is resolved in this order:
|
|
9
|
+
1. FITSOLVER_LIB_PATH env var, if set -- the exact file to load.
|
|
10
|
+
2. FITSOLVER_REPO_ROOT env var, if set -- look under <root>/build/.
|
|
11
|
+
3. A build/ directory found by walking up from this file's own
|
|
12
|
+
location -- covers `pip install -e` from inside a FitSolver
|
|
13
|
+
checkout (multi-repo dev: the live build/ wins over any vendored
|
|
14
|
+
copy so a rebuild is picked up immediately).
|
|
15
|
+
4. The _libs/ directory vendored into this package by the wheel build
|
|
16
|
+
-- the normal path for an installed (non-editable) release.
|
|
17
|
+
|
|
18
|
+
See example/python_example.py in the FitSolver repo for the original,
|
|
19
|
+
single-file version of this same pattern.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
import ctypes
|
|
23
|
+
import json
|
|
24
|
+
import os
|
|
25
|
+
import platform
|
|
26
|
+
from pathlib import Path
|
|
27
|
+
|
|
28
|
+
__all__ = ["solve", "SolverUnavailableError"]
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class SolverUnavailableError(RuntimeError):
|
|
32
|
+
"""Raised when the fitsolver_lib shared library can't be found or loaded."""
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def _library_filename() -> str:
|
|
36
|
+
return {
|
|
37
|
+
"Windows": "fitsolver_lib.dll",
|
|
38
|
+
"Darwin": "fitsolver_lib.dylib",
|
|
39
|
+
}.get(platform.system(), "fitsolver_lib.so")
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def _candidate_build_dirs() -> list[Path]:
|
|
43
|
+
candidates = []
|
|
44
|
+
|
|
45
|
+
repo_root = os.environ.get("FITSOLVER_REPO_ROOT")
|
|
46
|
+
if repo_root:
|
|
47
|
+
candidates.append(Path(repo_root) / "build")
|
|
48
|
+
|
|
49
|
+
# Walk up from this file looking for a sibling build/ directory.
|
|
50
|
+
here = Path(__file__).resolve()
|
|
51
|
+
candidates.extend(parent / "build" for parent in here.parents)
|
|
52
|
+
|
|
53
|
+
return candidates
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _bundled_library(filename: str) -> Path | None:
|
|
57
|
+
"""The copy a distribution wheel vendors next to this module. Absent
|
|
58
|
+
in an editable/source checkout -- populated only by the wheel build
|
|
59
|
+
(see tools/vendor_lib.py + pyproject.toml package-data)."""
|
|
60
|
+
candidate = Path(__file__).resolve().parent / "_libs" / filename
|
|
61
|
+
return candidate if candidate.is_file() else None
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def _find_library() -> Path:
|
|
65
|
+
explicit = os.environ.get("FITSOLVER_LIB_PATH")
|
|
66
|
+
if explicit:
|
|
67
|
+
path = Path(explicit)
|
|
68
|
+
if path.is_file():
|
|
69
|
+
return path
|
|
70
|
+
raise SolverUnavailableError(f"FITSOLVER_LIB_PATH is set but not a file: {explicit}")
|
|
71
|
+
|
|
72
|
+
filename = _library_filename()
|
|
73
|
+
|
|
74
|
+
# A live build/ from a dev checkout wins over the vendored copy, so a
|
|
75
|
+
# local `cmake --build` is picked up without reinstalling.
|
|
76
|
+
for build_dir in _candidate_build_dirs():
|
|
77
|
+
for sub in ("Release", "Debug", "."):
|
|
78
|
+
candidate = build_dir / sub / filename
|
|
79
|
+
if candidate.is_file():
|
|
80
|
+
return candidate
|
|
81
|
+
|
|
82
|
+
bundled = _bundled_library(filename)
|
|
83
|
+
if bundled is not None:
|
|
84
|
+
return bundled
|
|
85
|
+
|
|
86
|
+
raise SolverUnavailableError(
|
|
87
|
+
f"Could not find {filename}. Install a release wheel of "
|
|
88
|
+
"fitsolver-client (which vendors it), or build it in the FitSolver "
|
|
89
|
+
"repo (cmake -B build && cmake --build build --config Release "
|
|
90
|
+
"--target fitsolver_lib), or set FITSOLVER_LIB_PATH to its exact "
|
|
91
|
+
"location."
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
_lib: ctypes.CDLL | None = None
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def _get_lib() -> ctypes.CDLL:
|
|
99
|
+
# Loaded lazily (on first solve() call, not at import time) so
|
|
100
|
+
# importing this package never fails just because the DLL hasn't
|
|
101
|
+
# been built yet -- only actually calling solve() does.
|
|
102
|
+
global _lib
|
|
103
|
+
if _lib is None:
|
|
104
|
+
lib = ctypes.CDLL(str(_find_library()))
|
|
105
|
+
lib.fitsolver_solve.argtypes = [ctypes.c_char_p]
|
|
106
|
+
lib.fitsolver_solve.restype = ctypes.c_void_p
|
|
107
|
+
lib.fitsolver_free.argtypes = [ctypes.c_void_p]
|
|
108
|
+
_lib = lib
|
|
109
|
+
return _lib
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def solve(request: dict) -> dict:
|
|
113
|
+
"""Sends a {"items": [...], "boxes": [...]} request through the
|
|
114
|
+
fitsolver_lib C ABI and returns the parsed JSON response as a dict.
|
|
115
|
+
|
|
116
|
+
See the FitSolver README's "Request / response JSON schema" section
|
|
117
|
+
for the exact shape of `request` and the returned dict.
|
|
118
|
+
"""
|
|
119
|
+
lib = _get_lib()
|
|
120
|
+
request_bytes = json.dumps(request).encode("utf-8")
|
|
121
|
+
response_ptr = lib.fitsolver_solve(request_bytes)
|
|
122
|
+
try:
|
|
123
|
+
# c_void_p (not c_char_p) on the ctypes signature so we keep the
|
|
124
|
+
# real pointer and can correctly free it afterwards.
|
|
125
|
+
response_bytes = ctypes.cast(response_ptr, ctypes.c_char_p).value
|
|
126
|
+
return json.loads(response_bytes.decode("utf-8"))
|
|
127
|
+
finally:
|
|
128
|
+
lib.fitsolver_free(response_ptr)
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: fitsolver-client
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Minimal ctypes client for the FitSolver C ABI (fitsolver_lib)
|
|
5
|
+
Author: Fantastic Division
|
|
6
|
+
Project-URL: Homepage, https://github.com/FantasticDivision/Solver
|
|
7
|
+
Project-URL: Source, https://github.com/FantasticDivision/Solver
|
|
8
|
+
Keywords: bin-packing,packing,fitsolver,logistics
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Topic :: Scientific/Engineering
|
|
13
|
+
Requires-Python: >=3.9
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
|
|
16
|
+
# fitsolver-client
|
|
17
|
+
|
|
18
|
+
A minimal, dependency-free `ctypes` client for the FitSolver C ABI
|
|
19
|
+
(`fitsolver_lib`). JSON in, JSON out -- the same contract as
|
|
20
|
+
`fitsolver.solve()`, but without needing a compiled CPython extension.
|
|
21
|
+
|
|
22
|
+
## Install
|
|
23
|
+
|
|
24
|
+
### As a normal dependency (portal team, deployments)
|
|
25
|
+
|
|
26
|
+
Released wheels **vendor the native `fitsolver_lib`** inside the package,
|
|
27
|
+
so there is nothing else to build or configure:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
pip install fitsolver-client
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
# requirements.txt / pyproject.toml
|
|
35
|
+
fitsolver-client==0.1.0
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
One wheel is published per OS (Linux `manylinux_2_28`, macOS x86_64 +
|
|
39
|
+
arm64, Windows x64); each is valid for every Python >= 3.9. See
|
|
40
|
+
`.github/workflows/wheels.yml` for how they are built and published.
|
|
41
|
+
|
|
42
|
+
### From a local checkout (multi-repo development)
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
pip install -e path/to/FantasticSolver/python/fitsolver_client \
|
|
46
|
+
--config-settings editable_mode=compat
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
`editable_mode=compat` writes a plain-path `.pth` instead of an import
|
|
50
|
+
hook, so editors / Pylance resolve `import fitsolver_client` statically.
|
|
51
|
+
An editable install has no vendored library; it uses your local `build/`
|
|
52
|
+
(see below), so a `cmake --build` is picked up with no reinstall.
|
|
53
|
+
|
|
54
|
+
## The shared library
|
|
55
|
+
|
|
56
|
+
Resolution order at the first `solve()` call:
|
|
57
|
+
|
|
58
|
+
1. `FITSOLVER_LIB_PATH` -- exact path to the `.dll` / `.so` / `.dylib`.
|
|
59
|
+
2. `FITSOLVER_REPO_ROOT` -- looked up under `<root>/build/`.
|
|
60
|
+
3. A `build/` directory found by walking up from this package's location
|
|
61
|
+
(covers `pip install -e` from inside a FitSolver checkout).
|
|
62
|
+
4. `fitsolver_client/_libs/` -- the copy vendored into a release wheel.
|
|
63
|
+
|
|
64
|
+
Importing the package never fails on its own; only `solve()` does, with
|
|
65
|
+
`SolverUnavailableError`, if none of the above resolve.
|
|
66
|
+
|
|
67
|
+
To build the library for a local checkout:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
cmake -B build
|
|
71
|
+
cmake --build build --config Release --target fitsolver_lib
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Building a wheel by hand
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
cmake --build build --config Release --target fitsolver_lib
|
|
78
|
+
python python/fitsolver_client/tools/vendor_lib.py --build-dir build
|
|
79
|
+
python -m build --wheel python/fitsolver_client
|
|
80
|
+
# optional: normalise the tag to py3-none-<platform>
|
|
81
|
+
python -m wheel tags --python-tag py3 --abi-tag none \
|
|
82
|
+
--platform-tag win_amd64 --remove python/fitsolver_client/dist/*.whl
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Usage
|
|
86
|
+
|
|
87
|
+
```python
|
|
88
|
+
import fitsolver_client
|
|
89
|
+
|
|
90
|
+
response = fitsolver_client.solve({
|
|
91
|
+
"items": [
|
|
92
|
+
{"ItemCode": "ITM-001", "ItemReference": "Widget A",
|
|
93
|
+
"Width": 100, "Length": 200, "Depth": 50, "Weight": 1.0},
|
|
94
|
+
],
|
|
95
|
+
"boxes": [
|
|
96
|
+
{"Reference": "SML", "Width": 150, "Length": 150, "Depth": 150,
|
|
97
|
+
"MaxWeight": 8.5},
|
|
98
|
+
],
|
|
99
|
+
})
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
See the FitSolver README's "Request / response JSON schema" section for the
|
|
103
|
+
exact shape of the request and response dicts.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
fitsolver_client
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "fitsolver-client"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "Minimal ctypes client for the FitSolver C ABI (fitsolver_lib)"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.9"
|
|
7
|
+
dependencies = []
|
|
8
|
+
authors = [{ name = "Fantastic Division" }]
|
|
9
|
+
keywords = ["bin-packing", "packing", "fitsolver", "logistics"]
|
|
10
|
+
classifiers = [
|
|
11
|
+
"Programming Language :: Python :: 3",
|
|
12
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
13
|
+
"Intended Audience :: Developers",
|
|
14
|
+
"Topic :: Scientific/Engineering",
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
[project.urls]
|
|
18
|
+
Homepage = "https://github.com/FantasticDivision/Solver"
|
|
19
|
+
Source = "https://github.com/FantasticDivision/Solver"
|
|
20
|
+
|
|
21
|
+
[tool.setuptools]
|
|
22
|
+
packages = ["fitsolver_client"]
|
|
23
|
+
|
|
24
|
+
[tool.setuptools.package-data]
|
|
25
|
+
# The native library is vendored here by the wheel build (tools/vendor_lib.py).
|
|
26
|
+
# A source tree / editable install has no _libs/ dir and falls back to a
|
|
27
|
+
# local build/ or FITSOLVER_LIB_PATH -- see fitsolver_client/__init__.py.
|
|
28
|
+
fitsolver_client = ["_libs/*.dll", "_libs/*.so", "_libs/*.so.*", "_libs/*.dylib"]
|
|
29
|
+
|
|
30
|
+
[build-system]
|
|
31
|
+
requires = ["setuptools>=61", "wheel"]
|
|
32
|
+
build-backend = "setuptools.build_meta"
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"""Metadata lives in pyproject.toml; this shim exists only to force a
|
|
2
|
+
platform-specific wheel tag.
|
|
3
|
+
|
|
4
|
+
fitsolver-client is pure Python, but a built wheel vendors a native
|
|
5
|
+
.dll/.so/.dylib under fitsolver_client/_libs/. Without this, setuptools
|
|
6
|
+
would tag the wheel `py3-none-any` and pip on Linux would happily install
|
|
7
|
+
the Windows binary. Declaring the distribution non-pure makes bdist_wheel
|
|
8
|
+
emit `py3-none-<platform>` instead -- one wheel per OS, still valid for
|
|
9
|
+
every Python 3.x (ctypes has no ABI dependency).
|
|
10
|
+
|
|
11
|
+
An editable / sdist install builds no _libs/ dir and this is harmless.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from setuptools import setup
|
|
15
|
+
from setuptools.dist import Distribution
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class _BinaryDistribution(Distribution):
|
|
19
|
+
def has_ext_modules(self) -> bool: # noqa: D102
|
|
20
|
+
return True
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
setup(distclass=_BinaryDistribution)
|