scinexus 2026.4.17a0__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 (96) hide show
  1. scinexus-2026.4.17a0/.github/workflows/ci.yml +97 -0
  2. scinexus-2026.4.17a0/.github/workflows/codeql.yml +42 -0
  3. scinexus-2026.4.17a0/.github/workflows/docs.yml +60 -0
  4. scinexus-2026.4.17a0/.github/workflows/linters.yml +33 -0
  5. scinexus-2026.4.17a0/.github/workflows/release.yml +137 -0
  6. scinexus-2026.4.17a0/.gitignore +66 -0
  7. scinexus-2026.4.17a0/.hgignore +44 -0
  8. scinexus-2026.4.17a0/.readthedocs.yaml +25 -0
  9. scinexus-2026.4.17a0/LICENSE +28 -0
  10. scinexus-2026.4.17a0/PKG-INFO +153 -0
  11. scinexus-2026.4.17a0/README.md +123 -0
  12. scinexus-2026.4.17a0/changelog.md +27 -0
  13. scinexus-2026.4.17a0/docs/conftest.py +8 -0
  14. scinexus-2026.4.17a0/docs/explanation/app-lifecycle.md +48 -0
  15. scinexus-2026.4.17a0/docs/explanation/customisation-hooks.md +100 -0
  16. scinexus-2026.4.17a0/docs/explanation/data-store-model.md +38 -0
  17. scinexus-2026.4.17a0/docs/explanation/index.md +11 -0
  18. scinexus-2026.4.17a0/docs/explanation/not-completed-design.md +83 -0
  19. scinexus-2026.4.17a0/docs/explanation/source-tracking.md +40 -0
  20. scinexus-2026.4.17a0/docs/explanation/type-system.md +21 -0
  21. scinexus-2026.4.17a0/docs/explanation/why-composable-apps.md +22 -0
  22. scinexus-2026.4.17a0/docs/howto/customise-display-and-ids.md +247 -0
  23. scinexus-2026.4.17a0/docs/howto/extend-type-checking.md +115 -0
  24. scinexus-2026.4.17a0/docs/howto/handle-failures.md +241 -0
  25. scinexus-2026.4.17a0/docs/howto/index.md +14 -0
  26. scinexus-2026.4.17a0/docs/howto/log-and-cite.md +193 -0
  27. scinexus-2026.4.17a0/docs/howto/read-and-write-files.md +133 -0
  28. scinexus-2026.4.17a0/docs/howto/run-in-parallel.md +158 -0
  29. scinexus-2026.4.17a0/docs/howto/track-progress.md +145 -0
  30. scinexus-2026.4.17a0/docs/howto/use-data-stores.md +283 -0
  31. scinexus-2026.4.17a0/docs/howto/write-a-class-app.md +122 -0
  32. scinexus-2026.4.17a0/docs/howto/write-a-function-app.md +74 -0
  33. scinexus-2026.4.17a0/docs/index.md +33 -0
  34. scinexus-2026.4.17a0/docs/install.md +24 -0
  35. scinexus-2026.4.17a0/docs/reference/app-classes.md +23 -0
  36. scinexus-2026.4.17a0/docs/reference/data-stores.md +55 -0
  37. scinexus-2026.4.17a0/docs/reference/define-app.md +11 -0
  38. scinexus-2026.4.17a0/docs/reference/deserialise.md +7 -0
  39. scinexus-2026.4.17a0/docs/reference/index.md +19 -0
  40. scinexus-2026.4.17a0/docs/reference/io-util.md +7 -0
  41. scinexus-2026.4.17a0/docs/reference/not-completed.md +11 -0
  42. scinexus-2026.4.17a0/docs/reference/parallel.md +7 -0
  43. scinexus-2026.4.17a0/docs/reference/progress.md +7 -0
  44. scinexus-2026.4.17a0/docs/reference/source-proxy.md +11 -0
  45. scinexus-2026.4.17a0/docs/reference/utilities.md +29 -0
  46. scinexus-2026.4.17a0/docs/scripts/cog_utils.py +146 -0
  47. scinexus-2026.4.17a0/docs/tutorials/composing-apps.md +170 -0
  48. scinexus-2026.4.17a0/docs/tutorials/index.md +6 -0
  49. scinexus-2026.4.17a0/docs/tutorials/processing-a-dataset.md +78 -0
  50. scinexus-2026.4.17a0/docs/tutorials/your-first-app.md +0 -0
  51. scinexus-2026.4.17a0/noxfile.py +178 -0
  52. scinexus-2026.4.17a0/pyproject.toml +74 -0
  53. scinexus-2026.4.17a0/rtd_get_docs.py +150 -0
  54. scinexus-2026.4.17a0/ruff.toml +119 -0
  55. scinexus-2026.4.17a0/scripts/run_mypy_cov.py +10 -0
  56. scinexus-2026.4.17a0/src/scinexus/__init__.py +72 -0
  57. scinexus-2026.4.17a0/src/scinexus/_mypy_plugin.py +103 -0
  58. scinexus-2026.4.17a0/src/scinexus/_version.py +1 -0
  59. scinexus-2026.4.17a0/src/scinexus/composable.py +1177 -0
  60. scinexus-2026.4.17a0/src/scinexus/data_store.py +980 -0
  61. scinexus-2026.4.17a0/src/scinexus/deserialise.py +126 -0
  62. scinexus-2026.4.17a0/src/scinexus/io.py +245 -0
  63. scinexus-2026.4.17a0/src/scinexus/io_util.py +472 -0
  64. scinexus-2026.4.17a0/src/scinexus/misc.py +91 -0
  65. scinexus-2026.4.17a0/src/scinexus/parallel.py +299 -0
  66. scinexus-2026.4.17a0/src/scinexus/progress.py +517 -0
  67. scinexus-2026.4.17a0/src/scinexus/py.typed +0 -0
  68. scinexus-2026.4.17a0/src/scinexus/sqlite_data_store.py +532 -0
  69. scinexus-2026.4.17a0/src/scinexus/typing.py +238 -0
  70. scinexus-2026.4.17a0/src/scinexus/warning.py +257 -0
  71. scinexus-2026.4.17a0/tests/conftest.py +41 -0
  72. scinexus-2026.4.17a0/tests/data/brca1.fasta +2145 -0
  73. scinexus-2026.4.17a0/tests/data/c_elegans_WS199_dna_shortened.fasta +3 -0
  74. scinexus-2026.4.17a0/tests/data/formattest.fasta +60 -0
  75. scinexus-2026.4.17a0/tests/data/formattest.fasta.gz +0 -0
  76. scinexus-2026.4.17a0/tests/data/long_testseqs.fasta +220 -0
  77. scinexus-2026.4.17a0/tests/data/primate_brca1.fasta +336 -0
  78. scinexus-2026.4.17a0/tests/data/primates_brca1.fasta +500 -0
  79. scinexus-2026.4.17a0/tests/data/sample.tsv +4 -0
  80. scinexus-2026.4.17a0/tests/data/scitrack.log +45 -0
  81. scinexus-2026.4.17a0/tests/test_composable.py +2737 -0
  82. scinexus-2026.4.17a0/tests/test_data_store.py +1236 -0
  83. scinexus-2026.4.17a0/tests/test_deserialise.py +98 -0
  84. scinexus-2026.4.17a0/tests/test_init.py +43 -0
  85. scinexus-2026.4.17a0/tests/test_io.py +282 -0
  86. scinexus-2026.4.17a0/tests/test_io_util.py +521 -0
  87. scinexus-2026.4.17a0/tests/test_misc.py +163 -0
  88. scinexus-2026.4.17a0/tests/test_mypy_typing.py +180 -0
  89. scinexus-2026.4.17a0/tests/test_parallel.py +186 -0
  90. scinexus-2026.4.17a0/tests/test_parallel_mpi.py +212 -0
  91. scinexus-2026.4.17a0/tests/test_progress.py +905 -0
  92. scinexus-2026.4.17a0/tests/test_sqlite_data_store.py +763 -0
  93. scinexus-2026.4.17a0/tests/test_typing.py +335 -0
  94. scinexus-2026.4.17a0/tests/test_warning.py +240 -0
  95. scinexus-2026.4.17a0/uv.lock +1506 -0
  96. scinexus-2026.4.17a0/zensical.toml +312 -0
@@ -0,0 +1,97 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ pull_request:
6
+
7
+ # NOTE:
8
+ # if changing python versions, also update versions in
9
+ # - release.yml
10
+ # - noxfile.py
11
+
12
+ jobs:
13
+ tests:
14
+ name: "Python ${{ matrix.python-version }} (${{ matrix.os }})"
15
+ runs-on: ${{ matrix.os }}
16
+
17
+ strategy:
18
+ matrix:
19
+ os: [ubuntu-latest, macos-latest, windows-latest]
20
+ python-version: ["3.11", "3.14"]
21
+
22
+ steps:
23
+ - uses: "actions/checkout@v6"
24
+ with:
25
+ fetch-depth: 0
26
+
27
+ # Setup env
28
+ - uses: "actions/setup-python@v6"
29
+ with:
30
+ python-version: "${{ matrix.python-version }}"
31
+
32
+ - name: Install uv
33
+ uses: astral-sh/setup-uv@v7
34
+ with:
35
+ enable-cache: true
36
+ cache-dependency-glob: "pyproject.toml"
37
+
38
+ - name: Install MPI (Ubuntu)
39
+ if: startsWith(matrix.os, 'ubuntu')
40
+ run: |
41
+ sudo apt-get update
42
+ sudo apt-get install -y openmpi-bin libopenmpi-dev
43
+
44
+ - name: "Run nox for ${{ matrix.python-version }}"
45
+ shell: bash
46
+ run: |
47
+ lname="snx-${{matrix.os}}-${{matrix.python-version}}.lcov"
48
+ xname="snx-${{matrix.os}}-${{matrix.python-version}}.xml"
49
+ cov="lcov -o$lname xml -o$xname"
50
+ uv run --group test nox --force-python python -s testcov -- $cov
51
+
52
+ - name: Coveralls Parallel
53
+ uses: coverallsapp/github-action@v2
54
+ with:
55
+ parallel: true
56
+ github-token: ${{ secrets.github_token }}
57
+ flag-name: run-${{matrix.python-version}}-${{matrix.os}}
58
+ file: "snx-${{matrix.os}}-${{matrix.python-version}}.lcov"
59
+
60
+ type_check:
61
+ name: Type Check
62
+ runs-on: ${{ matrix.os }}
63
+
64
+ strategy:
65
+ matrix:
66
+ python-version: ["3.14"]
67
+ os: [ubuntu-latest]
68
+
69
+ steps:
70
+ - uses: actions/checkout@v6
71
+ with:
72
+ fetch-depth: 0
73
+
74
+ - uses: "actions/setup-python@v6"
75
+ with:
76
+ python-version: "${{ matrix.python-version }}"
77
+
78
+ - name: Install uv
79
+ uses: astral-sh/setup-uv@v7
80
+ with:
81
+ enable-cache: true
82
+ cache-dependency-glob: "pyproject.toml"
83
+
84
+ - name: "Run Type Checking for ${{ matrix.python-version }}"
85
+ run: |
86
+ uv run --group test nox --force-python python -s type_check
87
+
88
+ finish:
89
+ name: "Finish Coveralls"
90
+ needs: tests
91
+ runs-on: ubuntu-latest
92
+ steps:
93
+ - name: Coveralls Finished
94
+ uses: coverallsapp/github-action@v2
95
+ with:
96
+ github-token: ${{ secrets.github_token }}
97
+ parallel-finished: true
@@ -0,0 +1,42 @@
1
+ name: "CodeQL"
2
+
3
+ on:
4
+ push:
5
+ branches-ignore:
6
+ - master
7
+ pull_request:
8
+ branches-ignore:
9
+ - master
10
+ schedule:
11
+ - cron: '39 20 * * 6'
12
+
13
+ jobs:
14
+ analyze:
15
+ name: Analyze
16
+ runs-on: ubuntu-latest
17
+ permissions:
18
+ actions: read
19
+ contents: read
20
+ security-events: write
21
+
22
+ strategy:
23
+ fail-fast: false
24
+ matrix:
25
+ language: [ 'python' ]
26
+
27
+ steps:
28
+ - name: Checkout repository
29
+ uses: actions/checkout@v6
30
+
31
+ - name: Initialize CodeQL
32
+ uses: github/codeql-action/init@v4
33
+ with:
34
+ languages: ${{ matrix.language }}
35
+
36
+ - name: Autobuild
37
+ uses: github/codeql-action/autobuild@v4
38
+
39
+ - name: Perform CodeQL Analysis
40
+ uses: github/codeql-action/analyze@v4
41
+ with:
42
+ category: "/language:${{matrix.language}}"
@@ -0,0 +1,60 @@
1
+ name: Build Docs
2
+
3
+ concurrency:
4
+ group: docs-build-${{ github.ref }}
5
+ cancel-in-progress: true
6
+ on:
7
+ workflow_dispatch:
8
+ push:
9
+ branches:
10
+ - main
11
+ paths:
12
+ - 'docs/**'
13
+ - '.readthedocs.yaml'
14
+ - 'mkdocs.yml'
15
+ - 'rtd_get_docs.py'
16
+
17
+ permissions:
18
+ contents: read
19
+
20
+ jobs:
21
+ build-docs:
22
+ runs-on: ubuntu-latest
23
+
24
+ steps:
25
+ - name: Checkout Repository
26
+ uses: actions/checkout@v4
27
+ with:
28
+ fetch-depth: 0
29
+ submodules: recursive
30
+
31
+ - uses: "actions/setup-python@v5"
32
+ with:
33
+ python-version: "3.14"
34
+
35
+ - name: Install uv
36
+ uses: astral-sh/setup-uv@v7
37
+ with:
38
+ enable-cache: true
39
+ cache-dependency-glob: "pyproject.toml"
40
+
41
+ - name: Install Docs Dependencies
42
+ run: |
43
+ uv venv venv -p python
44
+ source venv/bin/activate
45
+ uv pip install ".[test]"
46
+
47
+ - name: Build Documentation
48
+ run: |
49
+ source venv/bin/activate
50
+ # update executable components
51
+ uv run nox -s cogdocs
52
+ # build actual docs
53
+ zensical build --clean
54
+ working-directory: ${{ github.workspace }}
55
+
56
+ - name: Upload Documentation Artifact
57
+ uses: actions/upload-artifact@v4
58
+ with:
59
+ name: scinexus-docs-html
60
+ path: site
@@ -0,0 +1,33 @@
1
+ name: Lint code using ruff
2
+
3
+ on:
4
+ push:
5
+ pull_request:
6
+
7
+ jobs:
8
+ linters:
9
+ runs-on: ubuntu-latest
10
+ if: github.repository != 'cogent3/SciNexus'
11
+ steps:
12
+ - uses: actions/checkout@v6
13
+ - name: Set up Python
14
+ uses: actions/setup-python@v6
15
+ with:
16
+ python-version: '3.14'
17
+
18
+ - name: Install uv
19
+ uses: astral-sh/setup-uv@v7
20
+ with:
21
+ enable-cache: true
22
+ cache-dependency-glob: "pyproject.toml"
23
+
24
+ - name: Format code using ruff
25
+ run: uv run --group test nox -s fmt
26
+
27
+ - name: Commit changes
28
+ uses: EndBug/add-and-commit@v10
29
+ with:
30
+ author_name: ${{ github.actor }}
31
+ author_email: ${{ github.actor }}@users.noreply.github.com
32
+ message: "STY: pre-commit linting with ruff"
33
+ add: "."
@@ -0,0 +1,137 @@
1
+ name: Release
2
+
3
+ on: [workflow_dispatch]
4
+
5
+ jobs:
6
+ test:
7
+ name: "Test on Python ${{ matrix.python-version }} (${{ matrix.os }})"
8
+ runs-on: ${{ matrix.os }}
9
+ strategy:
10
+ matrix:
11
+ os: [ubuntu-latest, macos-latest, windows-latest]
12
+ python-version: ["3.11", "3.12", "3.13", "3.14"]
13
+ steps:
14
+ - uses: "actions/checkout@v6"
15
+ with:
16
+ fetch-depth: 0
17
+
18
+ # Setup env
19
+ - uses: "actions/setup-python@v6"
20
+ with:
21
+ python-version: "${{ matrix.python-version }}"
22
+
23
+ - name: Install MPI (Ubuntu)
24
+ if: startsWith(matrix.os, 'ubuntu')
25
+ run: |
26
+ sudo apt-get update
27
+ sudo apt-get install -y openmpi-bin libopenmpi-dev
28
+
29
+ - name: Install uv
30
+ uses: astral-sh/setup-uv@v7
31
+ with:
32
+ enable-cache: true
33
+ cache-dependency-glob: "pyproject.toml"
34
+
35
+ - name: "Run nox for ${{ matrix.python-version }}"
36
+ shell: bash
37
+ run: |
38
+ uv run --group test nox -db uv --force-python python -s test
39
+ uv run --group test nox -db uv --force-python python -s test_types
40
+ uv run --group test nox -db uv --force-python python -s test_docs
41
+
42
+ - name: "Run MPI tests"
43
+ if: startsWith(matrix.os, 'ubuntu')
44
+ shell: bash
45
+ run: |
46
+ uv run --group test nox -db uv --force-python python -s testmpi
47
+
48
+ # docbuild:
49
+ # name: "Test the docs"
50
+ # runs-on: ubuntu-latest
51
+ # steps:
52
+ # - uses: "actions/checkout@v6"
53
+ # with:
54
+ # fetch-depth: 0
55
+
56
+ # - uses: "actions/setup-python@v6"
57
+ # with:
58
+ # python-version: "3.14"
59
+
60
+ # - name: Install uv
61
+ # uses: astral-sh/setup-uv@v7
62
+ # with:
63
+ # enable-cache: true
64
+ # cache-dependency-glob: "pyproject.toml"
65
+
66
+ # - name: "test the docs code"
67
+ # run: "uv run --group test zensical build"
68
+
69
+ build:
70
+ name: Build wheel and sdist
71
+ needs: test
72
+ runs-on: ubuntu-latest
73
+
74
+ steps:
75
+ - uses: actions/checkout@v6
76
+ with:
77
+ fetch-depth: 0
78
+
79
+ - uses: actions/setup-python@v6
80
+ with:
81
+ python-version: '3.14'
82
+
83
+ - name: Install uv
84
+ uses: astral-sh/setup-uv@v7
85
+ with:
86
+ enable-cache: true
87
+ cache-dependency-glob: "pyproject.toml"
88
+
89
+ - name: Build sdist and wheel
90
+ run: uv build
91
+
92
+ - name: Upload sdist and wheel
93
+ uses: actions/upload-artifact@v7
94
+ with:
95
+ name: snx-wheel-sdist
96
+ path: |
97
+ ./dist/*.whl
98
+ ./dist/*.tar.gz
99
+
100
+ release_test:
101
+ name: Release to Test PyPI
102
+ needs: build
103
+ # needs: [build, docbuild]
104
+ environment: release_test
105
+ runs-on: ubuntu-latest
106
+ permissions:
107
+ id-token: write
108
+
109
+ steps:
110
+ - name: Download sdist and wheel
111
+ uses: actions/download-artifact@v8
112
+ with:
113
+ name: snx-wheel-sdist
114
+ path: ./dist
115
+
116
+ - name: Publish package distributions to Test PyPI
117
+ uses: pypa/gh-action-pypi-publish@release/v1
118
+ with:
119
+ repository-url: https://test.pypi.org/legacy/
120
+
121
+ release:
122
+ name: Release to PyPI
123
+ needs: release_test
124
+ environment: release
125
+ runs-on: ubuntu-latest
126
+ permissions:
127
+ id-token: write
128
+
129
+ steps:
130
+ - name: Download sdist and wheel
131
+ uses: actions/download-artifact@v8
132
+ with:
133
+ name: snx-wheel-sdist
134
+ path: ./dist
135
+
136
+ - name: Publish package distributions to PyPI
137
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,66 @@
1
+ *.py[cod]
2
+
3
+ # C extensions
4
+ *.so
5
+
6
+ # Packages
7
+ *.egg
8
+ *.egg-info
9
+ dist
10
+ build
11
+ eggs
12
+ parts
13
+ bin
14
+ var
15
+ sdist
16
+ develop-eggs
17
+ .installed.cfg
18
+ lib
19
+ lib64
20
+ doc/_build
21
+
22
+ # docker stuff
23
+ .devcontainer/*
24
+
25
+ # Installer logs
26
+ pip-log.txt
27
+
28
+ # Unit test / coverage reports
29
+ .mypy*
30
+ **/.mypy_cache/*
31
+ .coverage*
32
+ .tox
33
+ .nox
34
+ coverage.xml
35
+ junit-*.xml
36
+ nosetests.xml
37
+ lcov*.info
38
+ .ruff_cache/*
39
+
40
+ # Translations
41
+ *.mo
42
+
43
+ # Mr Developer
44
+ .mr.developer.cfg
45
+ .project
46
+ .pydevproject
47
+ .idea/*
48
+ .DS_Store
49
+ __pycache__
50
+ *.code-workspace
51
+ *.wpr
52
+ *.wpu
53
+ .vscode/*
54
+ venv*
55
+ .venv*
56
+ working/
57
+ *.ipynb
58
+ *.ipynb_checkpoints/
59
+
60
+ # vi
61
+ .*.swp
62
+
63
+
64
+ CLAUDE.md
65
+
66
+ site/*
@@ -0,0 +1,44 @@
1
+ syntax:glob
2
+ .svn
3
+ *.pyc
4
+ *.pyo
5
+ *.so
6
+ *.o
7
+ *.DS_Store
8
+ *.tmproj
9
+ *.rej
10
+ *.orig
11
+ *.wpr
12
+ *.pdf
13
+ _build/*
14
+ build
15
+ *htmlcov*
16
+ *.idea
17
+ *.coverage*
18
+ *egg-info*
19
+ *.wpu
20
+ .cache*
21
+ *taskpaper
22
+ *.ipynb
23
+ *.ipynb_checkpoints*
24
+ *.sublime*
25
+ *.patch
26
+ *.pytest_cache
27
+ *.tox
28
+ *.nox
29
+ *.vscode
30
+ *.code-workspace
31
+ coverage.xml
32
+ __pycache__
33
+ junit-*.xml
34
+ dist/*
35
+ working/*
36
+ lcov*.info
37
+ .ruff_cache/*
38
+ .devcontainer/*
39
+ venv*
40
+ .venv*
41
+ .mypy*
42
+ CLAUDE.md
43
+ site/*
44
+ docs/data/*
@@ -0,0 +1,25 @@
1
+ # .readthedocs.yaml
2
+ # Read the Docs configuration file for MkDocs projects
3
+ # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
4
+
5
+ # Required
6
+ version: 2
7
+
8
+ # Set the version of Python and other tools you might need
9
+ build:
10
+ os: ubuntu-22.04
11
+ tools:
12
+ python: "3.14"
13
+ commands:
14
+ # Install the required dependencies
15
+ - pip install requests
16
+ # Run the script to download and extract the pre-built docs
17
+ - python rtd_get_docs.py
18
+ - echo "Documentation downloaded and extracted"
19
+
20
+ # Disable the default build processes since we're using pre-built docs
21
+ sphinx:
22
+ configuration: null
23
+
24
+ python:
25
+ install: []
@@ -0,0 +1,28 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2026, cogent3
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ 1. Redistributions of source code must retain the above copyright notice, this
9
+ list of conditions and the following disclaimer.
10
+
11
+ 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ this list of conditions and the following disclaimer in the documentation
13
+ and/or other materials provided with the distribution.
14
+
15
+ 3. Neither the name of the copyright holder nor the names of its
16
+ contributors may be used to endorse or promote products derived from
17
+ this software without specific prior written permission.
18
+
19
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,153 @@
1
+ Metadata-Version: 2.4
2
+ Name: scinexus
3
+ Version: 2026.4.17a0
4
+ Summary: A composable app infrastructure for scientific computing
5
+ License-Expression: BSD-3-Clause
6
+ License-File: LICENSE
7
+ Classifier: Development Status :: 5 - Production/Stable
8
+ Classifier: Intended Audience :: Science/Research
9
+ Classifier: License :: OSI Approved :: BSD License
10
+ Classifier: Operating System :: OS Independent
11
+ Classifier: Programming Language :: Python :: 3.11
12
+ Classifier: Programming Language :: Python :: 3.12
13
+ Classifier: Programming Language :: Python :: 3.13
14
+ Classifier: Programming Language :: Python :: 3.14
15
+ Classifier: Topic :: Scientific/Engineering
16
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
17
+ Classifier: Topic :: System :: Distributed Computing
18
+ Requires-Python: >=3.11
19
+ Requires-Dist: charset-normalizer
20
+ Requires-Dist: citeable
21
+ Requires-Dist: loky
22
+ Requires-Dist: scitrack
23
+ Requires-Dist: tqdm
24
+ Requires-Dist: typeguard
25
+ Provides-Extra: mpi
26
+ Requires-Dist: mpi4py; extra == 'mpi'
27
+ Provides-Extra: rich
28
+ Requires-Dist: rich; extra == 'rich'
29
+ Description-Content-Type: text/markdown
30
+
31
+ [![Coverage Status](https://coveralls.io/repos/github/cogent3/scinexus/badge.svg?branch=main)](https://coveralls.io/github/cogent3/scinexus?branch=main)
32
+ [![Codacy Badge](https://app.codacy.com/project/badge/Grade/fd8810efd4f142069bd84144e14350b4)](https://app.codacy.com/gh/cogent3/scinexus/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade)
33
+ [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
34
+ [![CI](https://github.com/cogent3/scinexus/actions/workflows/ci.yml/badge.svg)](https://github.com/cogent3/scinexus/actions/workflows/ci.yml)
35
+
36
+ # scinexus
37
+
38
+ *A composable app infrastructure for scientific computing. What dataclasses are for structured data, `scinexus` apps are for structured algorithms.*
39
+
40
+ Many scientific problems require repeating calculations across many files or database records. Such tasks suit data-level parallelism, but writing robust, maintainable code for them is often tedious and quickly becomes complex.
41
+
42
+ As the Unix philosophy articulates, writing algorithms that do one thing well and can be composed together through piping data of known type is a *Very Good Thing*™.
43
+
44
+ **`scinexus` encourages this design pattern.** We leverage the Python type annotation system to govern the compatibility (composability) of different applications. This enables in-process composition of your applications with validation of the consistency of the pipeline and the consistency of the data being run through it.
45
+
46
+ **`scinexus` is designed for scientific reproducibility.** Scientific computations should record all conditions needed to reproduce an analysis. `scinexus` reduces the effort by intercepting all arguments (including defaults) used in app construction and logging the resulting app state.
47
+
48
+ ## Examples
49
+
50
+ Developers can choose inheriting from a base class or use the `scinexus.define_app` decorator to make composable apps. The following examples show simple composition
51
+
52
+ <details>
53
+ <summary>Loading files so missing data does not cause a crash</summary>
54
+
55
+ ```python
56
+ from scinexus import define_app
57
+
58
+ @define_app(app_type="loader")
59
+ def read_json(path: str) -> dict:
60
+ import json
61
+ with open(path) as f:
62
+ return json.load(f)
63
+
64
+ @define_app
65
+ def validate(data: dict, required_field: str) -> dict:
66
+ if required_field not in data:
67
+ raise ValueError(f"missing {required_field!r} field") # becomes NotCompleted, doesn't crash
68
+ return data
69
+
70
+ app = read_json() + validate(required_field="name")
71
+ ```
72
+
73
+ You can apply `app` to a single file path as `app(filepath)`, or operate in parallel (and show a progress bar) on a sequence of file paths as
74
+
75
+ ```python
76
+ results = list(app.as_completed(["some_file_path.json", "some_other_file_path.json"], parallel=True, show_progress=True)
77
+ ```
78
+
79
+ </details>
80
+
81
+ <details>
82
+ <summary>A contrived numerical example</summary>
83
+
84
+ ```python
85
+ from scinexus import define_app
86
+
87
+
88
+ @define_app
89
+ def normalise(values: list[float]) -> list[float]:
90
+ lo, hi = min(values), max(values)
91
+ return [(v - lo) / (hi - lo) for v in values]
92
+
93
+ @define_app
94
+ def threshold(values: list[float]) -> list[bool]:
95
+ return [v > 0.5 for v in values]
96
+
97
+ app = normalise() + threshold()
98
+ app([1.0, 5.0, 3.0, 9.0])
99
+ ```
100
+
101
+ </details>
102
+
103
+ <details>
104
+ <summary>A configurable app</summary>
105
+
106
+ ```python
107
+ from scinexus import define_app
108
+
109
+
110
+ @define_app(app_type="loader")
111
+ def load_csv(path: str) -> list[dict]:
112
+ import csv
113
+
114
+ with open(path) as f:
115
+ return list(csv.DictReader(f))
116
+
117
+ @define_app
118
+ class summarise:
119
+ def __init__(self, column: str) -> None:
120
+ """column contains the values to produce summary stats for"""
121
+ self.column = column
122
+
123
+ def main(self, rows: list[dict]) -> dict[str, float]:
124
+ vals = [float(r[self.column]) for r in rows]
125
+ return {"mean": sum(vals) / len(vals), "min": min(vals), "max": max(vals)}
126
+
127
+ app = load_csv() + summarise(column="price")
128
+ ```
129
+
130
+ </details>
131
+
132
+ ## Features
133
+
134
+ - Type checking at composition time
135
+ - Durable computing -- failures recorded as `NotCompleted` records, not exceptions
136
+ - Data-level parallel execution via `loky` or MPI
137
+ - Progress bars (`tqdm` or `rich`)
138
+ - Automated logging and citation tracking
139
+ - Checkpointing via data stores (directory, SQLite)
140
+
141
+ ## Installation
142
+
143
+ ```bash
144
+ pip install scinexus
145
+ ```
146
+
147
+ ## History
148
+
149
+ The app framework and utility functions in `scinexus` incubated inside [cogent3](https://github.com/cogent3/cogent3) from March 2019, accumulating over five years of development, testing, and real-world use in computational genomics before being extracted into a standalone package. The design is mature and has underpinned analyses in published studies.
150
+
151
+ The extraction into `scinexus` makes the infrastructure available to any scientific Python project, free of the `cogent3` dependency.
152
+
153
+ We acknowledge here that many members of the `cogent3` community contributed to the code that now lives here, including [@rmcar17](https://github.com/rmcar17), [@Nick-Foto](https://github.com/Nick-Foto), [@KatherineCaley](https://github.com/KatherineCaley), [@fredjaya](https://github.com/fredjaya), and [@khiron](https://github.com/khiron).