isolate 0.12.9__tar.gz → 0.12.11__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.
Potentially problematic release.
This version of isolate might be problematic. Click here for more details.
- isolate-0.12.11/.github/workflows/release.yml +50 -0
- isolate-0.12.11/.github/workflows/test.yml +68 -0
- isolate-0.12.11/.gitignore +125 -0
- isolate-0.12.11/.pre-commit-config.yaml +28 -0
- {isolate-0.12.9 → isolate-0.12.11}/PKG-INFO +46 -21
- {isolate-0.12.9 → isolate-0.12.11}/README.md +25 -0
- isolate-0.12.11/pyproject.toml +67 -0
- isolate-0.12.11/setup.cfg +4 -0
- isolate-0.12.11/src/isolate/__init__.py +3 -0
- isolate-0.12.11/src/isolate/_isolate_version.py +16 -0
- isolate-0.12.11/src/isolate/_version.py +6 -0
- {isolate-0.12.9 → isolate-0.12.11}/src/isolate/backends/_base.py +6 -4
- {isolate-0.12.9 → isolate-0.12.11}/src/isolate/backends/common.py +7 -7
- {isolate-0.12.9 → isolate-0.12.11}/src/isolate/backends/conda.py +1 -2
- {isolate-0.12.9 → isolate-0.12.11}/src/isolate/backends/pyenv.py +8 -5
- {isolate-0.12.9 → isolate-0.12.11}/src/isolate/backends/remote.py +3 -2
- {isolate-0.12.9 → isolate-0.12.11}/src/isolate/connections/common.py +3 -1
- {isolate-0.12.9 → isolate-0.12.11}/src/isolate/connections/grpc/_base.py +15 -12
- {isolate-0.12.9 → isolate-0.12.11}/src/isolate/connections/grpc/agent.py +8 -4
- {isolate-0.12.9 → isolate-0.12.11}/src/isolate/connections/ipc/_base.py +6 -4
- {isolate-0.12.9 → isolate-0.12.11}/src/isolate/connections/ipc/agent.py +4 -1
- isolate-0.12.11/src/isolate/exceptions.py +2 -0
- {isolate-0.12.9 → isolate-0.12.11}/src/isolate/logs.py +0 -1
- {isolate-0.12.9 → isolate-0.12.11}/src/isolate/server/health/__init__.py +4 -1
- {isolate-0.12.9 → isolate-0.12.11}/src/isolate/server/server.py +6 -5
- isolate-0.12.11/src/isolate.egg-info/PKG-INFO +86 -0
- isolate-0.12.11/src/isolate.egg-info/SOURCES.txt +82 -0
- isolate-0.12.11/src/isolate.egg-info/dependency_links.txt +1 -0
- isolate-0.12.11/src/isolate.egg-info/entry_points.txt +6 -0
- isolate-0.12.11/src/isolate.egg-info/requires.txt +21 -0
- isolate-0.12.11/src/isolate.egg-info/top_level.txt +1 -0
- isolate-0.12.11/tests/__init__.py +0 -0
- isolate-0.12.11/tests/conftest.py +25 -0
- isolate-0.12.11/tests/test_backends.py +856 -0
- isolate-0.12.11/tests/test_concurrency.py +64 -0
- isolate-0.12.11/tests/test_connections.py +211 -0
- isolate-0.12.11/tests/test_isolate.py +42 -0
- isolate-0.12.11/tests/test_log.py +35 -0
- isolate-0.12.11/tests/test_serialization.py +65 -0
- isolate-0.12.11/tests/test_server.py +659 -0
- isolate-0.12.11/tools/Dockerfile +53 -0
- isolate-0.12.11/tools/agent_requirements.txt +4 -0
- isolate-0.12.11/tools/protobuf-requirements.txt +8 -0
- isolate-0.12.11/tools/regen_grpc.py +83 -0
- isolate-0.12.11/tools/requirements.txt +6 -0
- isolate-0.12.11/tools/test_agent_requirements.txt +4 -0
- isolate-0.12.9/pyproject.toml +0 -44
- isolate-0.12.9/src/isolate/__init__.py +0 -1
- {isolate-0.12.9 → isolate-0.12.11}/LICENSE +0 -0
- {isolate-0.12.9 → isolate-0.12.11}/src/isolate/backends/__init__.py +0 -0
- {isolate-0.12.9 → isolate-0.12.11}/src/isolate/backends/local.py +0 -0
- {isolate-0.12.9 → isolate-0.12.11}/src/isolate/backends/settings.py +0 -0
- {isolate-0.12.9 → isolate-0.12.11}/src/isolate/backends/virtualenv.py +0 -0
- {isolate-0.12.9 → isolate-0.12.11}/src/isolate/common/__init__.py +0 -0
- {isolate-0.12.9 → isolate-0.12.11}/src/isolate/common/timestamp.py +0 -0
- {isolate-0.12.9 → isolate-0.12.11}/src/isolate/connections/__init__.py +0 -0
- {isolate-0.12.9 → isolate-0.12.11}/src/isolate/connections/_local/__init__.py +0 -0
- {isolate-0.12.9 → isolate-0.12.11}/src/isolate/connections/_local/_base.py +0 -0
- {isolate-0.12.9 → isolate-0.12.11}/src/isolate/connections/_local/agent_startup.py +0 -0
- {isolate-0.12.9 → isolate-0.12.11}/src/isolate/connections/grpc/__init__.py +0 -0
- {isolate-0.12.9 → isolate-0.12.11}/src/isolate/connections/grpc/configuration.py +0 -0
- {isolate-0.12.9 → isolate-0.12.11}/src/isolate/connections/grpc/definitions/__init__.py +0 -0
- {isolate-0.12.9 → isolate-0.12.11}/src/isolate/connections/grpc/definitions/agent.proto +0 -0
- {isolate-0.12.9 → isolate-0.12.11}/src/isolate/connections/grpc/definitions/agent_pb2.py +0 -0
- {isolate-0.12.9 → isolate-0.12.11}/src/isolate/connections/grpc/definitions/agent_pb2.pyi +0 -0
- {isolate-0.12.9 → isolate-0.12.11}/src/isolate/connections/grpc/definitions/agent_pb2_grpc.py +0 -0
- {isolate-0.12.9 → isolate-0.12.11}/src/isolate/connections/grpc/definitions/common.proto +0 -0
- {isolate-0.12.9 → isolate-0.12.11}/src/isolate/connections/grpc/definitions/common_pb2.py +0 -0
- {isolate-0.12.9 → isolate-0.12.11}/src/isolate/connections/grpc/definitions/common_pb2.pyi +0 -0
- {isolate-0.12.9 → isolate-0.12.11}/src/isolate/connections/grpc/definitions/common_pb2_grpc.py +0 -0
- {isolate-0.12.9 → isolate-0.12.11}/src/isolate/connections/grpc/interface.py +0 -0
- {isolate-0.12.9 → isolate-0.12.11}/src/isolate/connections/ipc/__init__.py +0 -0
- {isolate-0.12.9 → isolate-0.12.11}/src/isolate/py.typed +0 -0
- {isolate-0.12.9 → isolate-0.12.11}/src/isolate/registry.py +0 -0
- {isolate-0.12.9 → isolate-0.12.11}/src/isolate/server/__init__.py +0 -0
- {isolate-0.12.9 → isolate-0.12.11}/src/isolate/server/definitions/__init__.py +0 -0
- {isolate-0.12.9 → isolate-0.12.11}/src/isolate/server/definitions/server.proto +0 -0
- {isolate-0.12.9 → isolate-0.12.11}/src/isolate/server/definitions/server_pb2.py +0 -0
- {isolate-0.12.9 → isolate-0.12.11}/src/isolate/server/definitions/server_pb2.pyi +0 -0
- {isolate-0.12.9 → isolate-0.12.11}/src/isolate/server/definitions/server_pb2_grpc.py +0 -0
- {isolate-0.12.9 → isolate-0.12.11}/src/isolate/server/health/health.proto +0 -0
- {isolate-0.12.9 → isolate-0.12.11}/src/isolate/server/health/health_pb2.py +0 -0
- {isolate-0.12.9 → isolate-0.12.11}/src/isolate/server/health/health_pb2.pyi +0 -0
- {isolate-0.12.9 → isolate-0.12.11}/src/isolate/server/health/health_pb2_grpc.py +0 -0
- {isolate-0.12.9 → isolate-0.12.11}/src/isolate/server/health_server.py +0 -0
- {isolate-0.12.9 → isolate-0.12.11}/src/isolate/server/interface.py +0 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
name: PyPI release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types:
|
|
6
|
+
- published
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
build:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v3
|
|
13
|
+
with:
|
|
14
|
+
fetch-depth: 0
|
|
15
|
+
|
|
16
|
+
- uses: actions/setup-python@v2
|
|
17
|
+
with:
|
|
18
|
+
python-version: "3.9"
|
|
19
|
+
|
|
20
|
+
- name: Install deps
|
|
21
|
+
run: python -m pip install --upgrade pip setuptools_scm build
|
|
22
|
+
|
|
23
|
+
- name: Build
|
|
24
|
+
run: python -m build
|
|
25
|
+
|
|
26
|
+
- name: Upload dist
|
|
27
|
+
uses: actions/upload-artifact@v4
|
|
28
|
+
with:
|
|
29
|
+
name: dist
|
|
30
|
+
path: dist
|
|
31
|
+
|
|
32
|
+
pypi-publish:
|
|
33
|
+
name: Upload release to PyPI
|
|
34
|
+
runs-on: ubuntu-latest
|
|
35
|
+
needs: build
|
|
36
|
+
environment:
|
|
37
|
+
name: pypi
|
|
38
|
+
url: https://pypi.org/p/isolate
|
|
39
|
+
permissions:
|
|
40
|
+
id-token: write
|
|
41
|
+
steps:
|
|
42
|
+
- name: Download dist
|
|
43
|
+
uses: actions/download-artifact@v4
|
|
44
|
+
with:
|
|
45
|
+
name: dist
|
|
46
|
+
path: dist
|
|
47
|
+
|
|
48
|
+
- name: Publish package distributions to PyPI
|
|
49
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
50
|
+
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
name: Tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
pull_request:
|
|
8
|
+
branches:
|
|
9
|
+
schedule:
|
|
10
|
+
- cron: '30 5 * * *' # every day at 5:30 UTC
|
|
11
|
+
|
|
12
|
+
concurrency:
|
|
13
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
14
|
+
cancel-in-progress: true
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
test:
|
|
18
|
+
runs-on: ${{ matrix.os }}
|
|
19
|
+
strategy:
|
|
20
|
+
fail-fast: true
|
|
21
|
+
|
|
22
|
+
matrix:
|
|
23
|
+
os: [ubuntu-latest]
|
|
24
|
+
python: ["3.8", "3.9", "3.10", "3.11"]
|
|
25
|
+
include:
|
|
26
|
+
- os: macos-latest
|
|
27
|
+
python: "3.8"
|
|
28
|
+
- os: macos-latest
|
|
29
|
+
python: "3.11"
|
|
30
|
+
steps:
|
|
31
|
+
- uses: actions/checkout@v3
|
|
32
|
+
|
|
33
|
+
- uses: actions/setup-python@v3
|
|
34
|
+
with:
|
|
35
|
+
python-version: ${{ matrix.python }}
|
|
36
|
+
|
|
37
|
+
- name: Install mamba
|
|
38
|
+
uses: mamba-org/setup-micromamba@v1
|
|
39
|
+
with:
|
|
40
|
+
environment-name: ci
|
|
41
|
+
create-args: >-
|
|
42
|
+
python=${{ matrix.python }}
|
|
43
|
+
condarc: |
|
|
44
|
+
channels:
|
|
45
|
+
- anaconda
|
|
46
|
+
- conda-forge
|
|
47
|
+
- pytorch
|
|
48
|
+
|
|
49
|
+
- uses: actions/checkout@v3
|
|
50
|
+
with:
|
|
51
|
+
repository: pyenv/pyenv
|
|
52
|
+
ref: v2.3.6
|
|
53
|
+
path: pyenv
|
|
54
|
+
|
|
55
|
+
- name: Install dependencies
|
|
56
|
+
run: |
|
|
57
|
+
python -m pip install -e ".[test]"
|
|
58
|
+
|
|
59
|
+
- name: Install uv
|
|
60
|
+
run: |
|
|
61
|
+
python -m pip install uv
|
|
62
|
+
|
|
63
|
+
- uses: pre-commit/action@v3.0.1
|
|
64
|
+
|
|
65
|
+
- name: Test
|
|
66
|
+
run: |
|
|
67
|
+
export ISOLATE_PYENV_EXECUTABLE=pyenv/bin/pyenv
|
|
68
|
+
python -m pytest -vvv
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
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
|
+
pip-wheel-metadata/
|
|
24
|
+
share/python-wheels/
|
|
25
|
+
*.egg-info/
|
|
26
|
+
.installed.cfg
|
|
27
|
+
*.egg
|
|
28
|
+
MANIFEST
|
|
29
|
+
|
|
30
|
+
# PyInstaller
|
|
31
|
+
# Usually these files are written by a python script from a template
|
|
32
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
33
|
+
*.manifest
|
|
34
|
+
*.spec
|
|
35
|
+
|
|
36
|
+
# Installer logs
|
|
37
|
+
pip-log.txt
|
|
38
|
+
pip-delete-this-directory.txt
|
|
39
|
+
|
|
40
|
+
# Unit test / coverage reports
|
|
41
|
+
htmlcov/
|
|
42
|
+
.tox/
|
|
43
|
+
.nox/
|
|
44
|
+
.coverage
|
|
45
|
+
.coverage.*
|
|
46
|
+
.cache
|
|
47
|
+
nosetests.xml
|
|
48
|
+
coverage.xml
|
|
49
|
+
*.cover
|
|
50
|
+
.hypothesis/
|
|
51
|
+
.pytest_cache/
|
|
52
|
+
|
|
53
|
+
# Translations
|
|
54
|
+
*.mo
|
|
55
|
+
*.pot
|
|
56
|
+
|
|
57
|
+
# Django stuff:
|
|
58
|
+
*.log
|
|
59
|
+
local_settings.py
|
|
60
|
+
db.sqlite3
|
|
61
|
+
db.sqlite3-journal
|
|
62
|
+
|
|
63
|
+
# Flask stuff:
|
|
64
|
+
instance/
|
|
65
|
+
.webassets-cache
|
|
66
|
+
|
|
67
|
+
# Scrapy stuff:
|
|
68
|
+
.scrapy
|
|
69
|
+
|
|
70
|
+
# Sphinx documentation
|
|
71
|
+
docs/_build/
|
|
72
|
+
|
|
73
|
+
# PyBuilder
|
|
74
|
+
target/
|
|
75
|
+
|
|
76
|
+
# Jupyter Notebook
|
|
77
|
+
.ipynb_checkpoints
|
|
78
|
+
|
|
79
|
+
# IPython
|
|
80
|
+
profile_default/
|
|
81
|
+
ipython_config.py
|
|
82
|
+
|
|
83
|
+
# pyenv
|
|
84
|
+
.python-version
|
|
85
|
+
|
|
86
|
+
# anti lolenv
|
|
87
|
+
Pipfile*
|
|
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
|
+
.dmypy.json
|
|
117
|
+
dmypy.json
|
|
118
|
+
|
|
119
|
+
# Pyre type checker
|
|
120
|
+
.pyre/
|
|
121
|
+
|
|
122
|
+
# vim
|
|
123
|
+
*.swp
|
|
124
|
+
|
|
125
|
+
/src/isolate/_isolate_version.py
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
3
|
+
rev: 'v0.3.4'
|
|
4
|
+
hooks:
|
|
5
|
+
- id: ruff
|
|
6
|
+
args: [--fix, --exit-non-zero-on-fix]
|
|
7
|
+
exclude: ".*(_pb2.py|_pb2.pyi|_pb2_grpc.py)$"
|
|
8
|
+
- id: ruff-format
|
|
9
|
+
exclude: ".*(_pb2.py|_pb2.pyi|_pb2_grpc.py)$"
|
|
10
|
+
- repo: https://github.com/asottile/setup-cfg-fmt
|
|
11
|
+
rev: v1.20.1
|
|
12
|
+
hooks:
|
|
13
|
+
- id: setup-cfg-fmt
|
|
14
|
+
- repo: https://github.com/pre-commit/mirrors-mypy
|
|
15
|
+
rev: v1.2.0
|
|
16
|
+
hooks:
|
|
17
|
+
- id: mypy
|
|
18
|
+
args:
|
|
19
|
+
- --disallow-incomplete-defs
|
|
20
|
+
- --ignore-missing-imports
|
|
21
|
+
- --no-warn-no-return
|
|
22
|
+
exclude: ".*(_pb2.py|_pb2.pyi|_pb2_grpc.py)$"
|
|
23
|
+
additional_dependencies: [types-protobuf]
|
|
24
|
+
- repo: https://github.com/codespell-project/codespell
|
|
25
|
+
rev: v2.1.0
|
|
26
|
+
hooks:
|
|
27
|
+
- id: codespell
|
|
28
|
+
exclude: ".*(_pb2.py|_pb2.pyi|_pb2_grpc.py)$"
|
|
@@ -1,28 +1,29 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: isolate
|
|
3
|
-
Version: 0.12.
|
|
3
|
+
Version: 0.12.11
|
|
4
4
|
Summary: Managed isolated environments for Python
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
Requires-Python: >=3.8
|
|
9
|
-
Classifier: Programming Language :: Python :: 3
|
|
10
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
11
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
12
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
13
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
-
Provides-Extra: build
|
|
15
|
-
Provides-Extra: grpc
|
|
16
|
-
Provides-Extra: server
|
|
17
|
-
Requires-Dist: PyYAML (>=6.0) ; extra == "build"
|
|
18
|
-
Requires-Dist: grpcio (>=1.49)
|
|
19
|
-
Requires-Dist: importlib-metadata (>=4.4) ; python_version < "3.10"
|
|
20
|
-
Requires-Dist: platformdirs
|
|
21
|
-
Requires-Dist: protobuf
|
|
22
|
-
Requires-Dist: tblib (>=1.7.0)
|
|
23
|
-
Requires-Dist: virtualenv (>=20.4) ; extra == "build"
|
|
24
|
-
Project-URL: Repository, https://github.com/fal-ai/isolate
|
|
5
|
+
Author-email: Features & Labels <hello@fal.ai>
|
|
6
|
+
Project-URL: Issues, https://github.com/fal-ai/isolate/issues
|
|
7
|
+
Project-URL: Source, https://github.com/fal-ai/isolate
|
|
8
|
+
Requires-Python: >=3.8
|
|
25
9
|
Description-Content-Type: text/markdown
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Requires-Dist: grpcio>=1.49
|
|
12
|
+
Requires-Dist: protobuf
|
|
13
|
+
Requires-Dist: tblib>=1.7.0
|
|
14
|
+
Requires-Dist: platformdirs
|
|
15
|
+
Requires-Dist: importlib-metadata>=4.4; python_version < "3.10"
|
|
16
|
+
Provides-Extra: build
|
|
17
|
+
Requires-Dist: virtualenv>=20.4; extra == "build"
|
|
18
|
+
Requires-Dist: PyYAML>=6.0; extra == "build"
|
|
19
|
+
Provides-Extra: test
|
|
20
|
+
Requires-Dist: isolate[build]; extra == "test"
|
|
21
|
+
Requires-Dist: pytest; extra == "test"
|
|
22
|
+
Requires-Dist: cloudpickle>=2.2.0; extra == "test"
|
|
23
|
+
Requires-Dist: dill>=0.3.5.1; extra == "test"
|
|
24
|
+
Requires-Dist: pytest-rerunfailures; extra == "test"
|
|
25
|
+
Provides-Extra: dev
|
|
26
|
+
Requires-Dist: isolate[test]; extra == "dev"
|
|
26
27
|
|
|
27
28
|
# Isolate
|
|
28
29
|
|
|
@@ -59,3 +60,27 @@ different) and can change it without any loss. Isolate is working towards a futu
|
|
|
59
60
|
transititon is as seamless as the transition from your local environment to the remote
|
|
60
61
|
environment.
|
|
61
62
|
|
|
63
|
+
## Contributing
|
|
64
|
+
|
|
65
|
+
### Installing in editable mode with dev dependencies
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
pip install -e '.[dev]'
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Running tests
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
pytest
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Pre-commit
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
pre-commit install
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Commit format
|
|
84
|
+
|
|
85
|
+
Please follow [conventional commits specification](https://www.conventionalcommits.org/) for descriptions/messages.
|
|
86
|
+
|
|
@@ -32,3 +32,28 @@ this problem lacked a universal interface which one can simply define a set of r
|
|
|
32
32
|
different) and can change it without any loss. Isolate is working towards a future where this
|
|
33
33
|
transititon is as seamless as the transition from your local environment to the remote
|
|
34
34
|
environment.
|
|
35
|
+
|
|
36
|
+
## Contributing
|
|
37
|
+
|
|
38
|
+
### Installing in editable mode with dev dependencies
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
pip install -e '.[dev]'
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Running tests
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
pytest
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Pre-commit
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
pre-commit install
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Commit format
|
|
57
|
+
|
|
58
|
+
Please follow [conventional commits specification](https://www.conventionalcommits.org/) for descriptions/messages.
|
|
59
|
+
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools", "wheel", "setuptools_scm[toml]>=7"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[tool.setuptools_scm]
|
|
6
|
+
version_file = "src/isolate/_isolate_version.py"
|
|
7
|
+
|
|
8
|
+
[tool.setuptools.packages.find]
|
|
9
|
+
where = ["src"]
|
|
10
|
+
include = ["isolate"]
|
|
11
|
+
namespaces = false
|
|
12
|
+
|
|
13
|
+
[project]
|
|
14
|
+
name = "isolate"
|
|
15
|
+
dynamic = ["version"]
|
|
16
|
+
readme = "README.md"
|
|
17
|
+
description = "Managed isolated environments for Python"
|
|
18
|
+
authors = [{ name = "Features & Labels", email = "hello@fal.ai"}]
|
|
19
|
+
requires-python = ">=3.8"
|
|
20
|
+
dependencies = [
|
|
21
|
+
"grpcio>=1.49",
|
|
22
|
+
"protobuf",
|
|
23
|
+
# These are non-intrusive packages with no transitive dependencies.
|
|
24
|
+
# They are also used in the agents themselves.
|
|
25
|
+
"tblib>=1.7.0",
|
|
26
|
+
"platformdirs",
|
|
27
|
+
# For 3.10 and later, importlib-metadata's newer versions are included in the
|
|
28
|
+
# standard library.
|
|
29
|
+
'importlib-metadata>=4.4; python_version < "3.10"',
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
[project.urls]
|
|
33
|
+
Issues = "https://github.com/fal-ai/isolate/issues"
|
|
34
|
+
Source = "https://github.com/fal-ai/isolate"
|
|
35
|
+
|
|
36
|
+
[project.optional-dependencies]
|
|
37
|
+
build = [
|
|
38
|
+
# The following are build-related dependencies, and their usage sites are heavily
|
|
39
|
+
# guarded with optional_import() calls.
|
|
40
|
+
"virtualenv>=20.4",
|
|
41
|
+
"PyYAML>=6.0",
|
|
42
|
+
]
|
|
43
|
+
test = [
|
|
44
|
+
"isolate[build]",
|
|
45
|
+
"pytest",
|
|
46
|
+
"cloudpickle>=2.2.0",
|
|
47
|
+
"dill>=0.3.5.1",
|
|
48
|
+
"pytest-rerunfailures",
|
|
49
|
+
]
|
|
50
|
+
dev = [
|
|
51
|
+
"isolate[test]",
|
|
52
|
+
]
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
[project.entry-points."isolate.backends"]
|
|
56
|
+
"virtualenv" = "isolate.backends.virtualenv:VirtualPythonEnvironment"
|
|
57
|
+
"conda" = "isolate.backends.conda:CondaEnvironment"
|
|
58
|
+
"local" = "isolate.backends.local:LocalPythonEnvironment"
|
|
59
|
+
"isolate-server" = "isolate.backends.remote:IsolateServer"
|
|
60
|
+
"pyenv" = "isolate.backends.pyenv:PyenvEnvironment"
|
|
61
|
+
|
|
62
|
+
[tool.ruff]
|
|
63
|
+
target-version = "py38"
|
|
64
|
+
exclude = ["*_pb2.py", "*_pb2.pyi", "*_pb2_grpc.py"]
|
|
65
|
+
|
|
66
|
+
[tool.ruff.lint]
|
|
67
|
+
select = ["E", "F", "W", "PLC", "PLE", "PLW", "I", "UP"]
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# file generated by setuptools_scm
|
|
2
|
+
# don't change, don't track in version control
|
|
3
|
+
TYPE_CHECKING = False
|
|
4
|
+
if TYPE_CHECKING:
|
|
5
|
+
from typing import Tuple, Union
|
|
6
|
+
VERSION_TUPLE = Tuple[Union[int, str], ...]
|
|
7
|
+
else:
|
|
8
|
+
VERSION_TUPLE = object
|
|
9
|
+
|
|
10
|
+
version: str
|
|
11
|
+
__version__: str
|
|
12
|
+
__version_tuple__: VERSION_TUPLE
|
|
13
|
+
version_tuple: VERSION_TUPLE
|
|
14
|
+
|
|
15
|
+
__version__ = version = '0.12.11'
|
|
16
|
+
__version_tuple__ = version_tuple = (0, 12, 11)
|
|
@@ -12,6 +12,7 @@ from typing import (
|
|
|
12
12
|
)
|
|
13
13
|
|
|
14
14
|
from isolate.backends.settings import DEFAULT_SETTINGS, IsolateSettings
|
|
15
|
+
from isolate.exceptions import IsolateException
|
|
15
16
|
from isolate.logs import Log, LogLevel, LogSource
|
|
16
17
|
|
|
17
18
|
__all__ = [
|
|
@@ -27,7 +28,7 @@ CallResultType = TypeVar("CallResultType")
|
|
|
27
28
|
BasicCallable = Callable[[], CallResultType]
|
|
28
29
|
|
|
29
30
|
|
|
30
|
-
class EnvironmentCreationError(
|
|
31
|
+
class EnvironmentCreationError(IsolateException):
|
|
31
32
|
"""Raised when the environment cannot be created."""
|
|
32
33
|
|
|
33
34
|
|
|
@@ -73,13 +74,14 @@ class BaseEnvironment(Generic[ConnectionKeyType]):
|
|
|
73
74
|
def open_connection(
|
|
74
75
|
self, connection_key: ConnectionKeyType
|
|
75
76
|
) -> EnvironmentConnection:
|
|
76
|
-
"""Return a new connection to the environment with using the
|
|
77
|
+
"""Return a new connection to the environment with using the
|
|
78
|
+
`connection_key`."""
|
|
77
79
|
raise NotImplementedError
|
|
78
80
|
|
|
79
81
|
@contextmanager
|
|
80
82
|
def connect(self) -> Iterator[EnvironmentConnection]:
|
|
81
|
-
"""Create the given environment (if it already doesn't exist) and establish a
|
|
82
|
-
to it."""
|
|
83
|
+
"""Create the given environment (if it already doesn't exist) and establish a
|
|
84
|
+
connection to it."""
|
|
83
85
|
connection_key = self.create()
|
|
84
86
|
with self.open_connection(connection_key) as connection:
|
|
85
87
|
yield connection
|
|
@@ -246,10 +246,10 @@ def get_executable(command: str, home: str | None = None) -> Path:
|
|
|
246
246
|
binary_path = shutil.which(command, path=path)
|
|
247
247
|
if binary_path is not None:
|
|
248
248
|
return Path(binary_path)
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
249
|
+
# TODO: we should probably show some instructions on how you
|
|
250
|
+
# can install conda here.
|
|
251
|
+
raise FileNotFoundError(
|
|
252
|
+
f"Could not find the {command} executable. "
|
|
253
|
+
f"If the {command} executable is not available by default, please point "
|
|
254
|
+
f"isolate to the path where the {command} binary is available '{home}'."
|
|
255
|
+
)
|
|
@@ -43,8 +43,9 @@ class PyenvEnvironment(BaseEnvironment[Path]):
|
|
|
43
43
|
pyenv = _get_pyenv_executable()
|
|
44
44
|
env_path = self.settings.cache_dir_for(self)
|
|
45
45
|
with self.settings.cache_lock_for(env_path):
|
|
46
|
-
# PyEnv installs* the Python versions under $root/versions/$version, where
|
|
47
|
-
# use versions/$version as the key and $root as the base directory
|
|
46
|
+
# PyEnv installs* the Python versions under $root/versions/$version, where
|
|
47
|
+
# we use versions/$version as the key and $root as the base directory
|
|
48
|
+
# (for pyenv).
|
|
48
49
|
#
|
|
49
50
|
# [0]: https://github.com/pyenv/pyenv#locating-pyenv-provided-python-installations
|
|
50
51
|
pyenv_root = env_path.parent.parent
|
|
@@ -126,15 +127,17 @@ def _get_pyenv_executable() -> Path:
|
|
|
126
127
|
if _PYENV_EXECUTABLE_PATH:
|
|
127
128
|
if not os.path.exists(_PYENV_EXECUTABLE_PATH):
|
|
128
129
|
raise EnvironmentCreationError(
|
|
129
|
-
|
|
130
|
+
"Path to pyenv executable not found! ISOLATE_PYENV_EXECUTABLE "
|
|
131
|
+
f"variable: {_PYENV_EXECUTABLE_PATH!r}"
|
|
130
132
|
)
|
|
131
133
|
return Path(_PYENV_EXECUTABLE_PATH)
|
|
132
134
|
|
|
133
135
|
pyenv_path = shutil.which(_PYENV_EXECUTABLE_NAME)
|
|
134
136
|
if pyenv_path is None:
|
|
135
137
|
raise FileNotFoundError(
|
|
136
|
-
"Could not find the pyenv executable. If pyenv is not already installed
|
|
137
|
-
"install it first. If it is not in your PATH,
|
|
138
|
+
"Could not find the pyenv executable. If pyenv is not already installed "
|
|
139
|
+
"in your system, please install it first. If it is not in your PATH, "
|
|
140
|
+
"then point ISOLATE_PYENV_COMMAND to the absolute path of the "
|
|
138
141
|
"pyenv executable."
|
|
139
142
|
)
|
|
140
143
|
return Path(pyenv_path)
|
|
@@ -51,8 +51,9 @@ class IsolateServer(BaseEnvironment[List[EnvironmentDefinition]]):
|
|
|
51
51
|
def create(self, *, force: bool = False) -> list[EnvironmentDefinition]:
|
|
52
52
|
if force is True:
|
|
53
53
|
raise NotImplementedError(
|
|
54
|
-
"Only individual environments can be forcibly created, please set
|
|
55
|
-
" manually by using the 'force_create' flag on the
|
|
54
|
+
"Only individual environments can be forcibly created, please set "
|
|
55
|
+
"them up manually by using the 'force_create' flag on the "
|
|
56
|
+
"environment definition."
|
|
56
57
|
)
|
|
57
58
|
|
|
58
59
|
envs = []
|
|
@@ -8,6 +8,8 @@ from typing import TYPE_CHECKING, Any, Iterator, cast
|
|
|
8
8
|
|
|
9
9
|
from tblib import Traceback, TracebackParseError
|
|
10
10
|
|
|
11
|
+
from isolate.exceptions import IsolateException
|
|
12
|
+
|
|
11
13
|
if TYPE_CHECKING:
|
|
12
14
|
from typing import Protocol
|
|
13
15
|
|
|
@@ -21,7 +23,7 @@ AGENT_SIGNATURE = "IS_ISOLATE_AGENT"
|
|
|
21
23
|
|
|
22
24
|
|
|
23
25
|
@dataclass
|
|
24
|
-
class SerializationError(
|
|
26
|
+
class SerializationError(IsolateException):
|
|
25
27
|
"""An error that happened during the serialization process."""
|
|
26
28
|
|
|
27
29
|
message: str
|
|
@@ -16,10 +16,11 @@ from isolate.connections.common import serialize_object
|
|
|
16
16
|
from isolate.connections.grpc import agent, definitions
|
|
17
17
|
from isolate.connections.grpc.configuration import get_default_options
|
|
18
18
|
from isolate.connections.grpc.interface import from_grpc
|
|
19
|
+
from isolate.exceptions import IsolateException
|
|
19
20
|
from isolate.logs import LogLevel, LogSource
|
|
20
21
|
|
|
21
22
|
|
|
22
|
-
class AgentError(
|
|
23
|
+
class AgentError(IsolateException):
|
|
23
24
|
"""An internal problem caused by (most probably) the agent."""
|
|
24
25
|
|
|
25
26
|
|
|
@@ -49,8 +50,8 @@ class GRPCExecutionBase(EnvironmentConnection):
|
|
|
49
50
|
channel_status.result(timeout=max_wait_timeout)
|
|
50
51
|
except grpc.FutureTimeoutError:
|
|
51
52
|
raise AgentError(
|
|
52
|
-
|
|
53
|
-
"in time."
|
|
53
|
+
"Couldn't connect to the gRPC server in the agent "
|
|
54
|
+
f"(listening at {address}) in time."
|
|
54
55
|
)
|
|
55
56
|
stub = definitions.AgentStub(channel)
|
|
56
57
|
stub._channel = channel # type: ignore
|
|
@@ -69,15 +70,16 @@ class GRPCExecutionBase(EnvironmentConnection):
|
|
|
69
70
|
# ---------
|
|
70
71
|
# 1. [controller]: Spawn the agent.
|
|
71
72
|
# 2. [agent]: Start listening at the given address.
|
|
72
|
-
# 3. [controller]: Await *at most* max_wait_timeout seconds for the agent to
|
|
73
|
-
# if it doesn't do it until then,
|
|
74
|
-
#
|
|
75
|
-
#
|
|
73
|
+
# 3. [controller]: Await *at most* max_wait_timeout seconds for the agent to
|
|
74
|
+
# be available if it doesn't do it until then,
|
|
75
|
+
# raise an AgentError.
|
|
76
|
+
# 4. [controller]: If the server is available, then establish the bridge and
|
|
77
|
+
# pass the 'function' as the input.
|
|
76
78
|
# 5. [agent]: Receive the function, deserialize it, start the execution.
|
|
77
|
-
# 6. [controller]: Watch agent for logs (stdout/stderr), and as soon as they
|
|
78
|
-
# call the log handler.
|
|
79
|
-
# 7. [agent]: Once the execution of the function is finished, send the
|
|
80
|
-
# using the same serialization method.
|
|
79
|
+
# 6. [controller]: Watch agent for logs (stdout/stderr), and as soon as they
|
|
80
|
+
# appear call the log handler.
|
|
81
|
+
# 7. [agent]: Once the execution of the function is finished, send the
|
|
82
|
+
# result using the same serialization method.
|
|
81
83
|
# 8. [controller]: Receive the result back and return it.
|
|
82
84
|
|
|
83
85
|
method = self.environment.settings.serialization_method
|
|
@@ -106,7 +108,8 @@ class GRPCExecutionBase(EnvironmentConnection):
|
|
|
106
108
|
return cast(CallResultType, from_grpc(partial_result.result))
|
|
107
109
|
|
|
108
110
|
raise AgentError(
|
|
109
|
-
"No result object was received from the agent
|
|
111
|
+
"No result object was received from the agent "
|
|
112
|
+
"(it never set is_complete to True)."
|
|
110
113
|
)
|
|
111
114
|
|
|
112
115
|
|