ray-pixi 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.
@@ -0,0 +1,36 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ concurrency:
9
+ group: ${{ github.workflow }}-${{ github.ref }}
10
+ cancel-in-progress: true
11
+
12
+ jobs:
13
+ lint:
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - uses: actions/checkout@v5
17
+ with:
18
+ fetch-depth: 0 # full history + tags so hatch-vcs can resolve the version
19
+
20
+ - name: Install uv
21
+ uses: astral-sh/setup-uv@v6
22
+ with:
23
+ python-version: "3.13"
24
+ enable-cache: true
25
+
26
+ - name: Install dependencies
27
+ run: uv sync --locked
28
+
29
+ - name: Ruff lint
30
+ run: uv run ruff check --output-format=github .
31
+
32
+ - name: Ruff format check
33
+ run: uv run ruff format --check .
34
+
35
+ - name: Type check (ty)
36
+ run: uv run ty check
@@ -0,0 +1,80 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags: ["v*"]
6
+
7
+ jobs:
8
+ build:
9
+ runs-on: ubuntu-latest
10
+ steps:
11
+ - uses: actions/checkout@v5
12
+ with:
13
+ fetch-depth: 0 # full history + tags so hatch-vcs resolves the version
14
+
15
+ - name: Install uv
16
+ uses: astral-sh/setup-uv@v6
17
+ with:
18
+ python-version: "3.13"
19
+ enable-cache: true
20
+
21
+ - name: Install dependencies
22
+ run: uv sync --locked
23
+
24
+ - name: Lint, format, type check
25
+ run: |
26
+ uv run ruff check .
27
+ uv run ruff format --check .
28
+ uv run ty check
29
+
30
+ - name: Test
31
+ run: uv run pytest
32
+
33
+ - name: Build sdist and wheel
34
+ run: uv build
35
+
36
+ - name: Upload dist artifact
37
+ uses: actions/upload-artifact@v4
38
+ with:
39
+ name: dist
40
+ path: dist/
41
+
42
+ pypi-publish:
43
+ needs: build
44
+ runs-on: ubuntu-latest
45
+ environment:
46
+ name: pypi
47
+ url: https://pypi.org/p/ray-pixi
48
+ permissions:
49
+ id-token: write # OIDC token for PyPI Trusted Publishing
50
+ steps:
51
+ - name: Download dist artifact
52
+ uses: actions/download-artifact@v4
53
+ with:
54
+ name: dist
55
+ path: dist/
56
+
57
+ - name: Publish to PyPI
58
+ uses: pypa/gh-action-pypi-publish@release/v1
59
+
60
+ github-release:
61
+ needs: build
62
+ runs-on: ubuntu-latest
63
+ permissions:
64
+ contents: write # create the release and upload assets
65
+ steps:
66
+ - name: Download dist artifact
67
+ uses: actions/download-artifact@v4
68
+ with:
69
+ name: dist
70
+ path: dist/
71
+
72
+ - name: Create GitHub Release
73
+ env:
74
+ GH_TOKEN: ${{ github.token }}
75
+ run: >
76
+ gh release create "${{ github.ref_name }}"
77
+ dist/*
78
+ --repo "${{ github.repository }}"
79
+ --title "${{ github.ref_name }}"
80
+ --generate-notes
@@ -0,0 +1,221 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[codz]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # PyInstaller
30
+ # Usually these files are written by a python script from a template
31
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
32
+ *.manifest
33
+ *.spec
34
+
35
+ # Installer logs
36
+ pip-log.txt
37
+ pip-delete-this-directory.txt
38
+
39
+ # Unit test / coverage reports
40
+ htmlcov/
41
+ .tox/
42
+ .nox/
43
+ .coverage
44
+ .coverage.*
45
+ .cache
46
+ nosetests.xml
47
+ coverage.xml
48
+ *.cover
49
+ *.py.cover
50
+ .hypothesis/
51
+ .pytest_cache/
52
+ cover/
53
+
54
+ # Translations
55
+ *.mo
56
+ *.pot
57
+
58
+ # Django stuff:
59
+ *.log
60
+ local_settings.py
61
+ db.sqlite3
62
+ db.sqlite3-journal
63
+
64
+ # Flask stuff:
65
+ instance/
66
+ .webassets-cache
67
+
68
+ # Scrapy stuff:
69
+ .scrapy
70
+
71
+ # Sphinx documentation
72
+ docs/_build/
73
+
74
+ # PyBuilder
75
+ .pybuilder/
76
+ target/
77
+
78
+ # Jupyter Notebook
79
+ .ipynb_checkpoints
80
+
81
+ # IPython
82
+ profile_default/
83
+ ipython_config.py
84
+
85
+ # pyenv
86
+ # For a library or package, you might want to ignore these files since the code is
87
+ # intended to run in multiple environments; otherwise, check them in:
88
+ # .python-version
89
+
90
+ # pipenv
91
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
92
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
93
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
94
+ # install all needed dependencies.
95
+ # Pipfile.lock
96
+
97
+ # UV
98
+ # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
99
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
100
+ # commonly ignored for libraries.
101
+ # uv.lock
102
+
103
+ # poetry
104
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
105
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
106
+ # commonly ignored for libraries.
107
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
108
+ # poetry.lock
109
+ # poetry.toml
110
+
111
+ # pdm
112
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
113
+ # pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
114
+ # https://pdm-project.org/en/latest/usage/project/#working-with-version-control
115
+ # pdm.lock
116
+ # pdm.toml
117
+ .pdm-python
118
+ .pdm-build/
119
+
120
+ # pixi
121
+ # Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
122
+ # pixi.lock
123
+ # Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
124
+ # in the .venv directory. It is recommended not to include this directory in version control.
125
+ .pixi
126
+
127
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
128
+ __pypackages__/
129
+
130
+ # Celery stuff
131
+ celerybeat-schedule
132
+ celerybeat.pid
133
+
134
+ # Redis
135
+ *.rdb
136
+ *.aof
137
+ *.pid
138
+
139
+ # RabbitMQ
140
+ mnesia/
141
+ rabbitmq/
142
+ rabbitmq-data/
143
+
144
+ # ActiveMQ
145
+ activemq-data/
146
+
147
+ # SageMath parsed files
148
+ *.sage.py
149
+
150
+ # Environments
151
+ .env
152
+ .envrc
153
+ .venv
154
+ env/
155
+ venv/
156
+ ENV/
157
+ env.bak/
158
+ venv.bak/
159
+
160
+ # Spyder project settings
161
+ .spyderproject
162
+ .spyproject
163
+
164
+ # Rope project settings
165
+ .ropeproject
166
+
167
+ # mkdocs documentation
168
+ /site
169
+
170
+ # mypy
171
+ .mypy_cache/
172
+ .dmypy.json
173
+ dmypy.json
174
+
175
+ # Pyre type checker
176
+ .pyre/
177
+
178
+ # pytype static type analyzer
179
+ .pytype/
180
+
181
+ # Cython debug symbols
182
+ cython_debug/
183
+
184
+ # PyCharm
185
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
186
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
187
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
188
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
189
+ # .idea/
190
+
191
+ # Abstra
192
+ # Abstra is an AI-powered process automation framework.
193
+ # Ignore directories containing user credentials, local state, and settings.
194
+ # Learn more at https://abstra.io/docs
195
+ .abstra/
196
+
197
+ # Visual Studio Code
198
+ # Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
199
+ # that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
200
+ # and can be added to the global gitignore or merged into this file. However, if you prefer,
201
+ # you could uncomment the following to ignore the entire vscode folder
202
+ .vscode/
203
+ # Temporary file for partial code execution
204
+ tempCodeRunnerFile.py
205
+
206
+ # Ruff stuff:
207
+ .ruff_cache/
208
+
209
+ # PyPI configuration file
210
+ .pypirc
211
+
212
+ # Marimo
213
+ marimo/_static/
214
+ marimo/_lsp/
215
+ __marimo__/
216
+
217
+ # Streamlit
218
+ .streamlit/secrets.toml
219
+
220
+ # superpowers (brainstorming specs / plans — kept local only)
221
+ docs/superpowers/
@@ -0,0 +1 @@
1
+ 3.13
ray_pixi-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 ZhengYu, Xu
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,132 @@
1
+ Metadata-Version: 2.4
2
+ Name: ray-pixi
3
+ Version: 0.1.0
4
+ Summary: Add your description here
5
+ Author-email: ZhengYu Xu <zen-xu@outlook.com>
6
+ License-File: LICENSE
7
+ Requires-Python: >=3.13
8
+ Requires-Dist: pydantic>=2
9
+ Requires-Dist: ray>=2.50
10
+ Requires-Dist: tomli-w>=1.0
11
+ Description-Content-Type: text/markdown
12
+
13
+ # ray-pixi
14
+
15
+ A [pixi](https://pixi.sh) `runtime_env` for [Ray](https://ray.io): declare a pixi
16
+ environment in your `runtime_env`, and Ray installs it on each node and launches
17
+ the workers inside it via `pixi run`.
18
+
19
+ ## Install
20
+
21
+ ```bash
22
+ pip install ray-pixi # or: pixi add --pypi ray-pixi
23
+ ```
24
+
25
+ ## Plugin registration
26
+
27
+ Ray discovers runtime_env plugins through the `RAY_RUNTIME_ENV_PLUGINS`
28
+ environment variable, which **must be set before the runtime_env agent starts** —
29
+ that is, before `ray start` on every node (and before `ray.init()` for a local
30
+ cluster):
31
+
32
+ ```bash
33
+ export RAY_RUNTIME_ENV_PLUGINS='[{"class":"ray_pixi.PixiPlugin"}]'
34
+ ray start --head # or: ray start --address=...
35
+ ```
36
+
37
+ On KubeRay / a cluster YAML, set the same value in each node's container env.
38
+ ray-pixi must also be installed in the agent's Python environment on every node
39
+ (so it can import `ray_pixi.PixiPlugin`).
40
+
41
+ ## Usage
42
+
43
+ Once the variable is set, declare the environment with `pixi()`:
44
+
45
+ ```python
46
+ import ray
47
+
48
+ from ray_pixi import pixi
49
+
50
+ ray.init(runtime_env={"pixi": pixi("pixi.toml", environment="default", locked=True)})
51
+
52
+
53
+ @ray.remote
54
+ def task():
55
+ import numpy
56
+
57
+ return numpy.__version__
58
+
59
+
60
+ print(ray.get(task.remote()))
61
+ ```
62
+
63
+ You can also declare the environment inline, without a manifest file:
64
+
65
+ ```python
66
+ ray.init(
67
+ runtime_env={
68
+ "pixi": pixi(
69
+ channels=["conda-forge"],
70
+ dependencies={"python": "3.13.*", "numpy": "*"},
71
+ )
72
+ }
73
+ )
74
+ ```
75
+
76
+ ## The `pixi` field
77
+
78
+ `runtime_env["pixi"]` accepts a `str` (a manifest path) or a `dict`:
79
+
80
+ | key | description |
81
+ | --- | --- |
82
+ | `manifest` | path to a `pixi.toml` / `pyproject.toml` (mutually exclusive with the inline keys) |
83
+ | `channels` / `dependencies` / `pypi_dependencies` / `platforms` | inline spec |
84
+ | `environment` | environment to select, defaults to `default` |
85
+ | `locked` | reproduce strictly from `pixi.lock`, defaults to `False` |
86
+ | `pixi_version` | if set, bootstrap this pixi version on the node |
87
+ | `pixi_install_options` | extra flags passed through to `pixi install` |
88
+
89
+ Prefer building the field with `ray_pixi.pixi()`: given a manifest path it reads
90
+ the file (and a sibling `pixi.lock`) on the driver and inlines the content, so the
91
+ configuration is self-contained across nodes.
92
+
93
+ > **Requirements:** every node needs a `pixi` executable (on `PATH`, or bootstrapped
94
+ > via `pixi_version`), and the pixi environment must provide a `python` and `ray`
95
+ > that match the cluster (see *Version matching* below).
96
+
97
+ ## Version matching
98
+
99
+ Ray refuses to connect a worker whose `ray` or `python` version differs from the
100
+ cluster. Concretely:
101
+
102
+ - **Ray version** is always compared exactly — declare the cluster's exact version.
103
+ - **Python version** is compared at the level set by the cluster's
104
+ `RAY_DEFAULT_PYTHON_VERSION_MATCH_LEVEL` environment variable:
105
+ - `patch` (Ray's default) — must match down to the micro version
106
+ (`3.13.12` ≠ `3.13.13`), or Ray errors.
107
+ - `minor` — only `major.minor` must match; a micro difference just warns. Set
108
+ `RAY_DEFAULT_PYTHON_VERSION_MATCH_LEVEL=minor` on the cluster to allow this.
109
+
110
+ How ray-pixi helps:
111
+
112
+ - **Inline mode:** if you omit `python` from `dependencies` it is pinned to the
113
+ node's exact running version, and if you omit `ray` from `pypi_dependencies` it is
114
+ added as `ray[default]==<cluster ray version>`, so workers match by default.
115
+ - **Manifest mode:** ray-pixi does **not** edit your manifest, so it must declare
116
+ both `python` and `ray` itself (ray as a pypi dependency). A manifest that installs
117
+ neither is rejected after install with a clear error.
118
+ - **Both modes:** after installing, ray-pixi verifies the env's python *minor* and
119
+ *ray* version against the cluster and fails fast (with a clear error) on a
120
+ mismatch. The python check is minor-level only, so under the default `patch` level
121
+ still pin `python` to the cluster's exact version (e.g. `python = "==3.13.12"` in
122
+ your manifest), or relax the cluster to `minor`.
123
+
124
+ ## Known interactions
125
+
126
+ - **Launching the driver with `uv run`:** Ray's built-in uv integration
127
+ (`RAY_ENABLE_UV_RUN_RUNTIME_ENV`, on by default) detects the `uv run` ancestor and
128
+ tries to rewrite `py_executable` to replicate the uv environment, which conflicts
129
+ with the pixi plugin. Disable it when using pixi:
130
+ `RAY_ENABLE_UV_RUN_RUNTIME_ENV=0`.
131
+ - **`platforms`:** when you declare an inline spec without `platforms`, ray-pixi
132
+ defaults it to the building node's platform (e.g. `linux-64`).
@@ -0,0 +1,120 @@
1
+ # ray-pixi
2
+
3
+ A [pixi](https://pixi.sh) `runtime_env` for [Ray](https://ray.io): declare a pixi
4
+ environment in your `runtime_env`, and Ray installs it on each node and launches
5
+ the workers inside it via `pixi run`.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ pip install ray-pixi # or: pixi add --pypi ray-pixi
11
+ ```
12
+
13
+ ## Plugin registration
14
+
15
+ Ray discovers runtime_env plugins through the `RAY_RUNTIME_ENV_PLUGINS`
16
+ environment variable, which **must be set before the runtime_env agent starts** —
17
+ that is, before `ray start` on every node (and before `ray.init()` for a local
18
+ cluster):
19
+
20
+ ```bash
21
+ export RAY_RUNTIME_ENV_PLUGINS='[{"class":"ray_pixi.PixiPlugin"}]'
22
+ ray start --head # or: ray start --address=...
23
+ ```
24
+
25
+ On KubeRay / a cluster YAML, set the same value in each node's container env.
26
+ ray-pixi must also be installed in the agent's Python environment on every node
27
+ (so it can import `ray_pixi.PixiPlugin`).
28
+
29
+ ## Usage
30
+
31
+ Once the variable is set, declare the environment with `pixi()`:
32
+
33
+ ```python
34
+ import ray
35
+
36
+ from ray_pixi import pixi
37
+
38
+ ray.init(runtime_env={"pixi": pixi("pixi.toml", environment="default", locked=True)})
39
+
40
+
41
+ @ray.remote
42
+ def task():
43
+ import numpy
44
+
45
+ return numpy.__version__
46
+
47
+
48
+ print(ray.get(task.remote()))
49
+ ```
50
+
51
+ You can also declare the environment inline, without a manifest file:
52
+
53
+ ```python
54
+ ray.init(
55
+ runtime_env={
56
+ "pixi": pixi(
57
+ channels=["conda-forge"],
58
+ dependencies={"python": "3.13.*", "numpy": "*"},
59
+ )
60
+ }
61
+ )
62
+ ```
63
+
64
+ ## The `pixi` field
65
+
66
+ `runtime_env["pixi"]` accepts a `str` (a manifest path) or a `dict`:
67
+
68
+ | key | description |
69
+ | --- | --- |
70
+ | `manifest` | path to a `pixi.toml` / `pyproject.toml` (mutually exclusive with the inline keys) |
71
+ | `channels` / `dependencies` / `pypi_dependencies` / `platforms` | inline spec |
72
+ | `environment` | environment to select, defaults to `default` |
73
+ | `locked` | reproduce strictly from `pixi.lock`, defaults to `False` |
74
+ | `pixi_version` | if set, bootstrap this pixi version on the node |
75
+ | `pixi_install_options` | extra flags passed through to `pixi install` |
76
+
77
+ Prefer building the field with `ray_pixi.pixi()`: given a manifest path it reads
78
+ the file (and a sibling `pixi.lock`) on the driver and inlines the content, so the
79
+ configuration is self-contained across nodes.
80
+
81
+ > **Requirements:** every node needs a `pixi` executable (on `PATH`, or bootstrapped
82
+ > via `pixi_version`), and the pixi environment must provide a `python` and `ray`
83
+ > that match the cluster (see *Version matching* below).
84
+
85
+ ## Version matching
86
+
87
+ Ray refuses to connect a worker whose `ray` or `python` version differs from the
88
+ cluster. Concretely:
89
+
90
+ - **Ray version** is always compared exactly — declare the cluster's exact version.
91
+ - **Python version** is compared at the level set by the cluster's
92
+ `RAY_DEFAULT_PYTHON_VERSION_MATCH_LEVEL` environment variable:
93
+ - `patch` (Ray's default) — must match down to the micro version
94
+ (`3.13.12` ≠ `3.13.13`), or Ray errors.
95
+ - `minor` — only `major.minor` must match; a micro difference just warns. Set
96
+ `RAY_DEFAULT_PYTHON_VERSION_MATCH_LEVEL=minor` on the cluster to allow this.
97
+
98
+ How ray-pixi helps:
99
+
100
+ - **Inline mode:** if you omit `python` from `dependencies` it is pinned to the
101
+ node's exact running version, and if you omit `ray` from `pypi_dependencies` it is
102
+ added as `ray[default]==<cluster ray version>`, so workers match by default.
103
+ - **Manifest mode:** ray-pixi does **not** edit your manifest, so it must declare
104
+ both `python` and `ray` itself (ray as a pypi dependency). A manifest that installs
105
+ neither is rejected after install with a clear error.
106
+ - **Both modes:** after installing, ray-pixi verifies the env's python *minor* and
107
+ *ray* version against the cluster and fails fast (with a clear error) on a
108
+ mismatch. The python check is minor-level only, so under the default `patch` level
109
+ still pin `python` to the cluster's exact version (e.g. `python = "==3.13.12"` in
110
+ your manifest), or relax the cluster to `minor`.
111
+
112
+ ## Known interactions
113
+
114
+ - **Launching the driver with `uv run`:** Ray's built-in uv integration
115
+ (`RAY_ENABLE_UV_RUN_RUNTIME_ENV`, on by default) detects the `uv run` ancestor and
116
+ tries to rewrite `py_executable` to replicate the uv environment, which conflicts
117
+ with the pixi plugin. Disable it when using pixi:
118
+ `RAY_ENABLE_UV_RUN_RUNTIME_ENV=0`.
119
+ - **`platforms`:** when you declare an inline spec without `platforms`, ray-pixi
120
+ defaults it to the building node's platform (e.g. `linux-64`).
@@ -0,0 +1,58 @@
1
+ [project]
2
+ name = "ray-pixi"
3
+ dynamic = ["version"]
4
+ description = "Add your description here"
5
+ readme = "README.md"
6
+ authors = [
7
+ { name = "ZhengYu Xu", email = "zen-xu@outlook.com" },
8
+ ]
9
+ requires-python = ">=3.13"
10
+ dependencies = ["ray>=2.50", "tomli-w>=1.0", "pydantic>=2"]
11
+
12
+ [build-system]
13
+ requires = ["hatchling", "hatch-vcs"]
14
+ build-backend = "hatchling.build"
15
+
16
+ [tool.hatch.version]
17
+ source = "vcs"
18
+
19
+ [tool.hatch.build.targets.wheel]
20
+ packages = ["src/ray_pixi"]
21
+
22
+ [dependency-groups]
23
+ dev = [
24
+ "ruff>=0.15",
25
+ "ty>=0.0.39",
26
+ "pytest>=8",
27
+ ]
28
+
29
+ [tool.ruff]
30
+ target-version = "py313"
31
+ line-length = 88
32
+ src = ["src"]
33
+
34
+ [tool.ruff.lint]
35
+ select = [
36
+ "E", # pycodestyle errors
37
+ "W", # pycodestyle warnings
38
+ "F", # pyflakes
39
+ "I", # isort
40
+ "B", # flake8-bugbear
41
+ "C4", # flake8-comprehensions
42
+ "UP", # pyupgrade
43
+ "SIM", # flake8-simplify
44
+ "RUF", # ruff-specific rules
45
+ ]
46
+
47
+ [tool.ruff.lint.isort]
48
+ known-first-party = ["ray_pixi"]
49
+
50
+ [tool.ruff.format]
51
+ docstring-code-format = true
52
+
53
+ [tool.ty.environment]
54
+ root = ["./src"]
55
+
56
+ [tool.pytest.ini_options]
57
+ testpaths = ["tests"]
58
+ addopts = "-ra"
@@ -0,0 +1,23 @@
1
+ """ray-pixi: a pixi runtime_env plugin for Ray.
2
+
3
+ Register the plugin by setting, on every node before it starts::
4
+
5
+ RAY_RUNTIME_ENV_PLUGINS = '[{"class": "ray_pixi.PixiPlugin"}]'
6
+
7
+ The Ray runtime_env agent reads that variable at startup. Build the
8
+ ``runtime_env["pixi"]`` field with :func:`pixi`.
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ from importlib.metadata import PackageNotFoundError, version
14
+
15
+ from ray_pixi.plugin import PixiPlugin
16
+ from ray_pixi.spec import pixi
17
+
18
+ try:
19
+ __version__ = version("ray-pixi")
20
+ except PackageNotFoundError: # package is not installed
21
+ __version__ = "0.0.0+unknown"
22
+
23
+ __all__ = ["PixiPlugin", "__version__", "pixi"]