pygim 0.1.0.dev1__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.
- pygim-0.1.0.dev1/LICENSE +21 -0
- pygim-0.1.0.dev1/PKG-INFO +214 -0
- pygim-0.1.0.dev1/README.rst +158 -0
- pygim-0.1.0.dev1/pyproject.toml +123 -0
- pygim-0.1.0.dev1/setup.cfg +4 -0
- pygim-0.1.0.dev1/setup.py +531 -0
- pygim-0.1.0.dev1/src/_pygim/__init__.py +4 -0
- pygim-0.1.0.dev1/src/_pygim/_cli/__init__.py +2 -0
- pygim-0.1.0.dev1/src/_pygim/_cli/_cli_app.py +174 -0
- pygim-0.1.0.dev1/src/_pygim/_cli/_commenter.py +184 -0
- pygim-0.1.0.dev1/src/_pygim/_cli/_docs_serve.py +692 -0
- pygim-0.1.0.dev1/src/_pygim/_core/__init__.py +2 -0
- pygim-0.1.0.dev1/src/_pygim/_core/_error_msgs.py +48 -0
- pygim-0.1.0.dev1/src/_pygim/_core/_exceptions.py +82 -0
- pygim-0.1.0.dev1/src/_pygim/_core/_typing.py +53 -0
- pygim-0.1.0.dev1/src/_pygim/_core/protocols.py +318 -0
- pygim-0.1.0.dev1/src/_pygim/_core/protocols.pyi +65 -0
- pygim-0.1.0.dev1/src/_pygim/_mcp/__init__.py +2 -0
- pygim-0.1.0.dev1/src/_pygim/_mcp/memory.py +342 -0
- pygim-0.1.0.dev1/src/_pygim_fast/datagen/bindings.cpp +72 -0
- pygim-0.1.0.dev1/src/_pygim_fast/each/bindings.cpp +34 -0
- pygim-0.1.0.dev1/src/_pygim_fast/memory/adapter/bindings.cpp +84 -0
- pygim-0.1.0.dev1/src/_pygim_fast/pathlike/adapter/bindings.cpp +227 -0
- pygim-0.1.0.dev1/src/_pygim_fast/pathlike/adapter/third_party/simdjson/simdjson.cpp +65333 -0
- pygim-0.1.0.dev1/src/_pygim_fast/persistence/adapter/bindings.cpp +117 -0
- pygim-0.1.0.dev1/src/_pygim_fast/persistence/adapter/test_bindings.cpp +107 -0
- pygim-0.1.0.dev1/src/_pygim_fast/tools/bench_bindings.cpp +114 -0
- pygim-0.1.0.dev1/src/_pygim_fast/utils/bindings.cpp +297 -0
- pygim-0.1.0.dev1/src/_pygim_fast/wiring/factory/bindings.cpp +51 -0
- pygim-0.1.0.dev1/src/_pygim_fast/wiring/ioc/bindings.cpp +102 -0
- pygim-0.1.0.dev1/src/_pygim_fast/wiring/registry/bindings.cpp +69 -0
- pygim-0.1.0.dev1/src/pygim/__init__.py +89 -0
- pygim-0.1.0.dev1/src/pygim/__main__.py +165 -0
- pygim-0.1.0.dev1/src/pygim/_stubs.py +75 -0
- pygim-0.1.0.dev1/src/pygim/ai/__init__.py +0 -0
- pygim-0.1.0.dev1/src/pygim/core/__init__.py +4 -0
- pygim-0.1.0.dev1/src/pygim/core/explib.py +30 -0
- pygim-0.1.0.dev1/src/pygim/core/funcs.py +53 -0
- pygim-0.1.0.dev1/src/pygim/core/protocols.py +5 -0
- pygim-0.1.0.dev1/src/pygim/core/testing.py +82 -0
- pygim-0.1.0.dev1/src/pygim/core/testing.pyi +13 -0
- pygim-0.1.0.dev1/src/pygim/core/timing_and_profiling.py +101 -0
- pygim-0.1.0.dev1/src/pygim/memory.pyi +48 -0
- pygim-0.1.0.dev1/src/pygim/pathlike.pyi +229 -0
- pygim-0.1.0.dev1/src/pygim/persistence.py +43 -0
- pygim-0.1.0.dev1/src/pygim.egg-info/PKG-INFO +214 -0
- pygim-0.1.0.dev1/src/pygim.egg-info/SOURCES.txt +61 -0
- pygim-0.1.0.dev1/src/pygim.egg-info/dependency_links.txt +1 -0
- pygim-0.1.0.dev1/src/pygim.egg-info/entry_points.txt +3 -0
- pygim-0.1.0.dev1/src/pygim.egg-info/requires.txt +35 -0
- pygim-0.1.0.dev1/src/pygim.egg-info/top_level.txt +3 -0
- pygim-0.1.0.dev1/tests/static/mapping_proofs.cpp +163 -0
- pygim-0.1.0.dev1/tests/static/memory_proofs.cpp +112 -0
- pygim-0.1.0.dev1/tests/static/pathlike_core_proofs.cpp +406 -0
- pygim-0.1.0.dev1/tests/static/pathlike_parity_proofs.cpp +759 -0
- pygim-0.1.0.dev1/tests/static/pathlike_scalar_proofs.cpp +102 -0
- pygim-0.1.0.dev1/tests/static/registry_core_proofs.cpp +186 -0
pygim-0.1.0.dev1/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Debith
|
|
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,214 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pygim
|
|
3
|
+
Version: 0.1.0.dev1
|
|
4
|
+
Summary: Full Python Gimmicks project with all of its sub-projects.
|
|
5
|
+
Project-URL: homepage, https://github.com/Debith/pygim
|
|
6
|
+
Project-URL: documentation, https://readthedocs.org/projects/pygim/
|
|
7
|
+
Project-URL: source, https://github.com/Debith/pygim
|
|
8
|
+
Project-URL: download, https://pypi.org/project/pygim/#files
|
|
9
|
+
Project-URL: tracker, https://github.com/Debith/pygim/issues
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Programming Language :: Python
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
20
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
21
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
22
|
+
Classifier: Typing :: Typed
|
|
23
|
+
Description-Content-Type: text/x-rst
|
|
24
|
+
License-File: LICENSE
|
|
25
|
+
Requires-Dist: click>=8
|
|
26
|
+
Requires-Dist: pyarrow==25.0.*
|
|
27
|
+
Requires-Dist: polars>=0.20
|
|
28
|
+
Requires-Dist: tabulate>=0.9
|
|
29
|
+
Requires-Dist: typing_extensions>=4.0
|
|
30
|
+
Provides-Extra: dev
|
|
31
|
+
Requires-Dist: pytest; extra == "dev"
|
|
32
|
+
Requires-Dist: pytest-xdist; extra == "dev"
|
|
33
|
+
Requires-Dist: mypy; extra == "dev"
|
|
34
|
+
Requires-Dist: coverage; extra == "dev"
|
|
35
|
+
Requires-Dist: coverage[toml]; extra == "dev"
|
|
36
|
+
Requires-Dist: pandas; extra == "dev"
|
|
37
|
+
Requires-Dist: pybind11; extra == "dev"
|
|
38
|
+
Requires-Dist: pyodbc; extra == "dev"
|
|
39
|
+
Requires-Dist: ruff; extra == "dev"
|
|
40
|
+
Requires-Dist: markdown; extra == "dev"
|
|
41
|
+
Provides-Extra: test
|
|
42
|
+
Requires-Dist: pytest; extra == "test"
|
|
43
|
+
Requires-Dist: pytest-xdist; extra == "test"
|
|
44
|
+
Requires-Dist: coverage; extra == "test"
|
|
45
|
+
Requires-Dist: coverage[toml]; extra == "test"
|
|
46
|
+
Requires-Dist: pyodbc; extra == "test"
|
|
47
|
+
Requires-Dist: pyyaml; extra == "test"
|
|
48
|
+
Requires-Dist: tomli; python_version < "3.11" and extra == "test"
|
|
49
|
+
Requires-Dist: markdown; extra == "test"
|
|
50
|
+
Provides-Extra: docs
|
|
51
|
+
Requires-Dist: markdown; extra == "docs"
|
|
52
|
+
Provides-Extra: pandas
|
|
53
|
+
Requires-Dist: pandas; extra == "pandas"
|
|
54
|
+
Dynamic: license-file
|
|
55
|
+
Dynamic: requires-dist
|
|
56
|
+
|
|
57
|
+
#######################
|
|
58
|
+
Python Gimmicks (pygim)
|
|
59
|
+
#######################
|
|
60
|
+
|
|
61
|
+
| |docs| |downloads| |wheel| |pyversions|
|
|
62
|
+
|
|
63
|
+
.. |docs| image:: https://readthedocs.org/projects/pygim/badge/
|
|
64
|
+
:target: https://readthedocs.org/projects/pygim
|
|
65
|
+
:alt: Documentation Status
|
|
66
|
+
|
|
67
|
+
.. |downloads| image:: https://img.shields.io/pypi/dm/pygim.svg
|
|
68
|
+
:alt: PyPI Package monthly downloads
|
|
69
|
+
:target: https://pypi.org/project/pygim/
|
|
70
|
+
|
|
71
|
+
.. |wheel| image:: https://img.shields.io/pypi/format/pygim.svg
|
|
72
|
+
:alt: PyPI Wheel
|
|
73
|
+
:target: https://pypi.org/project/pygim/
|
|
74
|
+
|
|
75
|
+
.. |pyversions| image:: https://img.shields.io/pypi/pyversions/pygim.svg
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
Python Gimmicks is a library that contains magical but useful tools
|
|
79
|
+
that can be used to improve productivity of any Python project. The
|
|
80
|
+
goal is to use whatever Pythonic means to provide as light-weight
|
|
81
|
+
and high-performance solutions as possible.
|
|
82
|
+
|
|
83
|
+
Installation
|
|
84
|
+
============
|
|
85
|
+
|
|
86
|
+
To install this project, simply write the following command:
|
|
87
|
+
|
|
88
|
+
.. code-block:: bash
|
|
89
|
+
|
|
90
|
+
$ pip install pygim
|
|
91
|
+
|
|
92
|
+
Command Line Interface
|
|
93
|
+
======================
|
|
94
|
+
|
|
95
|
+
Installing the package also exposes a ``pygim`` command that wraps the
|
|
96
|
+
project's housekeeping helpers. Run ``pygim --help`` to see the available
|
|
97
|
+
sub-commands, including quick clean-up tools and a shortcut for running the
|
|
98
|
+
coverage workflow used in this repository.
|
|
99
|
+
|
|
100
|
+
.. code-block:: bash
|
|
101
|
+
|
|
102
|
+
$ pygim clean-up --all --yes
|
|
103
|
+
Starting clean up in `/your/project/path`
|
|
104
|
+
Excellent! You never see them again!
|
|
105
|
+
|
|
106
|
+
You can also trigger the test coverage routine in one line:
|
|
107
|
+
|
|
108
|
+
.. code-block:: bash
|
|
109
|
+
|
|
110
|
+
$ pygim show-test-coverage
|
|
111
|
+
|
|
112
|
+
Both commands accept the same flags described in ``pygim --help``, so you can
|
|
113
|
+
mix and match automation-friendly options (like ``--quiet`` or ``--yes``) to
|
|
114
|
+
fit your workflow.
|
|
115
|
+
|
|
116
|
+
Sub-modules
|
|
117
|
+
-----------
|
|
118
|
+
|
|
119
|
+
This library is divided into multiple different smaller packages.
|
|
120
|
+
|
|
121
|
+
* pygim: This is the main project that contains the CLI and all the examples.
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
The ``oo`` command is the AI-flavoured front door. Free text goes to the
|
|
125
|
+
assistant; ``oo docs serve`` serves a documentation tree locally with a review
|
|
126
|
+
layer on top of every HTML page:
|
|
127
|
+
|
|
128
|
+
.. code-block:: bash
|
|
129
|
+
|
|
130
|
+
$ oo docs serve --dir build/html --rebuild "make html"
|
|
131
|
+
|
|
132
|
+
Every served page gets a ✎ button (click anywhere, or select text, to leave a
|
|
133
|
+
comment); comments append to ``__notes__/site-comments.jsonl`` under the served
|
|
134
|
+
root, ready to be read back and acted on. Dropping an image on a page writes it
|
|
135
|
+
under ``images/``. ``GET /pages`` lists the site's pages, and ``--rebuild``
|
|
136
|
+
reports which pages the rebuild added and removed. Opening a Markdown page
|
|
137
|
+
generates its HTML beside it (Mermaid fences become diagrams, ``.md`` links
|
|
138
|
+
point at the generated pages) and serves that, so the commenter works on it
|
|
139
|
+
and comments key on the HTML page — a design folder is served as it is
|
|
140
|
+
written:
|
|
141
|
+
|
|
142
|
+
.. code-block:: bash
|
|
143
|
+
|
|
144
|
+
$ oo docs serve --dir docs/design --host 127.0.0.1
|
|
145
|
+
|
|
146
|
+
``/`` falls back to the first of ``site/``, ``docs/``,
|
|
147
|
+
``build/html/`` or ``docs/_build/html/`` that has an ``index.html`` (override
|
|
148
|
+
with ``--index``). It binds all interfaces by default so the page is reachable
|
|
149
|
+
via the WSL IP; set ``PYGIM_HOST`` or pass ``--host 127.0.0.1`` for
|
|
150
|
+
localhost only.
|
|
151
|
+
|
|
152
|
+
Persistence (Experimental)
|
|
153
|
+
--------------------------
|
|
154
|
+
|
|
155
|
+
An experimental high-performance persistence layer (DDD-style DataStore) now exists as a C++ extension:
|
|
156
|
+
|
|
157
|
+
* Strategies: pluggable objects with ``fetch(key)->data|None`` and ``save(key,value)``.
|
|
158
|
+
* Optional transformer pipeline (pre-save / post-load) when enabled at construction.
|
|
159
|
+
* Optional factory callable to turn raw data into rich entities.
|
|
160
|
+
* Native MSSQL strategy (ODBC) with pybind-free core/adapter architecture.
|
|
161
|
+
* Fluent ``Query`` for lightweight SQL assembly without manual string concatenation.
|
|
162
|
+
* Arrow IPC utilities for zero-copy hand-off between Polars and C++ pipelines.
|
|
163
|
+
|
|
164
|
+
Example (read):
|
|
165
|
+
|
|
166
|
+
.. code-block:: python
|
|
167
|
+
|
|
168
|
+
from pygim import persistence
|
|
169
|
+
|
|
170
|
+
store = persistence.acquire_datastore("Driver={ODBC Driver 18 for SQL Server};Server=localhost;...")
|
|
171
|
+
|
|
172
|
+
df = store.load("users")
|
|
173
|
+
print(df)
|
|
174
|
+
|
|
175
|
+
Write (upsert) example: ``docs/examples/persistence/mssql_write_example.py``.
|
|
176
|
+
|
|
177
|
+
Architecture Diagram:
|
|
178
|
+
|
|
179
|
+
See PlantUML: ``docs/design/persistence_class_diagram.puml`` for component relationships.
|
|
180
|
+
|
|
181
|
+
.. note:: The MSSQL native strategy uses a pybind-free core/adapter split. ODBC headers must be available at build time for native SQL Server support.
|
|
182
|
+
|
|
183
|
+
Query Security & Dialect Notes
|
|
184
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
185
|
+
|
|
186
|
+
Passing a built ``Query`` object directly to ``DataStore.load(query)``
|
|
187
|
+
will bind parameters using ODBC. The builder renders
|
|
188
|
+
queries via ``MssqlDialect``, emitting ``TOP n`` for SQL Server.
|
|
189
|
+
|
|
190
|
+
Native Arrow Persist Path
|
|
191
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
192
|
+
|
|
193
|
+
Bulk DataFrame persistence is handled inside native bindings via
|
|
194
|
+
``DataStore.save(...)``. The strategy prefers Arrow C Data
|
|
195
|
+
Interface (``__arrow_c_stream__``) and falls back to IPC serialization only
|
|
196
|
+
when needed.
|
|
197
|
+
|
|
198
|
+
.. code-block:: python
|
|
199
|
+
|
|
200
|
+
from pygim import persistence
|
|
201
|
+
|
|
202
|
+
conn = "Driver={ODBC Driver 18 for SQL Server};Server=localhost;..."
|
|
203
|
+
store = persistence.acquire_datastore(conn)
|
|
204
|
+
df = generate_polars_dataset(n=100_000)
|
|
205
|
+
|
|
206
|
+
metrics = store.save(df, "stress_data")
|
|
207
|
+
print(metrics)
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
Changelog
|
|
212
|
+
=========
|
|
213
|
+
|
|
214
|
+
See the detailed list of changes in ``CHANGELOG.rst``. For upcoming (unreleased) work, consult the top "Unreleased" section before the next version tag.
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
#######################
|
|
2
|
+
Python Gimmicks (pygim)
|
|
3
|
+
#######################
|
|
4
|
+
|
|
5
|
+
| |docs| |downloads| |wheel| |pyversions|
|
|
6
|
+
|
|
7
|
+
.. |docs| image:: https://readthedocs.org/projects/pygim/badge/
|
|
8
|
+
:target: https://readthedocs.org/projects/pygim
|
|
9
|
+
:alt: Documentation Status
|
|
10
|
+
|
|
11
|
+
.. |downloads| image:: https://img.shields.io/pypi/dm/pygim.svg
|
|
12
|
+
:alt: PyPI Package monthly downloads
|
|
13
|
+
:target: https://pypi.org/project/pygim/
|
|
14
|
+
|
|
15
|
+
.. |wheel| image:: https://img.shields.io/pypi/format/pygim.svg
|
|
16
|
+
:alt: PyPI Wheel
|
|
17
|
+
:target: https://pypi.org/project/pygim/
|
|
18
|
+
|
|
19
|
+
.. |pyversions| image:: https://img.shields.io/pypi/pyversions/pygim.svg
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
Python Gimmicks is a library that contains magical but useful tools
|
|
23
|
+
that can be used to improve productivity of any Python project. The
|
|
24
|
+
goal is to use whatever Pythonic means to provide as light-weight
|
|
25
|
+
and high-performance solutions as possible.
|
|
26
|
+
|
|
27
|
+
Installation
|
|
28
|
+
============
|
|
29
|
+
|
|
30
|
+
To install this project, simply write the following command:
|
|
31
|
+
|
|
32
|
+
.. code-block:: bash
|
|
33
|
+
|
|
34
|
+
$ pip install pygim
|
|
35
|
+
|
|
36
|
+
Command Line Interface
|
|
37
|
+
======================
|
|
38
|
+
|
|
39
|
+
Installing the package also exposes a ``pygim`` command that wraps the
|
|
40
|
+
project's housekeeping helpers. Run ``pygim --help`` to see the available
|
|
41
|
+
sub-commands, including quick clean-up tools and a shortcut for running the
|
|
42
|
+
coverage workflow used in this repository.
|
|
43
|
+
|
|
44
|
+
.. code-block:: bash
|
|
45
|
+
|
|
46
|
+
$ pygim clean-up --all --yes
|
|
47
|
+
Starting clean up in `/your/project/path`
|
|
48
|
+
Excellent! You never see them again!
|
|
49
|
+
|
|
50
|
+
You can also trigger the test coverage routine in one line:
|
|
51
|
+
|
|
52
|
+
.. code-block:: bash
|
|
53
|
+
|
|
54
|
+
$ pygim show-test-coverage
|
|
55
|
+
|
|
56
|
+
Both commands accept the same flags described in ``pygim --help``, so you can
|
|
57
|
+
mix and match automation-friendly options (like ``--quiet`` or ``--yes``) to
|
|
58
|
+
fit your workflow.
|
|
59
|
+
|
|
60
|
+
Sub-modules
|
|
61
|
+
-----------
|
|
62
|
+
|
|
63
|
+
This library is divided into multiple different smaller packages.
|
|
64
|
+
|
|
65
|
+
* pygim: This is the main project that contains the CLI and all the examples.
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
The ``oo`` command is the AI-flavoured front door. Free text goes to the
|
|
69
|
+
assistant; ``oo docs serve`` serves a documentation tree locally with a review
|
|
70
|
+
layer on top of every HTML page:
|
|
71
|
+
|
|
72
|
+
.. code-block:: bash
|
|
73
|
+
|
|
74
|
+
$ oo docs serve --dir build/html --rebuild "make html"
|
|
75
|
+
|
|
76
|
+
Every served page gets a ✎ button (click anywhere, or select text, to leave a
|
|
77
|
+
comment); comments append to ``__notes__/site-comments.jsonl`` under the served
|
|
78
|
+
root, ready to be read back and acted on. Dropping an image on a page writes it
|
|
79
|
+
under ``images/``. ``GET /pages`` lists the site's pages, and ``--rebuild``
|
|
80
|
+
reports which pages the rebuild added and removed. Opening a Markdown page
|
|
81
|
+
generates its HTML beside it (Mermaid fences become diagrams, ``.md`` links
|
|
82
|
+
point at the generated pages) and serves that, so the commenter works on it
|
|
83
|
+
and comments key on the HTML page — a design folder is served as it is
|
|
84
|
+
written:
|
|
85
|
+
|
|
86
|
+
.. code-block:: bash
|
|
87
|
+
|
|
88
|
+
$ oo docs serve --dir docs/design --host 127.0.0.1
|
|
89
|
+
|
|
90
|
+
``/`` falls back to the first of ``site/``, ``docs/``,
|
|
91
|
+
``build/html/`` or ``docs/_build/html/`` that has an ``index.html`` (override
|
|
92
|
+
with ``--index``). It binds all interfaces by default so the page is reachable
|
|
93
|
+
via the WSL IP; set ``PYGIM_HOST`` or pass ``--host 127.0.0.1`` for
|
|
94
|
+
localhost only.
|
|
95
|
+
|
|
96
|
+
Persistence (Experimental)
|
|
97
|
+
--------------------------
|
|
98
|
+
|
|
99
|
+
An experimental high-performance persistence layer (DDD-style DataStore) now exists as a C++ extension:
|
|
100
|
+
|
|
101
|
+
* Strategies: pluggable objects with ``fetch(key)->data|None`` and ``save(key,value)``.
|
|
102
|
+
* Optional transformer pipeline (pre-save / post-load) when enabled at construction.
|
|
103
|
+
* Optional factory callable to turn raw data into rich entities.
|
|
104
|
+
* Native MSSQL strategy (ODBC) with pybind-free core/adapter architecture.
|
|
105
|
+
* Fluent ``Query`` for lightweight SQL assembly without manual string concatenation.
|
|
106
|
+
* Arrow IPC utilities for zero-copy hand-off between Polars and C++ pipelines.
|
|
107
|
+
|
|
108
|
+
Example (read):
|
|
109
|
+
|
|
110
|
+
.. code-block:: python
|
|
111
|
+
|
|
112
|
+
from pygim import persistence
|
|
113
|
+
|
|
114
|
+
store = persistence.acquire_datastore("Driver={ODBC Driver 18 for SQL Server};Server=localhost;...")
|
|
115
|
+
|
|
116
|
+
df = store.load("users")
|
|
117
|
+
print(df)
|
|
118
|
+
|
|
119
|
+
Write (upsert) example: ``docs/examples/persistence/mssql_write_example.py``.
|
|
120
|
+
|
|
121
|
+
Architecture Diagram:
|
|
122
|
+
|
|
123
|
+
See PlantUML: ``docs/design/persistence_class_diagram.puml`` for component relationships.
|
|
124
|
+
|
|
125
|
+
.. note:: The MSSQL native strategy uses a pybind-free core/adapter split. ODBC headers must be available at build time for native SQL Server support.
|
|
126
|
+
|
|
127
|
+
Query Security & Dialect Notes
|
|
128
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
129
|
+
|
|
130
|
+
Passing a built ``Query`` object directly to ``DataStore.load(query)``
|
|
131
|
+
will bind parameters using ODBC. The builder renders
|
|
132
|
+
queries via ``MssqlDialect``, emitting ``TOP n`` for SQL Server.
|
|
133
|
+
|
|
134
|
+
Native Arrow Persist Path
|
|
135
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
136
|
+
|
|
137
|
+
Bulk DataFrame persistence is handled inside native bindings via
|
|
138
|
+
``DataStore.save(...)``. The strategy prefers Arrow C Data
|
|
139
|
+
Interface (``__arrow_c_stream__``) and falls back to IPC serialization only
|
|
140
|
+
when needed.
|
|
141
|
+
|
|
142
|
+
.. code-block:: python
|
|
143
|
+
|
|
144
|
+
from pygim import persistence
|
|
145
|
+
|
|
146
|
+
conn = "Driver={ODBC Driver 18 for SQL Server};Server=localhost;..."
|
|
147
|
+
store = persistence.acquire_datastore(conn)
|
|
148
|
+
df = generate_polars_dataset(n=100_000)
|
|
149
|
+
|
|
150
|
+
metrics = store.save(df, "stress_data")
|
|
151
|
+
print(metrics)
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
Changelog
|
|
156
|
+
=========
|
|
157
|
+
|
|
158
|
+
See the detailed list of changes in ``CHANGELOG.rst``. For upcoming (unreleased) work, consult the top "Unreleased" section before the next version tag.
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools", "wheel", "tomli; python_version < '3.11'", "pybind11", "setuptools_scm[toml]>=8", "pyarrow>=15"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
backend-path = []
|
|
5
|
+
|
|
6
|
+
[project]
|
|
7
|
+
name = "pygim"
|
|
8
|
+
dynamic = ["version", "dependencies"]
|
|
9
|
+
description = "Full Python Gimmicks project with all of its sub-projects."
|
|
10
|
+
readme = "README.rst"
|
|
11
|
+
classifiers = [
|
|
12
|
+
"Development Status :: 4 - Beta",
|
|
13
|
+
"Intended Audience :: Developers",
|
|
14
|
+
"Programming Language :: Python",
|
|
15
|
+
"Programming Language :: Python :: 3",
|
|
16
|
+
"Programming Language :: Python :: 3.9",
|
|
17
|
+
"Programming Language :: Python :: 3.10",
|
|
18
|
+
"Programming Language :: Python :: 3.11",
|
|
19
|
+
"Programming Language :: Python :: 3.12",
|
|
20
|
+
"Programming Language :: Python :: 3.13",
|
|
21
|
+
"Programming Language :: Python :: 3.14",
|
|
22
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
23
|
+
"Topic :: Software Development :: Quality Assurance",
|
|
24
|
+
"Typing :: Typed",
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
[project.urls]
|
|
28
|
+
homepage = "https://github.com/Debith/pygim"
|
|
29
|
+
documentation = "https://readthedocs.org/projects/pygim/"
|
|
30
|
+
source = "https://github.com/Debith/pygim"
|
|
31
|
+
download = "https://pypi.org/project/pygim/#files"
|
|
32
|
+
tracker = "https://github.com/Debith/pygim/issues"
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
[project.optional-dependencies]
|
|
36
|
+
dev = [
|
|
37
|
+
'pytest',
|
|
38
|
+
'pytest-xdist',
|
|
39
|
+
'mypy',
|
|
40
|
+
'coverage',
|
|
41
|
+
'coverage[toml]',
|
|
42
|
+
'pandas',
|
|
43
|
+
'pybind11',
|
|
44
|
+
'pyodbc',
|
|
45
|
+
'ruff',
|
|
46
|
+
'markdown',
|
|
47
|
+
]
|
|
48
|
+
|
|
49
|
+
test = [
|
|
50
|
+
'pytest',
|
|
51
|
+
'pytest-xdist',
|
|
52
|
+
'coverage',
|
|
53
|
+
'coverage[toml]',
|
|
54
|
+
'pyodbc',
|
|
55
|
+
# Differential-test oracles: the pathlike harness compares decoding against
|
|
56
|
+
# reference implementations. These MUST be present wherever the suite acts
|
|
57
|
+
# as a merge gate (test_differential_oracles_installed_in_ci enforces it).
|
|
58
|
+
'pyyaml',
|
|
59
|
+
'tomli; python_version < "3.11"',
|
|
60
|
+
# `oo docs serve` renders Markdown pages; the docs-serve tests assert the rendering.
|
|
61
|
+
'markdown',
|
|
62
|
+
]
|
|
63
|
+
|
|
64
|
+
# `oo docs serve`: Markdown pages rendered on the fly (Mermaid fences become diagrams).
|
|
65
|
+
docs = [
|
|
66
|
+
'markdown',
|
|
67
|
+
]
|
|
68
|
+
|
|
69
|
+
pandas = [
|
|
70
|
+
'pandas',
|
|
71
|
+
]
|
|
72
|
+
|
|
73
|
+
[project.scripts]
|
|
74
|
+
pygim = "pygim.__main__:cli"
|
|
75
|
+
oo = "pygim.__main__:cli_oo"
|
|
76
|
+
|
|
77
|
+
[tool.pytest.ini_options]
|
|
78
|
+
minversion = "6.0"
|
|
79
|
+
python_files = "test_*.py"
|
|
80
|
+
addopts = '-ra -q --doctest-glob="**/*.py" --tb=short --doctest-modules --doctest-continue-on-failure'
|
|
81
|
+
testpaths = [
|
|
82
|
+
"tests/", # doctests
|
|
83
|
+
"src/",
|
|
84
|
+
]
|
|
85
|
+
|
|
86
|
+
[tool.coverage.report]
|
|
87
|
+
omit = [
|
|
88
|
+
"./docs/**/*.*",
|
|
89
|
+
"**/tests/**/*.*"
|
|
90
|
+
]
|
|
91
|
+
include = ["./src/**/*.py",
|
|
92
|
+
]
|
|
93
|
+
show_missing = true
|
|
94
|
+
exclude_lines = [
|
|
95
|
+
"pragma: no cover",
|
|
96
|
+
"if False",
|
|
97
|
+
"if __name__ == .__main__.:",
|
|
98
|
+
"@abc.abstractmethod",
|
|
99
|
+
"@abc.abstractproperty",
|
|
100
|
+
]
|
|
101
|
+
|
|
102
|
+
[tool.pygim.build]
|
|
103
|
+
# The runtime requirements. They are dynamic because setup.py pins pyarrow to
|
|
104
|
+
# the release the extensions were built against (setup.py::_pin_arrow_abi).
|
|
105
|
+
dependencies = [
|
|
106
|
+
"click>=8",
|
|
107
|
+
"pyarrow>=15",
|
|
108
|
+
"polars>=0.20",
|
|
109
|
+
"tabulate>=0.9",
|
|
110
|
+
"typing_extensions>=4.0",
|
|
111
|
+
]
|
|
112
|
+
|
|
113
|
+
[tool.pygim.commands]
|
|
114
|
+
|
|
115
|
+
[tool.mypy]
|
|
116
|
+
exclude = [
|
|
117
|
+
'tests/.*',
|
|
118
|
+
'build/.*',
|
|
119
|
+
]
|
|
120
|
+
|
|
121
|
+
[tool.setuptools_scm]
|
|
122
|
+
version_scheme = "no-guess-dev"
|
|
123
|
+
local_scheme = "dirty-tag"
|