hyped-crane 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- hyped_crane-0.1.0/.github/workflows/linting.yml +30 -0
- hyped_crane-0.1.0/.github/workflows/publish.yml +98 -0
- hyped_crane-0.1.0/.github/workflows/tests.yml +48 -0
- hyped_crane-0.1.0/.gitignore +147 -0
- hyped_crane-0.1.0/.pre-commit-config.yaml +20 -0
- hyped_crane-0.1.0/PKG-INFO +125 -0
- hyped_crane-0.1.0/README.md +95 -0
- hyped_crane-0.1.0/pyproject.toml +96 -0
- hyped_crane-0.1.0/setup.cfg +4 -0
- hyped_crane-0.1.0/src/crane/__init__.py +46 -0
- hyped_crane-0.1.0/src/crane/__version__.py +16 -0
- hyped_crane-0.1.0/src/crane/arrow.py +94 -0
- hyped_crane-0.1.0/src/crane/core/__init__.py +20 -0
- hyped_crane-0.1.0/src/crane/core/callbacks/__init__.py +6 -0
- hyped_crane-0.1.0/src/crane/core/callbacks/base.py +147 -0
- hyped_crane-0.1.0/src/crane/core/callbacks/tqdm_reporter.py +137 -0
- hyped_crane-0.1.0/src/crane/core/consumer.py +108 -0
- hyped_crane-0.1.0/src/crane/core/monitor.py +495 -0
- hyped_crane-0.1.0/src/crane/core/runners/__init__.py +5 -0
- hyped_crane-0.1.0/src/crane/core/runners/base.py +77 -0
- hyped_crane-0.1.0/src/crane/core/runners/main_process_runner.py +194 -0
- hyped_crane-0.1.0/src/crane/core/runners/multi_process_runner.py +1243 -0
- hyped_crane-0.1.0/src/crane/core/sharding.py +257 -0
- hyped_crane-0.1.0/src/crane/core/utils.py +591 -0
- hyped_crane-0.1.0/src/crane/core/worker.py +81 -0
- hyped_crane-0.1.0/src/crane/core/writer.py +344 -0
- hyped_crane-0.1.0/src/crane/json.py +75 -0
- hyped_crane-0.1.0/src/crane/logging/__init__.py +1 -0
- hyped_crane-0.1.0/src/crane/logging/formatter.py +14 -0
- hyped_crane-0.1.0/src/crane/logging/setup.py +63 -0
- hyped_crane-0.1.0/src/hyped_crane.egg-info/PKG-INFO +125 -0
- hyped_crane-0.1.0/src/hyped_crane.egg-info/SOURCES.txt +53 -0
- hyped_crane-0.1.0/src/hyped_crane.egg-info/dependency_links.txt +1 -0
- hyped_crane-0.1.0/src/hyped_crane.egg-info/requires.txt +20 -0
- hyped_crane-0.1.0/src/hyped_crane.egg-info/top_level.txt +1 -0
- hyped_crane-0.1.0/tests/__init__.py +0 -0
- hyped_crane-0.1.0/tests/crane/__init__.py +0 -0
- hyped_crane-0.1.0/tests/crane/base.py +36 -0
- hyped_crane-0.1.0/tests/crane/core/__init__.py +0 -0
- hyped_crane-0.1.0/tests/crane/core/callbacks/__init__.py +0 -0
- hyped_crane-0.1.0/tests/crane/core/callbacks/test_base.py +70 -0
- hyped_crane-0.1.0/tests/crane/core/callbacks/test_tqdm_reporter.py +43 -0
- hyped_crane-0.1.0/tests/crane/core/runners/__init__.py +0 -0
- hyped_crane-0.1.0/tests/crane/core/runners/test_main_process_runner.py +61 -0
- hyped_crane-0.1.0/tests/crane/core/runners/test_multi_process_runner.py +307 -0
- hyped_crane-0.1.0/tests/crane/core/test_consumer.py +113 -0
- hyped_crane-0.1.0/tests/crane/core/test_monitor.py +126 -0
- hyped_crane-0.1.0/tests/crane/core/test_sharding.py +238 -0
- hyped_crane-0.1.0/tests/crane/core/test_utils.py +107 -0
- hyped_crane-0.1.0/tests/crane/core/test_writer.py +124 -0
- hyped_crane-0.1.0/tests/crane/test_arrow.py +37 -0
- hyped_crane-0.1.0/tests/crane/test_json.py +24 -0
- hyped_crane-0.1.0/tests/third_party/sharedmock/__init__.py +1 -0
- hyped_crane-0.1.0/tests/third_party/sharedmock/asserters.py +35 -0
- hyped_crane-0.1.0/tests/third_party/sharedmock/mock.py +87 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
name: Linting
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
pull_request:
|
|
8
|
+
branches:
|
|
9
|
+
- main
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
build:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
- name: Set up Python
|
|
18
|
+
uses: actions/setup-python@v4
|
|
19
|
+
with:
|
|
20
|
+
python-version: '3.11'
|
|
21
|
+
cache: 'pip'
|
|
22
|
+
|
|
23
|
+
- name: Install dependencies
|
|
24
|
+
run: |
|
|
25
|
+
python -m pip install --upgrade pip
|
|
26
|
+
pip install pre-commit
|
|
27
|
+
pre-commit install
|
|
28
|
+
|
|
29
|
+
- name: Analysing the code with pre-commit
|
|
30
|
+
run: pre-commit run --all-files
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
name: Publish Python 🐍 distribution 📦 to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
create:
|
|
5
|
+
tags:
|
|
6
|
+
- "v[0-9]+.[0-9]+.[0-9]+"
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
build:
|
|
10
|
+
name: Build distribution 📦
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v4
|
|
15
|
+
with:
|
|
16
|
+
persist-credentials: false
|
|
17
|
+
- name: Set up Python
|
|
18
|
+
uses: actions/setup-python@v5
|
|
19
|
+
with:
|
|
20
|
+
python-version: "3.x"
|
|
21
|
+
- name: Install pypa/build
|
|
22
|
+
run: >-
|
|
23
|
+
python3 -m
|
|
24
|
+
pip install
|
|
25
|
+
build
|
|
26
|
+
--user
|
|
27
|
+
- name: Build a binary wheel and a source tarball
|
|
28
|
+
run: python3 -m build
|
|
29
|
+
- name: Store the distribution packages
|
|
30
|
+
uses: actions/upload-artifact@v4
|
|
31
|
+
with:
|
|
32
|
+
name: python-package-distributions
|
|
33
|
+
path: dist/
|
|
34
|
+
|
|
35
|
+
publish-to-pypi:
|
|
36
|
+
name: Publish Python 🐍 distribution 📦 to PyPI
|
|
37
|
+
needs:
|
|
38
|
+
- build
|
|
39
|
+
runs-on: ubuntu-latest
|
|
40
|
+
|
|
41
|
+
environment:
|
|
42
|
+
name: pypi
|
|
43
|
+
url: https://pypi.org/p/hyped-crane
|
|
44
|
+
|
|
45
|
+
permissions:
|
|
46
|
+
id-token: write
|
|
47
|
+
|
|
48
|
+
steps:
|
|
49
|
+
- name: Download all the dists
|
|
50
|
+
uses: actions/download-artifact@v4
|
|
51
|
+
with:
|
|
52
|
+
name: python-package-distributions
|
|
53
|
+
path: dist/
|
|
54
|
+
- name: Publish distribution 📦 to PyPI
|
|
55
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
56
|
+
|
|
57
|
+
github-release:
|
|
58
|
+
name: >-
|
|
59
|
+
Sign the Python 🐍 distribution 📦 with Sigstore
|
|
60
|
+
and upload them to GitHub Release
|
|
61
|
+
needs:
|
|
62
|
+
- publish-to-pypi
|
|
63
|
+
runs-on: ubuntu-latest
|
|
64
|
+
|
|
65
|
+
permissions:
|
|
66
|
+
contents: write # IMPORTANT: mandatory for making GitHub Releases
|
|
67
|
+
id-token: write # IMPORTANT: mandatory for sigstore
|
|
68
|
+
|
|
69
|
+
steps:
|
|
70
|
+
- name: Download all the dists
|
|
71
|
+
uses: actions/download-artifact@v4
|
|
72
|
+
with:
|
|
73
|
+
name: python-package-distributions
|
|
74
|
+
path: dist/
|
|
75
|
+
- name: Sign the dists with Sigstore
|
|
76
|
+
uses: sigstore/gh-action-sigstore-python@v3.0.0
|
|
77
|
+
with:
|
|
78
|
+
inputs: >-
|
|
79
|
+
./dist/*.tar.gz
|
|
80
|
+
./dist/*.whl
|
|
81
|
+
- name: Create GitHub Release
|
|
82
|
+
env:
|
|
83
|
+
GITHUB_TOKEN: ${{ github.token }}
|
|
84
|
+
run: >-
|
|
85
|
+
gh release create
|
|
86
|
+
"$GITHUB_REF_NAME"
|
|
87
|
+
--repo "$GITHUB_REPOSITORY"
|
|
88
|
+
--notes ""
|
|
89
|
+
- name: Upload artifact signatures to GitHub Release
|
|
90
|
+
env:
|
|
91
|
+
GITHUB_TOKEN: ${{ github.token }}
|
|
92
|
+
# Upload to GitHub Release using the `gh` CLI.
|
|
93
|
+
# `dist/` contains the built packages, and the
|
|
94
|
+
# sigstore-produced signatures and certificates.
|
|
95
|
+
run: >-
|
|
96
|
+
gh release upload
|
|
97
|
+
"$GITHUB_REF_NAME" dist/**
|
|
98
|
+
--repo "$GITHUB_REPOSITORY"
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
name: Tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
pull_request:
|
|
8
|
+
branches:
|
|
9
|
+
- main
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
build:
|
|
13
|
+
|
|
14
|
+
runs-on: ${{ matrix.os }}
|
|
15
|
+
strategy:
|
|
16
|
+
matrix:
|
|
17
|
+
# TODO: support windows-latest
|
|
18
|
+
# TODO: tests are super slow on macos-latest
|
|
19
|
+
os: [ubuntu-latest] #, macos-latest, windows-latest]
|
|
20
|
+
python-version: ["3.10", "3.11", "3.12"]
|
|
21
|
+
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/checkout@v4
|
|
24
|
+
- name: Set up Python
|
|
25
|
+
uses: actions/setup-python@v4
|
|
26
|
+
with:
|
|
27
|
+
python-version: ${{ matrix.python-version }}
|
|
28
|
+
cache: 'pip'
|
|
29
|
+
|
|
30
|
+
- name: Display Python version
|
|
31
|
+
run: python -c "import sys; print(sys.version)"
|
|
32
|
+
|
|
33
|
+
- name: Install dependencies
|
|
34
|
+
run: |
|
|
35
|
+
python -m pip install --upgrade pip
|
|
36
|
+
python -m pip install -e .[tests,arrow]
|
|
37
|
+
|
|
38
|
+
- name: Run tests
|
|
39
|
+
run: python -m pytest --cov=src tests -v
|
|
40
|
+
|
|
41
|
+
- name: Upload coverage report
|
|
42
|
+
run: |
|
|
43
|
+
pip install coveralls[toml]
|
|
44
|
+
coveralls --service=github
|
|
45
|
+
env:
|
|
46
|
+
COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }}
|
|
47
|
+
if: ${{ matrix.python-version == '3.10' && matrix.os == 'ubuntu-latest' }}
|
|
48
|
+
continue-on-error: true
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# Project specific
|
|
2
|
+
notebooks/
|
|
3
|
+
checkpoints/
|
|
4
|
+
data/
|
|
5
|
+
/src/crane/__version__.py
|
|
6
|
+
**/*.lock
|
|
7
|
+
# ignore prototype scripts
|
|
8
|
+
/proto*.py
|
|
9
|
+
/proto*.ipynb
|
|
10
|
+
|
|
11
|
+
# Byte-compiled / optimized / DLL files
|
|
12
|
+
__pycache__/
|
|
13
|
+
*.py[cod]
|
|
14
|
+
*$py.class
|
|
15
|
+
|
|
16
|
+
# C extensions
|
|
17
|
+
*.so
|
|
18
|
+
|
|
19
|
+
# Distribution / packaging
|
|
20
|
+
.Python
|
|
21
|
+
build/
|
|
22
|
+
develop-eggs/
|
|
23
|
+
dist/
|
|
24
|
+
downloads/
|
|
25
|
+
eggs/
|
|
26
|
+
.eggs/
|
|
27
|
+
lib/
|
|
28
|
+
lib64/
|
|
29
|
+
parts/
|
|
30
|
+
sdist/
|
|
31
|
+
var/
|
|
32
|
+
wheels/
|
|
33
|
+
*.egg-info/
|
|
34
|
+
.installed.cfg
|
|
35
|
+
*.egg
|
|
36
|
+
MANIFEST
|
|
37
|
+
|
|
38
|
+
# PyInstaller
|
|
39
|
+
# Usually these files are written by a python script from a template
|
|
40
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
41
|
+
*.manifest
|
|
42
|
+
*.spec
|
|
43
|
+
|
|
44
|
+
# Installer logs
|
|
45
|
+
pip-log.txt
|
|
46
|
+
pip-delete-this-directory.txt
|
|
47
|
+
|
|
48
|
+
# Unit test / coverage reports
|
|
49
|
+
htmlcov/
|
|
50
|
+
.tox/
|
|
51
|
+
.coverage
|
|
52
|
+
.coverage.*
|
|
53
|
+
.cache
|
|
54
|
+
nosetests.xml
|
|
55
|
+
coverage.xml
|
|
56
|
+
coverage_html_report
|
|
57
|
+
*.cover
|
|
58
|
+
.hypothesis/
|
|
59
|
+
.pytest_cache/
|
|
60
|
+
|
|
61
|
+
# Translations
|
|
62
|
+
*.mo
|
|
63
|
+
*.pot
|
|
64
|
+
|
|
65
|
+
# Django stuff:
|
|
66
|
+
*.log
|
|
67
|
+
local_settings.py
|
|
68
|
+
db.sqlite3
|
|
69
|
+
|
|
70
|
+
# Flask stuff:
|
|
71
|
+
instance/
|
|
72
|
+
.webassets-cache
|
|
73
|
+
|
|
74
|
+
# Scrapy stuff:
|
|
75
|
+
.scrapy
|
|
76
|
+
|
|
77
|
+
# Sphinx documentation
|
|
78
|
+
docs/_build/
|
|
79
|
+
|
|
80
|
+
# PyBuilder
|
|
81
|
+
target/
|
|
82
|
+
|
|
83
|
+
# Jupyter Notebook
|
|
84
|
+
.ipynb_checkpoints
|
|
85
|
+
|
|
86
|
+
# pyenv
|
|
87
|
+
.python-version
|
|
88
|
+
|
|
89
|
+
# celery beat schedule file
|
|
90
|
+
celerybeat-schedule
|
|
91
|
+
|
|
92
|
+
# SageMath parsed files
|
|
93
|
+
*.sage.py
|
|
94
|
+
|
|
95
|
+
# Environments
|
|
96
|
+
.env
|
|
97
|
+
.venv
|
|
98
|
+
env/
|
|
99
|
+
venv/
|
|
100
|
+
ENV/
|
|
101
|
+
env.bak/
|
|
102
|
+
venv.bak/
|
|
103
|
+
|
|
104
|
+
# Spyder project settings
|
|
105
|
+
.spyderproject
|
|
106
|
+
.spyproject
|
|
107
|
+
|
|
108
|
+
# Rope project settings
|
|
109
|
+
.ropeproject
|
|
110
|
+
|
|
111
|
+
# mkdocs documentation
|
|
112
|
+
/site
|
|
113
|
+
|
|
114
|
+
# mypy
|
|
115
|
+
.mypy_cache/
|
|
116
|
+
|
|
117
|
+
.idea/
|
|
118
|
+
|
|
119
|
+
# Vscode
|
|
120
|
+
.vscode/
|
|
121
|
+
.history/
|
|
122
|
+
|
|
123
|
+
# Created by https://www.toptal.com/developers/gitignore/api/vim
|
|
124
|
+
# Edit at https://www.toptal.com/developers/gitignore?templates=vim
|
|
125
|
+
|
|
126
|
+
### Vim ###
|
|
127
|
+
# Swap
|
|
128
|
+
[._]*.s[a-v][a-z]
|
|
129
|
+
!*.svg # comment out if you don't need vector files
|
|
130
|
+
[._]*.sw[a-p]
|
|
131
|
+
[._]s[a-rt-v][a-z]
|
|
132
|
+
[._]ss[a-gi-z]
|
|
133
|
+
[._]sw[a-p]
|
|
134
|
+
|
|
135
|
+
# Session
|
|
136
|
+
Session.vim
|
|
137
|
+
Sessionx.vim
|
|
138
|
+
|
|
139
|
+
# Temporary
|
|
140
|
+
.netrwhist
|
|
141
|
+
*~
|
|
142
|
+
# Auto-generated tag files
|
|
143
|
+
tags
|
|
144
|
+
# Persistent undo
|
|
145
|
+
[._]*.un~
|
|
146
|
+
|
|
147
|
+
# End of https://www.toptal.com/developers/gitignore/api/vim
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
default_install_hook_types:
|
|
2
|
+
- pre-commit
|
|
3
|
+
repos:
|
|
4
|
+
- repo: https://github.com/pycqa/isort
|
|
5
|
+
rev: 5.11.5
|
|
6
|
+
hooks:
|
|
7
|
+
- id: isort
|
|
8
|
+
stages: [pre-commit]
|
|
9
|
+
- repo: https://github.com/psf/black-pre-commit-mirror
|
|
10
|
+
rev: 23.9.1
|
|
11
|
+
hooks:
|
|
12
|
+
- id: black
|
|
13
|
+
language_version: python3.11
|
|
14
|
+
stages: [pre-commit]
|
|
15
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
16
|
+
rev: v0.0.278
|
|
17
|
+
hooks:
|
|
18
|
+
- id: ruff
|
|
19
|
+
args: [--fix, --exit-non-zero-on-fix]
|
|
20
|
+
stages: [pre-commit]
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: hyped-crane
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Lift (process) and place (write) data streams, seamlessly and in parallel.
|
|
5
|
+
Author: open-hyped
|
|
6
|
+
License: Apache 2.0
|
|
7
|
+
Classifier: License :: Freely Distributable
|
|
8
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
12
|
+
Requires-Python: >=3.10
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
Requires-Dist: dill>=0.3.8
|
|
15
|
+
Requires-Dist: orjson>=3.10.1
|
|
16
|
+
Requires-Dist: datasets>=3.2.0
|
|
17
|
+
Requires-Dist: fsspec<=2023.9.2
|
|
18
|
+
Provides-Extra: arrow
|
|
19
|
+
Requires-Dist: pyarrow>=17.0.0; extra == "arrow"
|
|
20
|
+
Provides-Extra: linting
|
|
21
|
+
Requires-Dist: pre-commit; extra == "linting"
|
|
22
|
+
Provides-Extra: tests
|
|
23
|
+
Requires-Dist: pytest; extra == "tests"
|
|
24
|
+
Requires-Dist: pytest-cov; extra == "tests"
|
|
25
|
+
Requires-Dist: pytest-asyncio; extra == "tests"
|
|
26
|
+
Requires-Dist: pytest-integration; extra == "tests"
|
|
27
|
+
Provides-Extra: docs
|
|
28
|
+
Requires-Dist: sphinx; extra == "docs"
|
|
29
|
+
Requires-Dist: furo; extra == "docs"
|
|
30
|
+
|
|
31
|
+
# Hyped Crane
|
|
32
|
+
|
|
33
|
+
[](https://github.com/open-hyped/crane/actions/workflows/tests.yml)
|
|
34
|
+
[](https://github.com/open-hyped/crane/actions/workflows/linting.yml)
|
|
35
|
+
[](https://coveralls.io/github/open-hyped/crane?branch=main)
|
|
36
|
+
[](https://pypi.org/project/hyped-crane)
|
|
37
|
+
[](https://pypi.org/project/hyped-crane/)
|
|
38
|
+
|
|
39
|
+
Lift (process) and place (write) data streams, seamlessly and in parallel.
|
|
40
|
+
|
|
41
|
+
Hyped Crane is a Python library designed to simplify working with HuggingFace `datasets`' iterable datasets. It provides powerful tools for applying transformations to data streams, handling parallel processing, and writing data in varios formats.
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
## Features
|
|
45
|
+
|
|
46
|
+
- **Streaming-Friendly Transformations**: Apply lazy, streaming-friendly transformations to iterable datasets without preloading data into memory.
|
|
47
|
+
- **Seamless Multiprocessing**: Effortlessly process and write datasets using multiple processes, improving performance on large datasets.
|
|
48
|
+
- **Easily Extendable**: Provides a straightforward interface to implement support for custom data formats.
|
|
49
|
+
- **Interoperability with Hugging Face Datasets**: Write datasets in formats directly loadable using HuggingFace’s `load_from_disk` function.
|
|
50
|
+
|
|
51
|
+
## Installation
|
|
52
|
+
|
|
53
|
+
To install the library from **PyPI**, run:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
pip install hyped-crane
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
To install the library **from source**, clone run:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
git clone https://github.com/open-hyped/crane.git
|
|
63
|
+
cd crane
|
|
64
|
+
pip install .
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Getting Started
|
|
68
|
+
|
|
69
|
+
Here’s a quick example to illustrate how Hyped Crane works
|
|
70
|
+
|
|
71
|
+
### Step 1: "Load" the Dataset
|
|
72
|
+
|
|
73
|
+
`crane` is designed to work seamlessly with HuggingFace’s iterable datasets. Let’s start by creating one:
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
import datasets
|
|
77
|
+
|
|
78
|
+
# Create a dummy iterable dataset
|
|
79
|
+
dummy_data = [
|
|
80
|
+
{"a": 0, "b": [1, 2, 3, 4]},
|
|
81
|
+
{"a": 1, "b": [5, 6]},
|
|
82
|
+
{"a": 1, "b": [7, 8, 9, 10]}
|
|
83
|
+
]
|
|
84
|
+
ds = datasets.Dataset.from_list(dummy_data)
|
|
85
|
+
ds = ds.to_iterable_dataset()
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Step 2: Apply a Lazy Transformation
|
|
89
|
+
|
|
90
|
+
Transformations on iterable datasets are applied lazily. That means the data isn’t processed until it’s actually read:
|
|
91
|
+
|
|
92
|
+
```python
|
|
93
|
+
# Apply a transformation to compute the maximum of list "b"
|
|
94
|
+
ds = ds.map(lambda x: {"max(b)": max(x["b"])})
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Step 3: Write the Dataset to Disk
|
|
98
|
+
|
|
99
|
+
Use `crane`’s `ArrowDatasetWriter` to save the transformed dataset to disk. You can enable multiprocessing to speed up the transformation and writing processes:
|
|
100
|
+
|
|
101
|
+
```python
|
|
102
|
+
from crane import ArrowDatasetWriter
|
|
103
|
+
|
|
104
|
+
# Write the transformed dataset to disk with multiprocessing
|
|
105
|
+
writer = ArrowDatasetWriter("data", overwrite=True, num_proc=3)
|
|
106
|
+
writer.write(ds)
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
**Key Benefits**:
|
|
110
|
+
- **Data-Parallel Transformations**: The transformations defined by `map` operations are moved into the workers, allowing transformation workload to be evenly distributed.
|
|
111
|
+
- **Efficient Writing**: Each worker writes its own shard to disk in parallel, reducing bottlenecks in **I/O operations**.
|
|
112
|
+
|
|
113
|
+
`crane` handles worker communication, task distribution, and writing operations, so you can focus on defining your transformation logic without worrying about parallelization details.
|
|
114
|
+
|
|
115
|
+
**Note**: Datasets saved with the `ArrowDatasetWriter` are fully compatible with HuggingFace’s `load_from_disk` function. You can reload the dataset and continue working with it:
|
|
116
|
+
|
|
117
|
+
```python
|
|
118
|
+
# Reload the dataset from disk
|
|
119
|
+
ds = datasets.load_from_disk("data")
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
## Contributions
|
|
124
|
+
|
|
125
|
+
Contributions are welcome! Feel free to submit a pull request or open an issue to discuss your ideas.
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# Hyped Crane
|
|
2
|
+
|
|
3
|
+
[](https://github.com/open-hyped/crane/actions/workflows/tests.yml)
|
|
4
|
+
[](https://github.com/open-hyped/crane/actions/workflows/linting.yml)
|
|
5
|
+
[](https://coveralls.io/github/open-hyped/crane?branch=main)
|
|
6
|
+
[](https://pypi.org/project/hyped-crane)
|
|
7
|
+
[](https://pypi.org/project/hyped-crane/)
|
|
8
|
+
|
|
9
|
+
Lift (process) and place (write) data streams, seamlessly and in parallel.
|
|
10
|
+
|
|
11
|
+
Hyped Crane is a Python library designed to simplify working with HuggingFace `datasets`' iterable datasets. It provides powerful tools for applying transformations to data streams, handling parallel processing, and writing data in varios formats.
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
## Features
|
|
15
|
+
|
|
16
|
+
- **Streaming-Friendly Transformations**: Apply lazy, streaming-friendly transformations to iterable datasets without preloading data into memory.
|
|
17
|
+
- **Seamless Multiprocessing**: Effortlessly process and write datasets using multiple processes, improving performance on large datasets.
|
|
18
|
+
- **Easily Extendable**: Provides a straightforward interface to implement support for custom data formats.
|
|
19
|
+
- **Interoperability with Hugging Face Datasets**: Write datasets in formats directly loadable using HuggingFace’s `load_from_disk` function.
|
|
20
|
+
|
|
21
|
+
## Installation
|
|
22
|
+
|
|
23
|
+
To install the library from **PyPI**, run:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
pip install hyped-crane
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
To install the library **from source**, clone run:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
git clone https://github.com/open-hyped/crane.git
|
|
33
|
+
cd crane
|
|
34
|
+
pip install .
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Getting Started
|
|
38
|
+
|
|
39
|
+
Here’s a quick example to illustrate how Hyped Crane works
|
|
40
|
+
|
|
41
|
+
### Step 1: "Load" the Dataset
|
|
42
|
+
|
|
43
|
+
`crane` is designed to work seamlessly with HuggingFace’s iterable datasets. Let’s start by creating one:
|
|
44
|
+
|
|
45
|
+
```python
|
|
46
|
+
import datasets
|
|
47
|
+
|
|
48
|
+
# Create a dummy iterable dataset
|
|
49
|
+
dummy_data = [
|
|
50
|
+
{"a": 0, "b": [1, 2, 3, 4]},
|
|
51
|
+
{"a": 1, "b": [5, 6]},
|
|
52
|
+
{"a": 1, "b": [7, 8, 9, 10]}
|
|
53
|
+
]
|
|
54
|
+
ds = datasets.Dataset.from_list(dummy_data)
|
|
55
|
+
ds = ds.to_iterable_dataset()
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Step 2: Apply a Lazy Transformation
|
|
59
|
+
|
|
60
|
+
Transformations on iterable datasets are applied lazily. That means the data isn’t processed until it’s actually read:
|
|
61
|
+
|
|
62
|
+
```python
|
|
63
|
+
# Apply a transformation to compute the maximum of list "b"
|
|
64
|
+
ds = ds.map(lambda x: {"max(b)": max(x["b"])})
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Step 3: Write the Dataset to Disk
|
|
68
|
+
|
|
69
|
+
Use `crane`’s `ArrowDatasetWriter` to save the transformed dataset to disk. You can enable multiprocessing to speed up the transformation and writing processes:
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
from crane import ArrowDatasetWriter
|
|
73
|
+
|
|
74
|
+
# Write the transformed dataset to disk with multiprocessing
|
|
75
|
+
writer = ArrowDatasetWriter("data", overwrite=True, num_proc=3)
|
|
76
|
+
writer.write(ds)
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
**Key Benefits**:
|
|
80
|
+
- **Data-Parallel Transformations**: The transformations defined by `map` operations are moved into the workers, allowing transformation workload to be evenly distributed.
|
|
81
|
+
- **Efficient Writing**: Each worker writes its own shard to disk in parallel, reducing bottlenecks in **I/O operations**.
|
|
82
|
+
|
|
83
|
+
`crane` handles worker communication, task distribution, and writing operations, so you can focus on defining your transformation logic without worrying about parallelization details.
|
|
84
|
+
|
|
85
|
+
**Note**: Datasets saved with the `ArrowDatasetWriter` are fully compatible with HuggingFace’s `load_from_disk` function. You can reload the dataset and continue working with it:
|
|
86
|
+
|
|
87
|
+
```python
|
|
88
|
+
# Reload the dataset from disk
|
|
89
|
+
ds = datasets.load_from_disk("data")
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
## Contributions
|
|
94
|
+
|
|
95
|
+
Contributions are welcome! Feel free to submit a pull request or open an issue to discuss your ideas.
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "hyped-crane"
|
|
3
|
+
dynamic = ["version"]
|
|
4
|
+
description = "Lift (process) and place (write) data streams, seamlessly and in parallel."
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
classifiers = [
|
|
7
|
+
"License :: Freely Distributable",
|
|
8
|
+
"License :: OSI Approved :: Apache Software License",
|
|
9
|
+
"Programming Language :: Python :: 3.10",
|
|
10
|
+
"Programming Language :: Python :: 3.11",
|
|
11
|
+
"Programming Language :: Python :: 3.12",
|
|
12
|
+
]
|
|
13
|
+
authors = [
|
|
14
|
+
{name = "open-hyped"},
|
|
15
|
+
]
|
|
16
|
+
requires-python = ">=3.10"
|
|
17
|
+
license = {text = "Apache 2.0"}
|
|
18
|
+
dependencies = [
|
|
19
|
+
"dill>=0.3.8",
|
|
20
|
+
"orjson>=3.10.1",
|
|
21
|
+
"datasets>=3.2.0",
|
|
22
|
+
"fsspec<=2023.9.2",
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
[project.optional-dependencies]
|
|
26
|
+
arrow = ["pyarrow>=17.0.0"]
|
|
27
|
+
linting = ["pre-commit"]
|
|
28
|
+
tests = [
|
|
29
|
+
"pytest",
|
|
30
|
+
"pytest-cov",
|
|
31
|
+
"pytest-asyncio",
|
|
32
|
+
"pytest-integration",
|
|
33
|
+
]
|
|
34
|
+
docs = ["sphinx", "furo"]
|
|
35
|
+
|
|
36
|
+
[build-system]
|
|
37
|
+
requires = ["setuptools >= 61.0.0", "setuptools_scm>=8.0.0"]
|
|
38
|
+
build-backend = "setuptools.build_meta"
|
|
39
|
+
|
|
40
|
+
[tool.coverage.run]
|
|
41
|
+
concurrency = ["multiprocessing","thread"]
|
|
42
|
+
parallel = true
|
|
43
|
+
sigterm = true
|
|
44
|
+
data_file = "/tmp/.coverage"
|
|
45
|
+
|
|
46
|
+
[tool.coverage.report]
|
|
47
|
+
ignore_errors = true
|
|
48
|
+
omit = ["tests/*", "src/crane/__version__.py"]
|
|
49
|
+
# Regexes for lines to exclude from consideration
|
|
50
|
+
exclude_also = [
|
|
51
|
+
# Don't complain about missing debug-only code:
|
|
52
|
+
"def __repr__",
|
|
53
|
+
"if self\\.debug",
|
|
54
|
+
|
|
55
|
+
# Don't complain if tests don't hit defensive assertion code:
|
|
56
|
+
"raise AssertionError",
|
|
57
|
+
"raise NotImplementedError",
|
|
58
|
+
|
|
59
|
+
# Don't complain if non-runnable code isn't run:
|
|
60
|
+
"if 0:",
|
|
61
|
+
"if __name__ == .__main__.:",
|
|
62
|
+
|
|
63
|
+
# Don't complain about abstract methods, they aren't run:
|
|
64
|
+
"@(abc\\.)?abstractmethod",
|
|
65
|
+
|
|
66
|
+
# Don't complain about overloaded functions
|
|
67
|
+
"@(typing\\.)?overload",
|
|
68
|
+
"pragma: not covered"
|
|
69
|
+
]
|
|
70
|
+
|
|
71
|
+
[tool.setuptools_scm]
|
|
72
|
+
version_file = "src/crane/__version__.py"
|
|
73
|
+
|
|
74
|
+
[tool.black]
|
|
75
|
+
target-version = ["py310"]
|
|
76
|
+
line-length = 100
|
|
77
|
+
docstring-style = "google"
|
|
78
|
+
|
|
79
|
+
[tool.isort]
|
|
80
|
+
profile = "black"
|
|
81
|
+
line_length = 100
|
|
82
|
+
skip = ["docs/source/conf.py"]
|
|
83
|
+
|
|
84
|
+
[tool.ruff]
|
|
85
|
+
line-length = 100
|
|
86
|
+
ignore = ["E741", "B028", "B006", "B008", "B023"]
|
|
87
|
+
select = ["D", "E", "F", "W", "N", "B", "T"]
|
|
88
|
+
|
|
89
|
+
[tool.ruff.pydocstyle]
|
|
90
|
+
convention = "google"
|
|
91
|
+
|
|
92
|
+
[tool.ruff.per-file-ignores]
|
|
93
|
+
# Don't check docstrings of `tests` and `docs`
|
|
94
|
+
#"tests/**" = ["D"]
|
|
95
|
+
"docs/**" = ["D"]
|
|
96
|
+
"tests/**" = ["D", "E", "F", "W", "N", "B", "T"] # TODO: temporary
|