appose 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,24 @@
1
+ Copyright (c) 2023, Appose developers.
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without modification,
5
+ are permitted provided that the following conditions are met:
6
+
7
+ 1. Redistributions of source code must retain the above copyright notice, this
8
+ list of conditions and the following disclaimer.
9
+
10
+ 2. Redistributions in binary form must reproduce the above copyright notice,
11
+ this list of conditions and the following disclaimer in the documentation
12
+ and/or other materials provided with the distribution.
13
+
14
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
18
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24
+ POSSIBILITY OF SUCH DAMAGE.
appose-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,160 @@
1
+ Metadata-Version: 2.1
2
+ Name: appose
3
+ Version: 0.1.0
4
+ Summary: Appose: multi-language interprocess cooperation with shared memory.
5
+ Author: Appose developers
6
+ License: Simplified BSD License
7
+ Project-URL: homepage, https://github.com/apposed/appose-python
8
+ Project-URL: documentation, https://github.com/apposed/appose-python/blob/main/README.md
9
+ Project-URL: source, https://github.com/apposed/appose-python
10
+ Project-URL: download, https://pypi.org/project/appose-python
11
+ Project-URL: tracker, https://github.com/apposed/appose-python/issues
12
+ Keywords: java,javascript,python,cross-language,interprocess
13
+ Classifier: Development Status :: 2 - Pre-Alpha
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Intended Audience :: Education
16
+ Classifier: Intended Audience :: Science/Research
17
+ Classifier: Programming Language :: Python :: 3 :: Only
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: License :: OSI Approved :: BSD License
21
+ Classifier: Operating System :: Microsoft :: Windows
22
+ Classifier: Operating System :: Unix
23
+ Classifier: Operating System :: MacOS
24
+ Classifier: Topic :: Scientific/Engineering
25
+ Classifier: Topic :: Software Development :: Libraries :: Java Libraries
26
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
27
+ Classifier: Topic :: Utilities
28
+ Requires-Python: >=3.10
29
+ Description-Content-Type: text/markdown
30
+ Provides-Extra: dev
31
+ License-File: LICENSE.txt
32
+
33
+ # Appose Python
34
+
35
+ ***WARNING: Appose is currently in incubation.
36
+ Not all features described below are functional.
37
+ This document has some aspirational aspects!***
38
+
39
+ ## What is Appose?
40
+
41
+ Appose is a library for interprocess cooperation with shared memory.
42
+ The guiding principles are *simplicity* and *efficiency*.
43
+
44
+ Appose was written to enable **easy execution of Python-based deep learning
45
+ from Java without copying tensors**, but its utility extends beyond that.
46
+ The steps for using Appose are:
47
+
48
+ * Build an Environment with the dependencies you need.
49
+ * Create a Service linked to a *worker*, which runs in its own process.
50
+ * Execute scripts on the worker by launching Tasks.
51
+ * Receive status updates from the task asynchronously via callbacks.
52
+
53
+ For more about Appose as a whole, see https://apposed.org.
54
+
55
+ ## What is this project?
56
+
57
+ This is the **Python implementation of Appose**.
58
+
59
+ ## How do I use it?
60
+
61
+ The name of the package is `appose`.
62
+
63
+ ### Conda/Mamba
64
+
65
+ To use [the conda-forge package](https://anaconda.org/conda-forge/appose),
66
+ add `appose` to your `environment.yml`'s `dependencies` section:
67
+
68
+ ```yaml
69
+ dependencies:
70
+ - appose
71
+ ```
72
+
73
+ ### PyPI/Pip
74
+
75
+ To use [the PyPI package](https://pypi.org/project/appose),
76
+ add `appose` to your project dependencies.
77
+
78
+ Depending on how your project is set up, this might entail editing
79
+ `requirements.txt`, `setup.py`, `setup.cfg`, and/or `pyproject.toml`.
80
+
81
+ If you are just starting out, we recommend using `pyproject.toml` (see
82
+ [this guide](https://packaging.python.org/en/latest/tutorials/packaging-projects/#creating-pyproject-toml)):
83
+
84
+ ```toml
85
+ dependencies = [
86
+ "appose"
87
+ ]
88
+ ```
89
+
90
+ ## Examples
91
+
92
+ Here is a minimal example for calling into Java from Python:
93
+
94
+ ```python
95
+ import appose
96
+ env = appose.java(vendor="zulu", version="17").build()
97
+ with env.groovy() as groovy:
98
+ task = groovy.task("5 + 6")
99
+ task.waitFor()
100
+ result = task.outputs.get("result")
101
+ assert 11 == result
102
+ ```
103
+
104
+ *Note: The `Appose.java` builder is planned, but not yet implemented.*
105
+
106
+ Here is an example using a few more of Appose's features:
107
+
108
+ ```python
109
+ import appose
110
+ from time import sleep
111
+
112
+ golden_ratio_in_groovy = """
113
+ // Approximate the golden ratio using the Fibonacci sequence.
114
+ previous = 0
115
+ current = 1
116
+ for (i=0; i<iterations; i++) {
117
+ if (task.cancelRequested) {
118
+ task.cancel()
119
+ break
120
+ }
121
+ task.update(null, i, iterations)
122
+ v = current
123
+ current += previous
124
+ previous = v
125
+ }
126
+ task.outputs["numer"] = current
127
+ task.outputs["denom"] = previous
128
+ """
129
+
130
+ env = appose.java(vendor="zulu", version="17").build()
131
+ with env.groovy() as groovy:
132
+ task = groovy.task(golden_ratio_in_groovy)
133
+
134
+ def task_listener(event):
135
+ match event.responseType:
136
+ case ResponseType.UPDATE:
137
+ print(f"Progress {task.current}/{task.maximum}")
138
+ case ResponseType.COMPLETION:
139
+ numer = task.outputs["numer"]
140
+ denom = task.outputs["denom"]
141
+ ratio = numer / denom
142
+ print(f"Task complete. Result: {numer}/{denom} =~ {ratio}");
143
+ case ResponseType.CANCELATION:
144
+ print("Task canceled")
145
+ case ResponseType.FAILURE:
146
+ print(f"Task failed: {task.error}")
147
+
148
+ task.listen(task_listener)
149
+
150
+ task.start()
151
+ sleep(1)
152
+ if not task.status.is_finished():
153
+ # Task is taking too long; request a cancelation.
154
+ task.cancel()
155
+
156
+ task.wait_for()
157
+ ```
158
+
159
+ Of course, the above examples could have been done all in one language. But
160
+ hopefully they hint at the possibilities of easy cross-language integration.
appose-0.1.0/README.md ADDED
@@ -0,0 +1,128 @@
1
+ # Appose Python
2
+
3
+ ***WARNING: Appose is currently in incubation.
4
+ Not all features described below are functional.
5
+ This document has some aspirational aspects!***
6
+
7
+ ## What is Appose?
8
+
9
+ Appose is a library for interprocess cooperation with shared memory.
10
+ The guiding principles are *simplicity* and *efficiency*.
11
+
12
+ Appose was written to enable **easy execution of Python-based deep learning
13
+ from Java without copying tensors**, but its utility extends beyond that.
14
+ The steps for using Appose are:
15
+
16
+ * Build an Environment with the dependencies you need.
17
+ * Create a Service linked to a *worker*, which runs in its own process.
18
+ * Execute scripts on the worker by launching Tasks.
19
+ * Receive status updates from the task asynchronously via callbacks.
20
+
21
+ For more about Appose as a whole, see https://apposed.org.
22
+
23
+ ## What is this project?
24
+
25
+ This is the **Python implementation of Appose**.
26
+
27
+ ## How do I use it?
28
+
29
+ The name of the package is `appose`.
30
+
31
+ ### Conda/Mamba
32
+
33
+ To use [the conda-forge package](https://anaconda.org/conda-forge/appose),
34
+ add `appose` to your `environment.yml`'s `dependencies` section:
35
+
36
+ ```yaml
37
+ dependencies:
38
+ - appose
39
+ ```
40
+
41
+ ### PyPI/Pip
42
+
43
+ To use [the PyPI package](https://pypi.org/project/appose),
44
+ add `appose` to your project dependencies.
45
+
46
+ Depending on how your project is set up, this might entail editing
47
+ `requirements.txt`, `setup.py`, `setup.cfg`, and/or `pyproject.toml`.
48
+
49
+ If you are just starting out, we recommend using `pyproject.toml` (see
50
+ [this guide](https://packaging.python.org/en/latest/tutorials/packaging-projects/#creating-pyproject-toml)):
51
+
52
+ ```toml
53
+ dependencies = [
54
+ "appose"
55
+ ]
56
+ ```
57
+
58
+ ## Examples
59
+
60
+ Here is a minimal example for calling into Java from Python:
61
+
62
+ ```python
63
+ import appose
64
+ env = appose.java(vendor="zulu", version="17").build()
65
+ with env.groovy() as groovy:
66
+ task = groovy.task("5 + 6")
67
+ task.waitFor()
68
+ result = task.outputs.get("result")
69
+ assert 11 == result
70
+ ```
71
+
72
+ *Note: The `Appose.java` builder is planned, but not yet implemented.*
73
+
74
+ Here is an example using a few more of Appose's features:
75
+
76
+ ```python
77
+ import appose
78
+ from time import sleep
79
+
80
+ golden_ratio_in_groovy = """
81
+ // Approximate the golden ratio using the Fibonacci sequence.
82
+ previous = 0
83
+ current = 1
84
+ for (i=0; i<iterations; i++) {
85
+ if (task.cancelRequested) {
86
+ task.cancel()
87
+ break
88
+ }
89
+ task.update(null, i, iterations)
90
+ v = current
91
+ current += previous
92
+ previous = v
93
+ }
94
+ task.outputs["numer"] = current
95
+ task.outputs["denom"] = previous
96
+ """
97
+
98
+ env = appose.java(vendor="zulu", version="17").build()
99
+ with env.groovy() as groovy:
100
+ task = groovy.task(golden_ratio_in_groovy)
101
+
102
+ def task_listener(event):
103
+ match event.responseType:
104
+ case ResponseType.UPDATE:
105
+ print(f"Progress {task.current}/{task.maximum}")
106
+ case ResponseType.COMPLETION:
107
+ numer = task.outputs["numer"]
108
+ denom = task.outputs["denom"]
109
+ ratio = numer / denom
110
+ print(f"Task complete. Result: {numer}/{denom} =~ {ratio}");
111
+ case ResponseType.CANCELATION:
112
+ print("Task canceled")
113
+ case ResponseType.FAILURE:
114
+ print(f"Task failed: {task.error}")
115
+
116
+ task.listen(task_listener)
117
+
118
+ task.start()
119
+ sleep(1)
120
+ if not task.status.is_finished():
121
+ # Task is taking too long; request a cancelation.
122
+ task.cancel()
123
+
124
+ task.wait_for()
125
+ ```
126
+
127
+ Of course, the above examples could have been done all in one language. But
128
+ hopefully they hint at the possibilities of easy cross-language integration.
@@ -0,0 +1,78 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.2"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "appose"
7
+ version = "0.1.0"
8
+ description = "Appose: multi-language interprocess cooperation with shared memory."
9
+ license = {text = "Simplified BSD License"}
10
+ authors = [{name = "Appose developers"}]
11
+ readme = "README.md"
12
+ keywords = ["java", "javascript", "python", "cross-language", "interprocess"]
13
+ classifiers = [
14
+ "Development Status :: 2 - Pre-Alpha",
15
+ "Intended Audience :: Developers",
16
+ "Intended Audience :: Education",
17
+ "Intended Audience :: Science/Research",
18
+ "Programming Language :: Python :: 3 :: Only",
19
+ "Programming Language :: Python :: 3.10",
20
+ "Programming Language :: Python :: 3.11",
21
+ "License :: OSI Approved :: BSD License",
22
+ "Operating System :: Microsoft :: Windows",
23
+ "Operating System :: Unix",
24
+ "Operating System :: MacOS",
25
+ "Topic :: Scientific/Engineering",
26
+ "Topic :: Software Development :: Libraries :: Java Libraries",
27
+ "Topic :: Software Development :: Libraries :: Python Modules",
28
+ "Topic :: Utilities",
29
+ ]
30
+
31
+ # NB: Keep this in sync with environment.yml AND dev-environment.yml!
32
+ requires-python = ">=3.10"
33
+ dependencies = [
34
+ ]
35
+
36
+ [project.optional-dependencies]
37
+ # NB: Keep this in sync with dev-environment.yml!
38
+ dev = [
39
+ "autopep8",
40
+ "black",
41
+ "build",
42
+ "flake8",
43
+ "flake8-pyproject",
44
+ "flake8-typing-imports",
45
+ "isort",
46
+ "pytest",
47
+ "numpy",
48
+ "toml",
49
+ "validate-pyproject[all]",
50
+ ]
51
+
52
+ [project.urls]
53
+ homepage = "https://github.com/apposed/appose-python"
54
+ documentation = "https://github.com/apposed/appose-python/blob/main/README.md"
55
+ source = "https://github.com/apposed/appose-python"
56
+ download = "https://pypi.org/project/appose-python"
57
+ tracker = "https://github.com/apposed/appose-python/issues"
58
+
59
+ [tool.setuptools]
60
+ package-dir = {"" = "src"}
61
+ include-package-data = true
62
+
63
+ [tool.setuptools.packages.find]
64
+ where = ["src"]
65
+
66
+ # Thanks to Flake8-pyproject, we can configure flake8 here!
67
+ [tool.flake8]
68
+ exclude = ["bin", "build", "dist"]
69
+ extend-ignore = ["E203"]
70
+ # See https://black.readthedocs.io/en/stable/guides/using_black_with_other_tools.html#flake8
71
+ max-line-length = 88
72
+ min_python_version = "3.10"
73
+
74
+ [tool.isort]
75
+ profile = "black"
76
+
77
+ [tool.pytest.ini_options]
78
+ addopts = "-s -p no:faulthandler"
appose-0.1.0/setup.cfg ADDED
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,152 @@
1
+ ###
2
+ # #%L
3
+ # Appose: multi-language interprocess cooperation with shared memory.
4
+ # %%
5
+ # Copyright (C) 2023 Appose developers.
6
+ # %%
7
+ # Redistribution and use in source and binary forms, with or without
8
+ # modification, are permitted provided that the following conditions are met:
9
+ #
10
+ # 1. Redistributions of source code must retain the above copyright notice,
11
+ # this list of conditions and the following disclaimer.
12
+ # 2. Redistributions in binary form must reproduce the above copyright notice,
13
+ # this list of conditions and the following disclaimer in the documentation
14
+ # and/or other materials provided with the distribution.
15
+ #
16
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
20
+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21
+ # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26
+ # POSSIBILITY OF SUCH DAMAGE.
27
+ # #L%
28
+ ###
29
+
30
+ '''
31
+ Appose is a library for interprocess cooperation with shared memory.
32
+ The guiding principles are *simplicity* and *efficiency*.
33
+
34
+ Appose was written to enable **easy execution of Python-based deep learning
35
+ from Java without copying tensors**, but its utility extends beyond that.
36
+ The steps for using Appose are:
37
+
38
+ * Build an *environment* with the dependencies you need.
39
+ * Create a *service* linked to a *worker*, which runs in its own process.
40
+ * Execute scripts on the worker by launching *tasks*.
41
+ * Receive status updates from the task asynchronously via callbacks.
42
+
43
+ ## Examples
44
+
45
+ * TODO - move the below code somewhere linkable, for succinctness here.
46
+
47
+ Here is a very simple example written in Python:
48
+
49
+ import appose
50
+ env = appose.java(vendor="zulu", version="17").build()
51
+ groovy = env.groovy()
52
+ Task task = groovy.task("""
53
+ 5 + 6
54
+ """)
55
+ task.waitFor()
56
+ result = task.outputs.get("result")
57
+ assert 11 == result
58
+
59
+ And here is an example using a few more of Appose's features:
60
+
61
+ import appose
62
+ from time import sleep
63
+
64
+ env = appose.java(vendor="zulu", version="17").build()
65
+ groovy = env.groovy()
66
+ task = groovy.task("""
67
+ // Approximate the golden ratio using the Fibonacci sequence.
68
+ previous = 0
69
+ current = 1
70
+ for (i = 0; i < iterations; i++) {
71
+ if (task.cancelRequested) {
72
+ task.cancel()
73
+ break
74
+ }
75
+ task.status(null, i, iterations)
76
+ v = current
77
+ current += previous
78
+ previous = v
79
+ }
80
+ task.outputs["numer"] = current
81
+ task.outputs["denom"] = previous
82
+ """)
83
+
84
+ def task_listener(event):
85
+ match event.responseType:
86
+ case UPDATE:
87
+ print(f"Progress {task.current}/{task.maximum}")
88
+ case COMPLETION:
89
+ numer = task.outputs["numer"]
90
+ denom = task.outputs["denom"]
91
+ ratio = numer / denom
92
+ print(f"Task complete. Result: {numer}/{denom} =~ {ratio}");
93
+ case CANCELATION:
94
+ print("Task canceled")
95
+ case FAILURE:
96
+ print(f"Task failed: {task.error}")
97
+
98
+ task.listen(task_listener)
99
+
100
+ task.start()
101
+ sleep(1)
102
+ if not task.status.isFinished():
103
+ # Task is taking too long; request a cancelation.
104
+ task.cancel()
105
+
106
+ task.waitFor()
107
+
108
+ Of course, the above examples could have been done all in Python. But
109
+ hopefully they hint at the possibilities of easy cross-language integration.
110
+
111
+ ## Workers
112
+
113
+ A *worker* is a separate process created by Appose to do asynchronous
114
+ computation on behalf of the calling process. The calling process interacts
115
+ with a worker via its associated *service*.
116
+
117
+ Appose comes with built-in support for two worker implementations:
118
+ `python_worker` to run Python scripts, and `GroovyWorker` to run Groovy
119
+ scripts. These workers can be created easily by invoking the environment
120
+ object's `python()` and `groovy()` methods respectively.
121
+
122
+ But Appose is compatible with any program that abides by the
123
+ *Appose worker process contract*:
124
+
125
+ 1. The worker must accept requests in Appose's request format on its
126
+ standard input (stdin) stream.
127
+ 2. The worker must issue responses in Appose's response format on its
128
+ standard output (stdout) stream.
129
+
130
+ TODO - write up the request and response formats in detail here!
131
+ JSON, one line per request/response.
132
+ '''
133
+
134
+ from pathlib import Path
135
+
136
+ from .environment import Builder, Environment
137
+
138
+
139
+ def base(directory: Path) -> Builder:
140
+ return Builder().base(directory)
141
+
142
+
143
+ def java(vendor: str, version: str) -> Builder:
144
+ return Builder().java(vendor=vendor, version=version)
145
+
146
+
147
+ def conda(environment_yaml: Path) -> Builder:
148
+ return Builder().conda(environment_yaml=environment_yaml)
149
+
150
+
151
+ def system(directory: Path = Path(".")) -> Environment:
152
+ return Builder().base(directory).use_system_path().build()