mflux-web 0.0.1a1__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,106 @@
1
+ Metadata-Version: 2.3
2
+ Name: mflux-web
3
+ Version: 0.0.1a1
4
+ Summary: Web integration for mflux with a standalone Python API
5
+ Author: Anthony Wu
6
+ Author-email: Anthony Wu <462072+anthonywu@users.noreply.github.com>
7
+ Classifier: Programming Language :: Python :: 3.11
8
+ Classifier: Programming Language :: Python :: 3.12
9
+ Classifier: Programming Language :: Python :: 3.13
10
+ Classifier: Programming Language :: Python :: 3.14
11
+ Classifier: Programming Language :: Python :: 3.15
12
+ Requires-Python: >=3.11
13
+ Description-Content-Type: text/markdown
14
+
15
+ # mflux-web
16
+
17
+ Install (once published):
18
+
19
+ ```sh
20
+ pip install mflux-web
21
+ ```
22
+
23
+ Both entry points resolve to the same module object:
24
+
25
+ ```python
26
+ import mflux.web
27
+ import mflux_web
28
+
29
+ assert mflux.web is mflux_web
30
+ ```
31
+
32
+ `mflux_web` owns the implementation and works without installing or importing
33
+ `mflux`. Importing `mflux.web` registers it as an alias of `mflux_web`, sharing
34
+ all public symbols and module state. Either import order works, and the greeting
35
+ prints once per process. Submodules are not automatically aliased; use
36
+ `mflux.web.<plugin>` for third-party plugins. This initial scaffold has no web
37
+ server or application API yet.
38
+
39
+ ## Namespace ownership
40
+
41
+ This distribution owns `mflux/web/__init__.py` and `mflux_web/`. It deliberately
42
+ does **not** ship `mflux/__init__.py` or require the inference distribution.
43
+ The `mflux.web` alias adds plugin directories discovered by `pkgutil.extend_path`
44
+ to the shared package path, so other distributions can contribute subpackages
45
+ even from separate import paths.
46
+
47
+ A plugin distribution can ship:
48
+
49
+ ```text
50
+ src/
51
+ └── mflux/
52
+ └── web/
53
+ └── anythingelse/
54
+ └── __init__.py
55
+ ```
56
+
57
+ With this uv build configuration:
58
+
59
+ ```toml
60
+ [project]
61
+ name = "mflux-web-anythingelse"
62
+ version = "0.1.0"
63
+ dependencies = ["mflux-web>=0.0.1a1"]
64
+
65
+ [build-system]
66
+ requires = ["uv_build>=0.12.15,<0.13.0"]
67
+ build-backend = "uv_build"
68
+
69
+ [tool.uv.build-backend]
70
+ module-name = "mflux.web.anythingelse"
71
+ ```
72
+
73
+ Consumers can then use `import mflux.web.anythingelse`. Plugins must not ship
74
+ `mflux/__init__.py` or `mflux/web/__init__.py`; each owns a unique child name.
75
+
76
+ ## Integration with the mflux parent
77
+
78
+ The existing mflux project has a regular `mflux/__init__.py`. Normal wheel
79
+ installations into the same site-packages directory coexist with this package.
80
+ For separate editable installs or other split-path layouts, add this to the
81
+ **mflux project's** existing `src/mflux/__init__.py`, retaining its current setup:
82
+
83
+ ```python
84
+ from pkgutil import extend_path
85
+
86
+ __path__ = extend_path(__path__, __name__)
87
+ ```
88
+
89
+ Without that parent change, an installed regular mflux package can hide an
90
+ editable mflux-web checkout. Setting `namespace = true` in build configuration
91
+ does not change Python's runtime import behavior. This repository does not
92
+ modify or replace the parent initializer.
93
+
94
+ ## Development
95
+
96
+ Use uv-managed Python 3.14 for development; the library supports Python 3.11–3.15.
97
+
98
+ ```sh
99
+ uv sync
100
+ uv build
101
+ uv run python -m unittest discover -s tests -v
102
+ ```
103
+
104
+ The tests build the distributions in a temporary directory and check their
105
+ contents and imports in isolated subprocesses, including third-party namespace
106
+ contributions and regular-parent coexistence.
@@ -0,0 +1,92 @@
1
+ # mflux-web
2
+
3
+ Install (once published):
4
+
5
+ ```sh
6
+ pip install mflux-web
7
+ ```
8
+
9
+ Both entry points resolve to the same module object:
10
+
11
+ ```python
12
+ import mflux.web
13
+ import mflux_web
14
+
15
+ assert mflux.web is mflux_web
16
+ ```
17
+
18
+ `mflux_web` owns the implementation and works without installing or importing
19
+ `mflux`. Importing `mflux.web` registers it as an alias of `mflux_web`, sharing
20
+ all public symbols and module state. Either import order works, and the greeting
21
+ prints once per process. Submodules are not automatically aliased; use
22
+ `mflux.web.<plugin>` for third-party plugins. This initial scaffold has no web
23
+ server or application API yet.
24
+
25
+ ## Namespace ownership
26
+
27
+ This distribution owns `mflux/web/__init__.py` and `mflux_web/`. It deliberately
28
+ does **not** ship `mflux/__init__.py` or require the inference distribution.
29
+ The `mflux.web` alias adds plugin directories discovered by `pkgutil.extend_path`
30
+ to the shared package path, so other distributions can contribute subpackages
31
+ even from separate import paths.
32
+
33
+ A plugin distribution can ship:
34
+
35
+ ```text
36
+ src/
37
+ └── mflux/
38
+ └── web/
39
+ └── anythingelse/
40
+ └── __init__.py
41
+ ```
42
+
43
+ With this uv build configuration:
44
+
45
+ ```toml
46
+ [project]
47
+ name = "mflux-web-anythingelse"
48
+ version = "0.1.0"
49
+ dependencies = ["mflux-web>=0.0.1a1"]
50
+
51
+ [build-system]
52
+ requires = ["uv_build>=0.12.15,<0.13.0"]
53
+ build-backend = "uv_build"
54
+
55
+ [tool.uv.build-backend]
56
+ module-name = "mflux.web.anythingelse"
57
+ ```
58
+
59
+ Consumers can then use `import mflux.web.anythingelse`. Plugins must not ship
60
+ `mflux/__init__.py` or `mflux/web/__init__.py`; each owns a unique child name.
61
+
62
+ ## Integration with the mflux parent
63
+
64
+ The existing mflux project has a regular `mflux/__init__.py`. Normal wheel
65
+ installations into the same site-packages directory coexist with this package.
66
+ For separate editable installs or other split-path layouts, add this to the
67
+ **mflux project's** existing `src/mflux/__init__.py`, retaining its current setup:
68
+
69
+ ```python
70
+ from pkgutil import extend_path
71
+
72
+ __path__ = extend_path(__path__, __name__)
73
+ ```
74
+
75
+ Without that parent change, an installed regular mflux package can hide an
76
+ editable mflux-web checkout. Setting `namespace = true` in build configuration
77
+ does not change Python's runtime import behavior. This repository does not
78
+ modify or replace the parent initializer.
79
+
80
+ ## Development
81
+
82
+ Use uv-managed Python 3.14 for development; the library supports Python 3.11–3.15.
83
+
84
+ ```sh
85
+ uv sync
86
+ uv build
87
+ uv run python -m unittest discover -s tests -v
88
+ ```
89
+
90
+ The tests build the distributions in a temporary directory and check their
91
+ contents and imports in isolated subprocesses, including third-party namespace
92
+ contributions and regular-parent coexistence.
@@ -0,0 +1,72 @@
1
+ [project]
2
+ name = "mflux-web"
3
+ version = "0.0.1a1"
4
+ description = "Web integration for mflux with a standalone Python API"
5
+ readme = "README.md"
6
+ requires-python = ">=3.11"
7
+ classifiers = [
8
+ "Programming Language :: Python :: 3.11",
9
+ "Programming Language :: Python :: 3.12",
10
+ "Programming Language :: Python :: 3.13",
11
+ "Programming Language :: Python :: 3.14",
12
+ "Programming Language :: Python :: 3.15",
13
+ ]
14
+ dependencies = []
15
+
16
+ [[project.authors]]
17
+ name = "Anthony Wu"
18
+ email = "462072+anthonywu@users.noreply.github.com"
19
+
20
+ [build-system]
21
+ requires = ["uv_build>=0.12.15,<0.13.0"]
22
+ build-backend = "uv_build"
23
+
24
+ [tool.uv.build-backend]
25
+ module-name = [
26
+ "mflux_web",
27
+ "mflux.web",
28
+ ]
29
+ source-include = ["tests/**"]
30
+
31
+ [tool.ruff]
32
+ target-version = "py311"
33
+ line-length = 88
34
+ src = ["src"]
35
+
36
+ [tool.ruff.lint]
37
+ select = [
38
+ "E4",
39
+ "E7",
40
+ "E9",
41
+ "F",
42
+ "I",
43
+ "UP",
44
+ "B",
45
+ "SIM",
46
+ "RUF",
47
+ ]
48
+
49
+ [tool.ruff.format]
50
+ quote-style = "double"
51
+ indent-style = "space"
52
+
53
+ [tool.ty.environment]
54
+ python-version = "3.11"
55
+
56
+ [tool.ty.src]
57
+ include = [
58
+ "src",
59
+ "tests",
60
+ ]
61
+
62
+ [tool.ty.rules]
63
+ unused-ignore-comment = "warn"
64
+
65
+ [tool.ty.terminal]
66
+ error-on-warning = true
67
+
68
+ [dependency-groups]
69
+ dev = [
70
+ "ruff>=0.16.9",
71
+ "ty>=0.0.84",
72
+ ]
@@ -0,0 +1,56 @@
1
+ [project]
2
+ name = "mflux-web"
3
+ version = "0.0.1a1"
4
+ description = "Web integration for mflux with a standalone Python API"
5
+ readme = "README.md"
6
+ authors = [
7
+ { name = "Anthony Wu", email = "462072+anthonywu@users.noreply.github.com" }
8
+ ]
9
+ requires-python = ">=3.11"
10
+ classifiers = [
11
+ "Programming Language :: Python :: 3.11",
12
+ "Programming Language :: Python :: 3.12",
13
+ "Programming Language :: Python :: 3.13",
14
+ "Programming Language :: Python :: 3.14",
15
+ "Programming Language :: Python :: 3.15",
16
+ ]
17
+ dependencies = []
18
+
19
+ [build-system]
20
+ requires = ["uv_build>=0.12.15,<0.13.0"]
21
+ build-backend = "uv_build"
22
+
23
+ [tool.uv.build-backend]
24
+ module-name = ["mflux_web", "mflux.web"]
25
+ source-include = ["tests/**"]
26
+
27
+ [tool.ruff]
28
+ target-version = "py311"
29
+ line-length = 88
30
+ src = ["src"]
31
+
32
+ [tool.ruff.lint]
33
+ # Core errors, import sorting, upgrades, bug risks, and simple cleanup.
34
+ select = ["E4", "E7", "E9", "F", "I", "UP", "B", "SIM", "RUF"]
35
+
36
+ [tool.ruff.format]
37
+ quote-style = "double"
38
+ indent-style = "space"
39
+
40
+ [tool.ty.environment]
41
+ python-version = "3.11"
42
+
43
+ [tool.ty.src]
44
+ include = ["src", "tests"]
45
+
46
+ [tool.ty.rules]
47
+ unused-ignore-comment = "warn"
48
+
49
+ [tool.ty.terminal]
50
+ error-on-warning = true
51
+
52
+ [dependency-groups]
53
+ dev = [
54
+ "ruff>=0.16.9",
55
+ "ty>=0.0.84",
56
+ ]
@@ -0,0 +1,13 @@
1
+ """Alias mflux.web to the standalone mflux_web package."""
2
+
3
+ import sys
4
+ from pkgutil import extend_path
5
+
6
+ import mflux_web
7
+
8
+ # Keep plugin directories discoverable after replacing this module with the alias.
9
+ for path in extend_path(__path__, __name__):
10
+ if path not in mflux_web.__path__:
11
+ mflux_web.__path__.append(path)
12
+
13
+ sys.modules[__name__] = mflux_web
@@ -0,0 +1,9 @@
1
+ """Standalone web API; importing this package does not import mflux."""
2
+
3
+ from importlib.metadata import version
4
+
5
+ __version__ = version("mflux-web")
6
+
7
+ __all__ = ["__version__"]
8
+
9
+ print("Hello from mflux-web library")
@@ -0,0 +1,131 @@
1
+ """Exercise built artifacts without relying on the editable source checkout."""
2
+
3
+ import os
4
+ import subprocess
5
+ import sys
6
+ import tempfile
7
+ import unittest
8
+ import zipfile
9
+ from pathlib import Path
10
+
11
+ ROOT = Path(__file__).resolve().parents[1]
12
+
13
+
14
+ class PackagingTests(unittest.TestCase):
15
+ @classmethod
16
+ def setUpClass(cls):
17
+ cls.temp = tempfile.TemporaryDirectory()
18
+ cls.addClassCleanup(cls.temp.cleanup)
19
+ cls.root = Path(cls.temp.name)
20
+ dist = cls.root / "dist"
21
+ subprocess.run(
22
+ ["uv", "build", "--out-dir", str(dist)],
23
+ cwd=ROOT,
24
+ check=True,
25
+ capture_output=True,
26
+ text=True,
27
+ )
28
+ cls.site = cls.root / "site"
29
+ with zipfile.ZipFile(next(dist.glob("*.whl"))) as wheel:
30
+ cls.members = wheel.namelist()
31
+ wheel.extractall(cls.site)
32
+
33
+ def run_imports(self, code, *paths):
34
+ # -I -S prevents the project's editable install and user site from leaking in.
35
+ setup = f"import sys; sys.path[:0] = {[str(p) for p in paths]!r}\n"
36
+ result = subprocess.run(
37
+ [sys.executable, "-I", "-S", "-c", setup + code],
38
+ check=False,
39
+ cwd=self.root,
40
+ capture_output=True,
41
+ text=True,
42
+ env={k: v for k, v in os.environ.items() if k != "PYTHONPATH"},
43
+ )
44
+ self.assertEqual(result.returncode, 0, result.stderr)
45
+ return result.stdout
46
+
47
+ def test_wheel_ownership(self):
48
+ self.assertIn("mflux/web/__init__.py", self.members)
49
+ self.assertIn("mflux_web/__init__.py", self.members)
50
+ self.assertNotIn("mflux/__init__.py", self.members)
51
+ self.assertFalse(any("mflux_web_pypi" in name for name in self.members))
52
+
53
+ def test_standalone_does_not_import_parent(self):
54
+ self.run_imports(
55
+ 'import mflux_web\nassert "mflux" not in sys.modules\n'
56
+ 'assert mflux_web.__version__ == "0.0.1a1"',
57
+ self.site,
58
+ )
59
+
60
+ def test_both_entry_points(self):
61
+ for imports in (
62
+ "import mflux.web\nimport mflux_web",
63
+ "import mflux_web\nimport mflux.web",
64
+ "from mflux import web\nimport mflux.web\nimport mflux_web",
65
+ ):
66
+ with self.subTest(imports=imports):
67
+ output = self.run_imports(
68
+ imports + "\n"
69
+ "assert mflux.web is mflux_web\n"
70
+ 'assert sys.modules["mflux.web"] is mflux_web\n'
71
+ "mflux.web.shared_value = 42\n"
72
+ "assert mflux_web.shared_value == 42",
73
+ self.site,
74
+ )
75
+ self.assertEqual(output, "Hello from mflux-web library\n")
76
+
77
+ def test_plugin_on_separate_path(self):
78
+ plugin_root = self.root / "plugin"
79
+ plugin = plugin_root / "mflux/web/anythingelse"
80
+ plugin.mkdir(parents=True)
81
+ (plugin / "__init__.py").write_text("VALUE = 42\n")
82
+ self.run_imports(
83
+ "import mflux.web.anythingelse, mflux_web\n"
84
+ "assert mflux.web is mflux_web\n"
85
+ "assert mflux.web.anythingelse.VALUE == 42\n"
86
+ "assert mflux_web.anythingelse is mflux.web.anythingelse",
87
+ self.site,
88
+ plugin_root,
89
+ )
90
+
91
+ def test_regular_parent_in_same_site(self):
92
+ import shutil
93
+
94
+ site = self.root / "coinstalled"
95
+ shutil.copytree(self.site, site)
96
+ (site / "mflux/__init__.py").write_text("PARENT = True\n")
97
+ self.run_imports(
98
+ "import mflux.web\nassert mflux.PARENT",
99
+ site,
100
+ )
101
+
102
+ def test_split_parent_with_extend_path(self):
103
+ parent_root = self.root / "parent"
104
+ parent = parent_root / "mflux"
105
+ parent.mkdir(parents=True)
106
+ (parent / "__init__.py").write_text(
107
+ "from pkgutil import extend_path\n"
108
+ "__path__ = extend_path(__path__, __name__)\n"
109
+ "PARENT = True\n"
110
+ )
111
+ self.run_imports(
112
+ "import mflux.web\nassert mflux.PARENT",
113
+ parent_root,
114
+ self.site,
115
+ )
116
+
117
+ def test_unmodified_split_parent_hides_web(self):
118
+ parent_root = self.root / "unmodified"
119
+ parent = parent_root / "mflux"
120
+ parent.mkdir(parents=True)
121
+ (parent / "__init__.py").write_text("PARENT = True\n")
122
+ self.run_imports(
123
+ "import importlib.util, mflux_web\n"
124
+ 'assert importlib.util.find_spec("mflux.web") is None',
125
+ parent_root,
126
+ self.site,
127
+ )
128
+
129
+
130
+ if __name__ == "__main__":
131
+ unittest.main()