featm 0.5.7__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.
Files changed (186) hide show
  1. featm-0.5.7/.gitattributes +9 -0
  2. featm-0.5.7/.github/ISSUE_TEMPLATE/bug_report.md +27 -0
  3. featm-0.5.7/.github/scripts/check_release.py +26 -0
  4. featm-0.5.7/.github/scripts/test_wheel.py +18 -0
  5. featm-0.5.7/.github/workflows/ci.yml +28 -0
  6. featm-0.5.7/.github/workflows/publish-pypi.yml +69 -0
  7. featm-0.5.7/.gitignore +19 -0
  8. featm-0.5.7/CHANGELOG.md +26 -0
  9. featm-0.5.7/CONTRIBUTING.md +35 -0
  10. featm-0.5.7/LICENSE +21 -0
  11. featm-0.5.7/MANIFEST.in +13 -0
  12. featm-0.5.7/PKG-INFO +299 -0
  13. featm-0.5.7/README.md +194 -0
  14. featm-0.5.7/THIRD_PARTY_NOTICES.md +16 -0
  15. featm-0.5.7/benchmarks/batch_equivalence_smoke.py +473 -0
  16. featm-0.5.7/benchmarks/distributed_dask_equivalence_smoke.py +183 -0
  17. featm-0.5.7/benchmarks/distributed_equivalence_smoke.py +85 -0
  18. featm-0.5.7/benchmarks/distributed_persistent_cluster_benchmark.py +158 -0
  19. featm-0.5.7/benchmarks/scaling_benchmark.py +159 -0
  20. featm-0.5.7/benchmarks/smoke_universe.py +156 -0
  21. featm-0.5.7/benchmarks/step5/__init__.py +6 -0
  22. featm-0.5.7/benchmarks/step5/catalog.py +55 -0
  23. featm-0.5.7/benchmarks/step5/engine_worker.py +91 -0
  24. featm-0.5.7/benchmarks/step5/fixtures.py +287 -0
  25. featm-0.5.7/benchmarks/step5/gen_environment_manifest.py +87 -0
  26. featm-0.5.7/benchmarks/step5/gen_gpu_provenance_bridge.py +113 -0
  27. featm-0.5.7/benchmarks/step5/gen_validation_results.py +552 -0
  28. featm-0.5.7/benchmarks/step5/provenance.py +236 -0
  29. featm-0.5.7/benchmarks/step5/recompute_gpu_crossover_summary.py +118 -0
  30. featm-0.5.7/benchmarks/step5/run_dask_crossover_benchmark.py +226 -0
  31. featm-0.5.7/benchmarks/step5/run_engine_benchmark.py +60 -0
  32. featm-0.5.7/benchmarks/step5/run_metadata_audit.py +150 -0
  33. featm-0.5.7/benchmarks/step5/run_real_dataset_family_bundle_redundancy.py +53 -0
  34. featm-0.5.7/benchmarks/step5/run_real_dataset_family_bundle_utility.py +116 -0
  35. featm-0.5.7/benchmarks/step5/run_real_dataset_utility.py +367 -0
  36. featm-0.5.7/benchmarks/step5/run_redundancy_analysis.py +112 -0
  37. featm-0.5.7/benchmarks/step5/run_regression_matrix.py +175 -0
  38. featm-0.5.7/benchmarks/step5/run_stateful_benchmark.py +244 -0
  39. featm-0.5.7/benchmarks/step5/run_system_benchmark.py +183 -0
  40. featm-0.5.7/benchmarks/step5/run_true_family_bundle_redundancy.py +123 -0
  41. featm-0.5.7/benchmarks/step5/run_true_family_bundle_utility.py +208 -0
  42. featm-0.5.7/benchmarks/step5/summarize.py +62 -0
  43. featm-0.5.7/benchmarks/step5/summarize_dask_crossover.py +70 -0
  44. featm-0.5.7/benchmarks/step5/summarize_engine.py +54 -0
  45. featm-0.5.7/benchmarks/step5/utility_probes.py +222 -0
  46. featm-0.5.7/benchmarks/step5/worker.py +259 -0
  47. featm-0.5.7/docs/API.md +63 -0
  48. featm-0.5.7/docs/ARCHITECTURE.md +213 -0
  49. featm-0.5.7/docs/BENCHMARKS.md +38 -0
  50. featm-0.5.7/docs/COMPATIBILITY.md +44 -0
  51. featm-0.5.7/docs/DISTRIBUTED.md +57 -0
  52. featm-0.5.7/docs/EXECUTION_REFERENCE.md +130 -0
  53. featm-0.5.7/docs/FEATURE_AUTHORING.md +412 -0
  54. featm-0.5.7/docs/FEATURE_UNIVERSE.md +638 -0
  55. featm-0.5.7/docs/GETTING_STARTED.md +129 -0
  56. featm-0.5.7/docs/INSTALLATION.md +82 -0
  57. featm-0.5.7/docs/PRACTICAL_EXAMPLES.md +76 -0
  58. featm-0.5.7/docs/RELEASE_TESTING.md +33 -0
  59. featm-0.5.7/docs/SCALING.md +76 -0
  60. featm-0.5.7/examples/README.md +18 -0
  61. featm-0.5.7/examples/audio_features.py +38 -0
  62. featm-0.5.7/examples/ecg_features.py +21 -0
  63. featm-0.5.7/examples/image_features.py +19 -0
  64. featm-0.5.7/examples/stateful_categories.py +19 -0
  65. featm-0.5.7/examples/time_series.py +9 -0
  66. featm-0.5.7/pyproject.toml +170 -0
  67. featm-0.5.7/scripts/build_gpu_validation_notebook.py +1012 -0
  68. featm-0.5.7/scripts/build_step4_dask_validation_notebook.py +474 -0
  69. featm-0.5.7/scripts/build_step5_gpu_crossover_notebook.py +393 -0
  70. featm-0.5.7/scripts/gen_feature_universe.py +57 -0
  71. featm-0.5.7/setup.cfg +4 -0
  72. featm-0.5.7/src/featm/__init__.py +86 -0
  73. featm-0.5.7/src/featm/cache.py +190 -0
  74. featm-0.5.7/src/featm/checkpoint.py +231 -0
  75. featm-0.5.7/src/featm/cli.py +141 -0
  76. featm-0.5.7/src/featm/contracts.py +93 -0
  77. featm-0.5.7/src/featm/distributed/__init__.py +25 -0
  78. featm-0.5.7/src/featm/distributed/checkpoint.py +541 -0
  79. featm-0.5.7/src/featm/distributed/contracts.py +99 -0
  80. featm-0.5.7/src/featm/distributed/dask_runtime.py +142 -0
  81. featm-0.5.7/src/featm/distributed/execution.py +1118 -0
  82. featm-0.5.7/src/featm/distributed/local.py +83 -0
  83. featm-0.5.7/src/featm/distributed/partition_provider.py +245 -0
  84. featm-0.5.7/src/featm/distributed/planner.py +80 -0
  85. featm-0.5.7/src/featm/distributed/runtime.py +61 -0
  86. featm-0.5.7/src/featm/engine.py +497 -0
  87. featm-0.5.7/src/featm/execution.py +1994 -0
  88. featm-0.5.7/src/featm/executor.py +145 -0
  89. featm-0.5.7/src/featm/extractor.py +353 -0
  90. featm-0.5.7/src/featm/features/__init__.py +27 -0
  91. featm-0.5.7/src/featm/features/_utils.py +498 -0
  92. featm-0.5.7/src/featm/features/audio/__init__.py +0 -0
  93. featm-0.5.7/src/featm/features/audio/full.py +302 -0
  94. featm-0.5.7/src/featm/features/event/__init__.py +0 -0
  95. featm-0.5.7/src/featm/features/event/full.py +96 -0
  96. featm-0.5.7/src/featm/features/geometry/triangulation.py +283 -0
  97. featm-0.5.7/src/featm/features/graph/__init__.py +0 -0
  98. featm-0.5.7/src/featm/features/graph/full.py +379 -0
  99. featm-0.5.7/src/featm/features/image/basic.py +66 -0
  100. featm-0.5.7/src/featm/features/image/full.py +394 -0
  101. featm-0.5.7/src/featm/features/information/__init__.py +0 -0
  102. featm-0.5.7/src/featm/features/information/full.py +150 -0
  103. featm-0.5.7/src/featm/features/manifold/__init__.py +0 -0
  104. featm-0.5.7/src/featm/features/manifold/full.py +63 -0
  105. featm-0.5.7/src/featm/features/matrix/__init__.py +0 -0
  106. featm-0.5.7/src/featm/features/matrix/full.py +56 -0
  107. featm-0.5.7/src/featm/features/multimodal/__init__.py +0 -0
  108. featm-0.5.7/src/featm/features/multimodal/full.py +60 -0
  109. featm-0.5.7/src/featm/features/pointcloud/__init__.py +0 -0
  110. featm-0.5.7/src/featm/features/pointcloud/full.py +168 -0
  111. featm-0.5.7/src/featm/features/sequence/__init__.py +0 -0
  112. featm-0.5.7/src/featm/features/sequence/full.py +128 -0
  113. featm-0.5.7/src/featm/features/signal/__init__.py +0 -0
  114. featm-0.5.7/src/featm/features/signal/full.py +249 -0
  115. featm-0.5.7/src/featm/features/spatial/__init__.py +0 -0
  116. featm-0.5.7/src/featm/features/spatial/full.py +109 -0
  117. featm-0.5.7/src/featm/features/tabular/categorical.py +27 -0
  118. featm-0.5.7/src/featm/features/tabular/datetime.py +66 -0
  119. featm-0.5.7/src/featm/features/tabular/full.py +404 -0
  120. featm-0.5.7/src/featm/features/tabular/interactions.py +41 -0
  121. featm-0.5.7/src/featm/features/tabular/numeric.py +70 -0
  122. featm-0.5.7/src/featm/features/text/__init__.py +0 -0
  123. featm-0.5.7/src/featm/features/text/full.py +317 -0
  124. featm-0.5.7/src/featm/features/timeseries/basic.py +110 -0
  125. featm-0.5.7/src/featm/features/timeseries/full.py +676 -0
  126. featm-0.5.7/src/featm/features/topology/__init__.py +0 -0
  127. featm-0.5.7/src/featm/features/topology/full.py +129 -0
  128. featm-0.5.7/src/featm/features/video/__init__.py +0 -0
  129. featm-0.5.7/src/featm/features/video/full.py +117 -0
  130. featm-0.5.7/src/featm/gpu/__init__.py +50 -0
  131. featm-0.5.7/src/featm/gpu/backend.py +248 -0
  132. featm-0.5.7/src/featm/gpu/cache.py +184 -0
  133. featm-0.5.7/src/featm/gpu/dispatch.py +596 -0
  134. featm-0.5.7/src/featm/gpu/exceptions.py +79 -0
  135. featm-0.5.7/src/featm/gpu/kernels/__init__.py +1 -0
  136. featm-0.5.7/src/featm/gpu/kernels/reductions.py +112 -0
  137. featm-0.5.7/src/featm/gpu/kernels/spectral.py +207 -0
  138. featm-0.5.7/src/featm/gpu/memory.py +211 -0
  139. featm-0.5.7/src/featm/gpu/registration.py +88 -0
  140. featm-0.5.7/src/featm/matrix.py +553 -0
  141. featm-0.5.7/src/featm/planner.py +99 -0
  142. featm-0.5.7/src/featm/registry.py +590 -0
  143. featm-0.5.7/src/featm/report.py +232 -0
  144. featm-0.5.7/src/featm/resources.py +412 -0
  145. featm-0.5.7/src/featm/sampling.py +146 -0
  146. featm-0.5.7/src/featm/schema.py +131 -0
  147. featm-0.5.7/src/featm/sources.py +736 -0
  148. featm-0.5.7/src/featm/state.py +749 -0
  149. featm-0.5.7/src/featm.egg-info/PKG-INFO +299 -0
  150. featm-0.5.7/src/featm.egg-info/SOURCES.txt +184 -0
  151. featm-0.5.7/src/featm.egg-info/dependency_links.txt +1 -0
  152. featm-0.5.7/src/featm.egg-info/entry_points.txt +2 -0
  153. featm-0.5.7/src/featm.egg-info/requires.txt +126 -0
  154. featm-0.5.7/src/featm.egg-info/top_level.txt +1 -0
  155. featm-0.5.7/tests/conftest.py +70 -0
  156. featm-0.5.7/tests/fixtures/registry_v0.1.0_names.json +551 -0
  157. featm-0.5.7/tests/test_audit2.py +593 -0
  158. featm-0.5.7/tests/test_audit3.py +597 -0
  159. featm-0.5.7/tests/test_audit4.py +671 -0
  160. featm-0.5.7/tests/test_audit5.py +486 -0
  161. featm-0.5.7/tests/test_cache.py +153 -0
  162. featm-0.5.7/tests/test_checkpoint_replay_history.py +264 -0
  163. featm-0.5.7/tests/test_checkpoint_state_budget_identity.py +110 -0
  164. featm-0.5.7/tests/test_core.py +245 -0
  165. featm-0.5.7/tests/test_distributed_checkpoint.py +727 -0
  166. featm-0.5.7/tests/test_distributed_dask.py +438 -0
  167. featm-0.5.7/tests/test_distributed_foundation.py +267 -0
  168. featm-0.5.7/tests/test_distributed_gpu.py +230 -0
  169. featm-0.5.7/tests/test_distributed_io.py +277 -0
  170. featm-0.5.7/tests/test_distributed_planner.py +102 -0
  171. featm-0.5.7/tests/test_distributed_state_merge.py +275 -0
  172. featm-0.5.7/tests/test_docs_consistency.py +78 -0
  173. featm-0.5.7/tests/test_execution.py +834 -0
  174. featm-0.5.7/tests/test_gpu_backend.py +135 -0
  175. featm-0.5.7/tests/test_gpu_dispatch.py +914 -0
  176. featm-0.5.7/tests/test_gpu_memory.py +200 -0
  177. featm-0.5.7/tests/test_gpu_metadata.py +113 -0
  178. featm-0.5.7/tests/test_matrix.py +152 -0
  179. featm-0.5.7/tests/test_sources.py +151 -0
  180. featm-0.5.7/tests/test_state.py +120 -0
  181. featm-0.5.7/tests/test_step5_benchmark_foundation.py +484 -0
  182. featm-0.5.7/tests/test_step5_measurement_harness_provenance.py +249 -0
  183. featm-0.5.7/tests/test_step5_provenance_gate_hardening.py +254 -0
  184. featm-0.5.7/tests/test_v055_correctness.py +323 -0
  185. featm-0.5.7/tests/test_v056_checkpoint_budget.py +215 -0
  186. featm-0.5.7/tests/test_v057_checkpoint_root.py +80 -0
@@ -0,0 +1,9 @@
1
+ # Preserve audited product/test bytes, including existing line endings.
2
+ * -text
3
+ *.md text eol=lf
4
+ *.toml text eol=lf
5
+ *.yml text eol=lf
6
+ *.yaml text eol=lf
7
+ LICENSE text eol=lf
8
+ src/featm/** -text
9
+ tests/** -text
@@ -0,0 +1,27 @@
1
+ ---
2
+ name: Bug report
3
+ about: A minimal reproducer and environment details
4
+ title: ""
5
+ labels: ""
6
+ assignees: ""
7
+ ---
8
+
9
+ ## Expected and actual behavior
10
+
11
+ Describe the selected feature/operation and its expected output.
12
+
13
+ ## Minimal reproducer
14
+
15
+ Include executable code with synthetic input, explicit features and
16
+ `errors="raise"`. For `warn`/`skip`, also include the execution report and shape.
17
+
18
+ ## Environment
19
+
20
+ FEATM version; Python version; OS/architecture; installed extras;
21
+ relevant dependency versions; input shape/dtypes; CPU/GPU/Dask configuration.
22
+
23
+ ## Evidence
24
+
25
+ Paste the exception/traceback or report. Do not include tokens, personal data,
26
+ model weights or large datasets. A checkpoint issue may need a redacted manifest
27
+ and the steps that created it, not a binary artifact from an untrusted source.
@@ -0,0 +1,26 @@
1
+ """Check built artifacts without importing the development package."""
2
+ import email,hashlib,json,sys,tarfile,tomllib,zipfile
3
+ from pathlib import Path
4
+
5
+ root=Path(__file__).resolve().parents[2]
6
+ dist=Path(sys.argv[1]).resolve()
7
+ p=tomllib.loads((root/'pyproject.toml').read_text(encoding='utf-8'))['project']
8
+ assert p['name']=='featm' and p['version']=='0.5.7'
9
+ expected={'featm-0.5.7-py3-none-any.whl','featm-0.5.7.tar.gz'}
10
+ assert {f.name for f in dist.iterdir()}==expected
11
+ with zipfile.ZipFile(dist/'featm-0.5.7-py3-none-any.whl') as w,tarfile.open(dist/'featm-0.5.7.tar.gz') as t:
12
+ m=email.message_from_string(w.read('featm-0.5.7.dist-info/METADATA').decode('utf-8'))
13
+ s=email.message_from_string(t.extractfile('featm-0.5.7/PKG-INFO').read().decode('utf-8'))
14
+ assert m['Name']==s['Name']=='featm' and m['Version']==s['Version']=='0.5.7'
15
+ assert m.get_all('Requires-Dist')==s.get_all('Requires-Dist')
16
+ assert m['Requires-Python']==s['Requires-Python']==p['requires-python']
17
+ assert m.get_payload().replace('\r\n','\n').strip()==(root/'README.md').read_text(encoding='utf-8').strip()
18
+ licenses=[n for n in w.namelist() if n.endswith('/LICENSE')]
19
+ assert len(licenses)==1 and w.read(licenses[0])==(root/'LICENSE').read_bytes()
20
+ assert t.extractfile('featm-0.5.7/LICENSE').read()==(root/'LICENSE').read_bytes()
21
+ names={x.relative_to(root/'src').as_posix() for x in (root/'src/featm').rglob('*.py')}
22
+ assert len(names)==77 and names=={n for n in w.namelist() if n.startswith('featm/') and n.endswith('.py')}
23
+ for n in names:
24
+ assert w.read(n)==t.extractfile('featm-0.5.7/src/'+n).read()==(root/'src'/n).read_bytes()
25
+ print('PASS: version, metadata, README, license and 77 product files')
26
+ (root/'release-artifact-hashes.json').write_text(json.dumps({f.name:{'sha256':hashlib.sha256(f.read_bytes()).hexdigest(),'bytes':f.stat().st_size} for f in sorted(dist.iterdir())},indent=2))
@@ -0,0 +1,18 @@
1
+ """Exercise an installed wheel in a fresh environment, never an editable install."""
2
+ import os,subprocess,sys,tempfile,venv
3
+ from pathlib import Path
4
+
5
+ root=Path(__file__).resolve().parents[2]
6
+ wheel=next(Path(sys.argv[1]).resolve().glob('*.whl'))
7
+ env=os.environ.copy();env.pop('PYTHONPATH',None);env.update(PYTHONNOUSERSITE='1',PYTHONDONTWRITEBYTECODE='1',PYTHONUTF8='1')
8
+ with tempfile.TemporaryDirectory() as tmp:
9
+ base=Path(tmp);v=base/'env';venv.create(v,with_pip=True)
10
+ py=v/('Scripts/python.exe' if os.name=='nt' else 'bin/python')
11
+ def run(*args):subprocess.run([str(py),*map(str,args)],cwd=base,env=env,check=True)
12
+ # These are test dependencies, not changes to the package's runtime metadata.
13
+ run('-m','pip','install',wheel,'pytest','networkx','scipy','pyarrow')
14
+ run('-m','pip','check')
15
+ run('-c',"import featm,importlib.metadata as m,numpy as np,sys; from pathlib import Path; package_path=Path(featm.__file__).resolve(); environment_path=Path(sys.prefix).resolve(); print('INSTALLED_WHEEL',package_path,'ENVIRONMENT',environment_path); assert package_path.is_relative_to(environment_path), (package_path,environment_path); s=featm.REGISTRY.all(); assert featm.__version__==m.version('featm')=='0.5.7'; assert [len(s),len({x.modality for x in s}),len({(x.modality,x.family) for x in s}),sum(x.stateful for x in s),sum(x.gpu_available for x in s)]==[552,18,182,7,22]; np.testing.assert_allclose(featm.extract(np.array([[1.,2.,3.,4.],[10.,20.,30.,40.]]),features=['timeseries.statistical.mean'],errors='raise').to_numpy().ravel(),[2.5,25.])")
16
+ cfg=base/'pytest.ini';cfg.write_text('[pytest]\n')
17
+ runner=base/'runner.py';runner.write_text("import os,sys\nfrom pathlib import Path\nroot=Path(sys.argv.pop(1)); sys.path.insert(0,str(root)); os.chdir(root)\nimport featm,pytest\nassert not Path(featm.__file__).resolve().is_relative_to(root)\nraise SystemExit(pytest.main(sys.argv[1:]))\n")
18
+ run(runner,root,'-c',cfg,'tests/test_core.py','tests/test_state.py','tests/test_matrix.py','tests/test_v057_checkpoint_root.py','-q','-p','no:cacheprovider')
@@ -0,0 +1,28 @@
1
+ name: Distribution CI
2
+ on:
3
+ push:
4
+ branches: [main]
5
+ pull_request:
6
+ permissions:
7
+ contents: read
8
+ jobs:
9
+ wheel:
10
+ runs-on: ${{ matrix.os }}
11
+ strategy:
12
+ fail-fast: false
13
+ matrix:
14
+ os: [ubuntu-latest, windows-latest]
15
+ python: ['3.11']
16
+ steps:
17
+ - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
18
+ - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
19
+ with:
20
+ python-version: ${{ matrix.python }}
21
+ - name: Build and inspect distributions
22
+ run: |
23
+ python -m pip install build twine
24
+ python -m build
25
+ python -m twine check dist/*
26
+ python .github/scripts/check_release.py dist
27
+ - name: Install wheel into a fresh environment and test
28
+ run: python .github/scripts/test_wheel.py dist
@@ -0,0 +1,69 @@
1
+ name: Publish reviewed release to PyPI
2
+ on:
3
+ release:
4
+ types: [published]
5
+ permissions:
6
+ contents: read
7
+ concurrency:
8
+ group: featm-pypi-v0.5.7
9
+ cancel-in-progress: false
10
+ jobs:
11
+ build:
12
+ if: >-
13
+ github.repository == 'Harish-K22/featm' &&
14
+ github.repository_id == '1409483295' &&
15
+ github.event.repository.private == true &&
16
+ github.actor == 'Harish-K22' &&
17
+ github.event.release.draft == false &&
18
+ github.event.release.prerelease == false &&
19
+ github.event.release.tag_name == 'v0.5.7' &&
20
+ github.event.release.author.login == 'Harish-K22'
21
+ runs-on: ubuntu-latest
22
+ steps:
23
+ - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
24
+ with:
25
+ ref: refs/tags/v0.5.7
26
+ persist-credentials: false
27
+ - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
28
+ with:
29
+ python-version: '3.11'
30
+ - name: Verify owner-approved release commit
31
+ env:
32
+ APPROVED_RELEASE_COMMIT: ${{ vars.FEATM_APPROVED_RELEASE_COMMIT }}
33
+ run: |
34
+ python -c "import os,re,subprocess; expected=os.environ['APPROVED_RELEASE_COMMIT']; actual=subprocess.check_output(['git','rev-parse','HEAD'],text=True).strip(); assert re.fullmatch('[0-9a-f]{40}',expected), 'Set the repository variable FEATM_APPROVED_RELEASE_COMMIT to the reviewed full SHA'; assert actual==expected, 'Release tag does not point to the approved commit'; print('Approved source commit:',actual)"
35
+ - name: Validate exact source version and build
36
+ env:
37
+ RELEASE_TAG: ${{ github.event.release.tag_name }}
38
+ run: |
39
+ python -m pip install build twine
40
+ python -c "import os,tomllib; p=tomllib.load(open('pyproject.toml','rb'))['project']; assert p['name']=='featm' and p['version']=='0.5.7' and os.environ['RELEASE_TAG']=='v'+p['version']"
41
+ python -m build
42
+ python -m twine check dist/*
43
+ python .github/scripts/check_release.py dist
44
+ python .github/scripts/test_wheel.py dist
45
+ - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
46
+ with:
47
+ name: pypi-distributions
48
+ path: dist/
49
+ if-no-files-found: error
50
+ - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
51
+ with:
52
+ name: reviewed-distribution-hashes
53
+ path: release-artifact-hashes.json
54
+ if-no-files-found: error
55
+ publish:
56
+ needs: build
57
+ runs-on: ubuntu-latest
58
+ permissions:
59
+ id-token: write
60
+ actions: read
61
+ steps:
62
+ - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
63
+ with:
64
+ name: pypi-distributions
65
+ path: dist/
66
+ - name: Publish using OIDC
67
+ uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # release/v1
68
+ with:
69
+ packages-dir: dist/
featm-0.5.7/.gitignore ADDED
@@ -0,0 +1,19 @@
1
+ .venv/
2
+ venv/
3
+ __pycache__/
4
+ *.py[cod]
5
+ .pytest_cache/
6
+ .coverage
7
+ htmlcov/
8
+ build/
9
+ dist/
10
+ *.egg-info/
11
+ .DS_Store
12
+ Thumbs.db
13
+ .env
14
+ .env.*
15
+ datasets/
16
+ models/
17
+ checkpoints/
18
+ step5_final_results/
19
+ *_AUDIT_HANDOFF.zip
@@ -0,0 +1,26 @@
1
+ # Release notes
2
+
3
+ ## 0.5.7 — initial public release
4
+
5
+ FEATM offers a searchable registry for explicit, named feature extraction
6
+ across time series, tabular data and other modalities. Discover names with
7
+ `list_features`, create a callable with `create_feature`, and extract a selected
8
+ set with `extract`. Reuse training-only fitted transformations with `fit`,
9
+ `transform`, `save` and `load_fitted`.
10
+
11
+ The package includes bounded source execution, disk-backed results, compatible
12
+ checkpoint resume, Dask partition execution and a scoped 22-method CuPy GPU
13
+ surface. Backends and external models are optional; the beginner example uses
14
+ only base dependencies. The supporting catalogue retains 552 entries across
15
+ 18 modalities, not a claim of universal predictive improvement.
16
+
17
+ v0.5.7 rejects non-object checkpoint JSON roots without overwriting invalid
18
+ manifests, while preserving missing-file creation and valid resume behavior.
19
+ The documentation explains time-series shapes, error/report access,
20
+ training-only state, optional installation and execution limits.
21
+
22
+ Base certification is Windows/Ubuntu-WSL x86-64 CPython 3.10–3.14. Node2vec,
23
+ gensim/text and actual Windows CUDA support have narrower scopes; macOS, ARM
24
+ and Python 3.15 are unvalidated. Short harmonic/tonnetz inputs retain an
25
+ upstream librosa numerical limitation. See [compatibility](docs/COMPATIBILITY.md).
26
+
@@ -0,0 +1,35 @@
1
+ # Contributing
2
+
3
+ Use explicit named methods, and include a small reproducer when reporting a
4
+ problem. A report should contain the FEATM/Python versions, OS and architecture,
5
+ installed extras and dependency versions, input shape/dtypes, exact feature
6
+ names and parameters, error policy, actual exception/report and expected result.
7
+ For CUDA/Dask, include device/runtime or worker configuration. Remove credentials
8
+ and personal data; prefer synthetic inputs over private datasets.
9
+
10
+ The owner-confirmed repository is [https://github.com/Harish-K22/featm](https://github.com/Harish-K22/featm).
11
+ Use its [issue tracker](https://github.com/Harish-K22/featm/issues) when available; no private contact
12
+ address or repository visibility is assumed by these instructions.
13
+
14
+ ## Development setup
15
+
16
+ Once repository access is available, obtain a checkout from `https://github.com/Harish-K22/featm`.
17
+ The package lives in `src/featm/`; method definitions live in `src/featm/features/`
18
+ and stateful encoders in `src/featm/state.py`. From a checkout, in a virtual environment:
19
+
20
+ ```bash
21
+ python -m pip install -e ".[dev,io,distributed,scientific]"
22
+ python -m pytest -q -ra
23
+ ```
24
+
25
+ These are actual extras. Tests for optional backends/models may skip when their
26
+ dependencies are absent; include skip reasons. CUDA tests need the certified
27
+ GPU setup, not merely the development extra. A minimal CI job can use the above
28
+ CPU setup on the tested Windows/Ubuntu x86-64 Python scope; do not add unvalidated
29
+ platform badges or infer optional-wide support from a green base job.
30
+
31
+ Feature authoring contracts are in [docs/FEATURE_AUTHORING.md](docs/FEATURE_AUTHORING.md).
32
+ Changes should explain inputs, named outputs, dependencies, batch/stateful
33
+ semantics and relevant numerical verification. Avoid committing environments,
34
+ datasets, model weights, checkpoints or private audit material. Product/API
35
+ changes require their own review; this staged release preserves the audited implementation.
featm-0.5.7/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Harish K
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,13 @@
1
+ include README.md LICENSE CONTRIBUTING.md THIRD_PARTY_NOTICES.md CHANGELOG.md
2
+ include .gitignore .gitattributes
3
+ recursive-include docs *.md
4
+ recursive-include examples *.py *.md
5
+ recursive-include tests *.py *.json
6
+ recursive-include benchmarks *.py *.json *.csv
7
+ recursive-include scripts *.py
8
+ recursive-include .github *.md *.yml *.py *.ini
9
+ global-exclude *.pyc *.pyo .DS_Store Thumbs.db
10
+ prune .git
11
+ prune .venv
12
+ prune build
13
+ prune dist
featm-0.5.7/PKG-INFO ADDED
@@ -0,0 +1,299 @@
1
+ Metadata-Version: 2.4
2
+ Name: featm
3
+ Version: 0.5.7
4
+ Summary: One searchable API for explicit, named feature extraction across data modalities.
5
+ Author: featm contributors
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/Harish-K22/featm
8
+ Project-URL: Repository, https://github.com/Harish-K22/featm
9
+ Project-URL: Issues, https://github.com/Harish-K22/featm/issues
10
+ Keywords: feature-engineering,feature-extraction,machine-learning,time-series,signal-processing,computational-geometry,graphs
11
+ Requires-Python: >=3.10
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE
14
+ Requires-Dist: numpy>=1.24
15
+ Requires-Dist: pandas>=2.0
16
+ Requires-Dist: psutil>=5.9
17
+ Provides-Extra: io
18
+ Requires-Dist: pyarrow>=14; extra == "io"
19
+ Requires-Dist: polars>=1.0; extra == "io"
20
+ Provides-Extra: distributed
21
+ Requires-Dist: dask[distributed]>=2024.1; extra == "distributed"
22
+ Provides-Extra: scientific
23
+ Requires-Dist: scipy>=1.10; extra == "scientific"
24
+ Requires-Dist: scikit-learn>=1.3; extra == "scientific"
25
+ Requires-Dist: statsmodels>=0.14; extra == "scientific"
26
+ Provides-Extra: geometry
27
+ Requires-Dist: scipy>=1.10; extra == "geometry"
28
+ Requires-Dist: scikit-learn>=1.3; extra == "geometry"
29
+ Provides-Extra: graph
30
+ Requires-Dist: networkx>=3.0; extra == "graph"
31
+ Requires-Dist: scipy>=1.10; extra == "graph"
32
+ Requires-Dist: python-igraph>=0.11; extra == "graph"
33
+ Requires-Dist: leidenalg>=0.10; extra == "graph"
34
+ Requires-Dist: gensim>=4.4; python_version < "3.14" and extra == "graph"
35
+ Provides-Extra: graph-node2vec
36
+ Requires-Dist: networkx>=3.0; python_version < "3.13" and extra == "graph-node2vec"
37
+ Requires-Dist: gensim>=4.4; python_version < "3.13" and extra == "graph-node2vec"
38
+ Requires-Dist: node2vec>=0.5; python_version < "3.13" and extra == "graph-node2vec"
39
+ Provides-Extra: audio
40
+ Requires-Dist: librosa<1.0,>=0.11; python_version < "3.12" and extra == "audio"
41
+ Requires-Dist: librosa>=1.0; python_version >= "3.12" and extra == "audio"
42
+ Requires-Dist: scipy>=1.10; extra == "audio"
43
+ Provides-Extra: vision
44
+ Requires-Dist: opencv-python>=4.8; extra == "vision"
45
+ Requires-Dist: scikit-image>=0.22; extra == "vision"
46
+ Requires-Dist: scipy>=1.10; extra == "vision"
47
+ Provides-Extra: signal
48
+ Requires-Dist: scipy>=1.10; extra == "signal"
49
+ Requires-Dist: statsmodels>=0.14; extra == "signal"
50
+ Requires-Dist: EMD-signal>=1.6; extra == "signal"
51
+ Requires-Dist: vmdpy>=0.2; extra == "signal"
52
+ Provides-Extra: topology
53
+ Requires-Dist: gudhi>=3.9; extra == "topology"
54
+ Requires-Dist: scipy>=1.10; extra == "topology"
55
+ Provides-Extra: pointcloud
56
+ Requires-Dist: open3d>=0.18; extra == "pointcloud"
57
+ Requires-Dist: scipy>=1.10; extra == "pointcloud"
58
+ Provides-Extra: text
59
+ Requires-Dist: scikit-learn>=1.3; extra == "text"
60
+ Requires-Dist: gensim>=4.4; extra == "text"
61
+ Requires-Dist: spacy>=3.7; extra == "text"
62
+ Provides-Extra: embeddings
63
+ Requires-Dist: torch>=2.2; extra == "embeddings"
64
+ Requires-Dist: timm>=1.0; extra == "embeddings"
65
+ Requires-Dist: transformers>=4.40; extra == "embeddings"
66
+ Requires-Dist: sentence-transformers>=3.0; extra == "embeddings"
67
+ Requires-Dist: Pillow>=10; extra == "embeddings"
68
+ Provides-Extra: calendar
69
+ Requires-Dist: holidays>=0.50; extra == "calendar"
70
+ Provides-Extra: gpu
71
+ Requires-Dist: cupy-cuda12x[ctk]>=14.0; sys_platform != "darwin" and extra == "gpu"
72
+ Provides-Extra: gpu-cupy
73
+ Requires-Dist: cupy-cuda12x[ctk]>=14.0; sys_platform != "darwin" and extra == "gpu-cupy"
74
+ Provides-Extra: gpu-torch
75
+ Requires-Dist: torch>=2.2; extra == "gpu-torch"
76
+ Provides-Extra: gpu-rapids
77
+ Provides-Extra: full
78
+ Requires-Dist: scipy>=1.10; extra == "full"
79
+ Requires-Dist: scikit-learn>=1.3; extra == "full"
80
+ Requires-Dist: statsmodels>=0.14; extra == "full"
81
+ Requires-Dist: networkx>=3.0; extra == "full"
82
+ Requires-Dist: python-igraph>=0.11; extra == "full"
83
+ Requires-Dist: leidenalg>=0.10; extra == "full"
84
+ Requires-Dist: librosa<1.0,>=0.11; python_version < "3.12" and extra == "full"
85
+ Requires-Dist: librosa>=1.0; python_version >= "3.12" and extra == "full"
86
+ Requires-Dist: opencv-python>=4.8; extra == "full"
87
+ Requires-Dist: scikit-image>=0.22; extra == "full"
88
+ Requires-Dist: EMD-signal>=1.6; extra == "full"
89
+ Requires-Dist: vmdpy>=0.2; extra == "full"
90
+ Requires-Dist: gudhi>=3.9; extra == "full"
91
+ Requires-Dist: open3d>=0.18; extra == "full"
92
+ Requires-Dist: gensim>=4.4; extra == "full"
93
+ Requires-Dist: spacy>=3.7; extra == "full"
94
+ Requires-Dist: holidays>=0.50; extra == "full"
95
+ Requires-Dist: torch>=2.2; extra == "full"
96
+ Requires-Dist: timm>=1.0; extra == "full"
97
+ Requires-Dist: transformers>=4.40; extra == "full"
98
+ Requires-Dist: sentence-transformers>=3.0; extra == "full"
99
+ Requires-Dist: Pillow>=10; extra == "full"
100
+ Provides-Extra: dev
101
+ Requires-Dist: pytest>=8; extra == "dev"
102
+ Requires-Dist: pytest-cov>=5; extra == "dev"
103
+ Requires-Dist: build>=1.2; extra == "dev"
104
+ Dynamic: license-file
105
+
106
+ # FEATM
107
+
108
+ [Repository](https://github.com/Harish-K22/featm) · [Release notes](CHANGELOG.md)
109
+
110
+ **One searchable API for explicit, named feature extraction across data modalities.**
111
+
112
+ Use FEATM to discover an existing feature method by name, compute a small feature
113
+ set, and reuse fitted transformations on new data. You choose the methods;
114
+ FEATM does not select features automatically or promise better model accuracy.
115
+
116
+ ## Quickstart
117
+
118
+ ```python
119
+ import numpy as np
120
+ import featm
121
+
122
+ # Two samples, each with four time steps.
123
+ X = np.array([
124
+ [1.0, 2.0, 3.0, 4.0],
125
+ [10.0, 20.0, 30.0, 40.0],
126
+ ])
127
+ result = featm.extract(
128
+ X,
129
+ features=["timeseries.statistical.mean", "timeseries.statistical.std"],
130
+ errors="raise",
131
+ )
132
+ print(result)
133
+ ```
134
+
135
+ The mean column contains `2.5` and `25.0`: one output row per input sample.
136
+ For time-series features, `(n_steps,)` means one series, and
137
+ `(n_samples, n_steps)` means a batch. An `(8, 1)` array means eight one-step
138
+ series, **not** one eight-step series. Other modalities use different inputs;
139
+ see [input conventions](docs/GETTING_STARTED.md#input-conventions).
140
+
141
+ ## Installation
142
+
143
+ Install FEATM from PyPI:
144
+
145
+ ```bash
146
+ pip install featm
147
+ ```
148
+
149
+ During initial release testing, GitHub remains private; see the
150
+ [repository-access note](docs/INSTALLATION.md#initial-publication-period).
151
+
152
+ The quickstart needs only base dependencies: NumPy, pandas and psutil.
153
+ For checkpoints, Parquet, Arrow or disk-backed output, install the IO extra:
154
+
155
+ ```bash
156
+ python -m pip install "featm[io]"
157
+ ```
158
+
159
+ Quoted requirements work in PowerShell and POSIX shells. See the full
160
+ [installation table](docs/INSTALLATION.md) for minimal optional backends.
161
+
162
+ ## Find a feature
163
+
164
+ ```python
165
+ import numpy as np
166
+ import featm
167
+
168
+ print(featm.list_features("timeseries.fractal.*"))
169
+ print(featm.list_features("*entropy*"))
170
+ print(featm.list_features("*mean*"))
171
+
172
+ spec = featm.feature_info("timeseries.statistical.mean")
173
+ print(spec.input_types, spec.requires, spec.default_params)
174
+ mean = featm.create_feature("timeseries.statistical.mean")
175
+ print(mean(np.array([1.0, 2.0, 3.0, 4.0])))
176
+ ```
177
+
178
+ Names follow `modality.family.feature_name`. Narrow a broad search such as
179
+ `timeseries.*` by family. `list_modalities()`, `list_families()` and `search()`
180
+ also help with discovery. Parameters and input types vary by feature;
181
+ [API guidance](docs/API.md) explains what metadata is available.
182
+ Some features, including MFCC, HOG and LBP, expand into multiple named columns.
183
+ There is intentionally no `features="all"` mode.
184
+
185
+ ## Modalities and inputs
186
+
187
+ The registry covers time series, tabular, graph, image, audio, text, geometry,
188
+ point clouds, signal, video, information, sequence, matrix, topology, manifold,
189
+ spatial, event and multimodal data. Each family has its own input contract.
190
+ For example, text features typically accept an iterable of documents, while
191
+ graph features accept graph objects; do not reshape them using the time-series
192
+ convention.
193
+
194
+ The supporting inventory is 552 registered entries, 18 modalities and 182
195
+ modality/family groups. The [feature catalogue](docs/FEATURE_UNIVERSE.md) lists
196
+ names and dependencies. An entry's availability does not imply that its
197
+ optional backend or external model is installed.
198
+
199
+ ## Reuse state learned from training data
200
+
201
+ ```python
202
+ from pathlib import Path
203
+ from tempfile import TemporaryDirectory
204
+ import numpy as np
205
+ import pandas as pd
206
+ import featm
207
+
208
+ name = "tabular.encoding.category_frequency"
209
+ train = pd.DataFrame({"category": ["A", "A", "B", "B", "B", "C"]})
210
+ test = pd.DataFrame({"category": ["A", "B", "C", "D"]})
211
+ fitted = featm.fit(
212
+ train, features=[name], columns={name: "category"}, errors="raise"
213
+ )
214
+ result = fitted.transform(test)
215
+ print(result.to_pandas())
216
+ np.testing.assert_allclose(result.to_numpy().ravel(), [2/6, 3/6, 1/6, 0])
217
+
218
+ with TemporaryDirectory() as directory:
219
+ path = Path(directory) / "categories.pkl"
220
+ fitted.save(path)
221
+ restored = featm.load_fitted(path)
222
+ np.testing.assert_array_equal(
223
+ result.to_numpy(), restored.transform(test).to_numpy()
224
+ )
225
+ ```
226
+
227
+ Only `train` supplies fitted statistics. Unseen category `D` maps to zero;
228
+ transforming `test` does not refit the encoder. `extract()` fits and transforms
229
+ its own input, so use `fit()` followed by `transform()` for a train/test split.
230
+ There are seven stateful entries, including scaling and corpus-statistic text
231
+ features. See [stateful workflows](docs/GETTING_STARTED.md#stateful-workflows).
232
+
233
+ ## Errors and return types
234
+
235
+ Start with `errors="raise"` so a shape, parameter or dependency error is visible.
236
+ The default `errors="skip"` isolates feature failures and can return an empty
237
+ result if none succeeds. `errors="warn"` also emits warnings. An empty result
238
+ is not proof that every requested feature ran.
239
+
240
+ For a simple in-memory `pandas.DataFrame` result, inspect
241
+ `result.attrs.get("execution_report", {})`. The report is present when this
242
+ path records failures. Out-of-core extraction and fitted transformations use
243
+ `FeatureMatrix`: inspect `result.report` and convert with `result.to_pandas()`.
244
+ For large results, iterate batches rather than materializing everything.
245
+ See [tested error examples](docs/GETTING_STARTED.md#error-policy-and-reports).
246
+
247
+ ## Larger data, checkpointing and execution backends
248
+
249
+ File-backed extraction can read bounded batches, save disk-backed results and
250
+ resume a compatible checkpoint. IO is required for checkpoints even when the
251
+ input is already in memory. Existing incompatible or structurally invalid
252
+ checkpoints fail closed; choose a fresh directory when you want a new run.
253
+ Memory budgets guide execution; they are not a hard cap on total process RSS.
254
+
255
+ CPU is the default. Optional CuPy kernels cover 22 features; strict GPU mode
256
+ raises when a requested GPU implementation is unavailable, while fallback mode
257
+ reports a CPU fallback. Dask distributes eligible features according to their
258
+ batch semantics. Start with [scaling and checkpoints](docs/SCALING.md),
259
+ [GPU setup](docs/INSTALLATION.md#gpu) or [Dask](docs/DISTRIBUTED.md).
260
+
261
+ ## Examples and documentation
262
+
263
+ - [Getting started](docs/GETTING_STARTED.md): shapes, multiple families,
264
+ reports and fitted state.
265
+ - [Installation](docs/INSTALLATION.md) and [compatibility](docs/COMPATIBILITY.md).
266
+ - [Small executable examples](examples/README.md), including audio, images
267
+ and dataset-loading recipes without model-performance claims.
268
+ - [Evidence and benchmark interpretation](docs/BENCHMARKS.md).
269
+ - [Feature authoring](docs/FEATURE_AUTHORING.md) and
270
+ [architecture](docs/ARCHITECTURE.md) for contributors.
271
+
272
+ ## Compatibility and known limits
273
+
274
+ Base certification covers Windows x86-64 and Ubuntu/WSL Linux x86-64 with
275
+ CPython 3.10–3.14. Optional extras have narrower scopes: node2vec is certified
276
+ on 3.10–3.12, and gensim-backed text/DeepWalk paths through 3.13.
277
+ `full` is not a universal recommendation across all base Python versions.
278
+ Real GPU evidence is limited to the tested Windows/CUDA-12/CuPy-14 configuration.
279
+ macOS, ARM and Python 3.15 are **not validated**, rather than proven incompatible.
280
+
281
+ Certain short harmonic/tonnetz inputs can yield non-finite values inside
282
+ librosa. This was reproduced upstream without importing FEATM. No minimum
283
+ safe duration, universal sample-rate claim or upstream fix is asserted.
284
+ See [compatibility details](docs/COMPATIBILITY.md).
285
+
286
+ FEATM is explicit extraction, not AutoML, relational DFS or automatic feature
287
+ selection. New windowing infrastructure and sklearn Pipeline integration are
288
+ outside v0.5.7. A legacy `AutoFeatures` planner remains for compatibility; it
289
+ is not the recommended discovery or extraction workflow.
290
+
291
+ ## Contributing and license
292
+
293
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for setup and reproducible bug reports.
294
+ The owner-confirmed project address is [GitHub](https://github.com/Harish-K22/featm); report reproducible
295
+ problems using the [issue tracker](https://github.com/Harish-K22/featm/issues) once the repository is available.
296
+
297
+ FEATM's own code is distributed under the [MIT License](LICENSE),
298
+ Copyright (c) 2026 Harish K. Optional dependencies, datasets and external models
299
+ retain their own terms. See [third-party scope](THIRD_PARTY_NOTICES.md).