Skip to content

Commit 5abd91c

Browse files
authored
Fix package name (#29)
* Rename the package name to "transformers_js_py" * Create a `transformers_js` module as an alias * Update a dev script
1 parent 0a855bb commit 5abd91c

File tree

10 files changed

+121
-111
lines changed

10 files changed

+121
-111
lines changed

README.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ let out = await pipe('I love transformers!');
3535
<td>
3636

3737
```python
38-
from transformers_js import import_transformers_js
38+
from transformers_js_py import import_transformers_js
3939

4040
transformers = await import_transformers_js()
4141
pipeline = transformers.pipeline
@@ -64,7 +64,7 @@ See the [Transformers.js document](https://github.com/xenova/transformers.js/) f
6464
```python
6565
%pip install transformers_js_py
6666

67-
from transformers_js import import_transformers_js
67+
from transformers_js_py import import_transformers_js
6868

6969
transformers = await import_transformers_js()
7070
pipeline = transformers.pipeline
@@ -85,7 +85,7 @@ print(out)
8585
```python
8686
import streamlit as st
8787

88-
from transformers_js import import_transformers_js
88+
from transformers_js_py import import_transformers_js
8989

9090
st.title("Sentiment analysis")
9191

@@ -137,7 +137,7 @@ transformers_js_py
137137

138138
<gradio-file name="app.py" entrypoint>
139139
import gradio as gr
140-
from transformers_js import import_transformers_js
140+
from transformers_js_py import import_transformers_js
141141

142142
transformers = await import_transformers_js()
143143
pipeline = transformers.pipeline
@@ -169,7 +169,7 @@ For more details about Gradio-lite, please read [Gradio-Lite: Serverless Gradio
169169

170170
```python
171171
from shiny import App, render, ui
172-
from transformers_js import import_transformers_js
172+
from transformers_js_py import import_transformers_js
173173

174174
app_ui = ui.page_fluid(
175175
ui.input_text("text", "Text input", placeholder="Enter text"),
@@ -218,7 +218,7 @@ app = App(app_ui, server, debug=True)
218218
</py-config>
219219
<py-script>
220220
import asyncio
221-
from transformers_js import import_transformers_js
221+
from transformers_js_py import import_transformers_js
222222

223223
text_input = Element("text-input")
224224

@@ -252,7 +252,7 @@ With [HoloViz Panel](https://panel.holoviz.org) you develop your app on your lap
252252
Install the requirements
253253

254254
```bash
255-
pip install panel transformers_js_py
255+
pip install panel transformers_js_py
256256
```
257257

258258
Create the **app.py** file in your favorite editor or IDE.
@@ -264,7 +264,7 @@ pn.extension(sizing_mode="stretch_width", design="material")
264264

265265
@pn.cache
266266
async def _get_pipeline(model="sentiment-analysis"):
267-
from transformers_js import import_transformers_js
267+
from transformers_js_py import import_transformers_js
268268
transformers = await import_transformers_js()
269269
return await transformers.pipeline(model)
270270

@@ -315,7 +315,7 @@ pn.extension(design="material")
315315

316316
@pn.cache
317317
async def _get_pipeline(model):
318-
from transformers_js import import_transformers_js
318+
from transformers_js_py import import_transformers_js
319319
transformers = await import_transformers_js()
320320
return await transformers.pipeline(model)
321321

pyodide-e2e/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"scripts": {
77
"dev": "run-p dev:*",
88
"dev:front": "vite",
9-
"dev:python": "chokidar \"../transformers_js/**/*.py\" --initial -c \"cd .. && poetry build\"",
9+
"dev:python": "chokidar \"../transformers_js_py/**/*.py\" \"../transformers_js/**/*.py\" --initial -c \"cd .. && poetry build\"",
1010
"build": "tsc && vite build",
1111
"preview": "vite preview",
1212
"test": "vitest"

pyodide-e2e/src/main.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ async function main() {
1212
await micropip.install(wheelUrl);
1313

1414
await pyodide.runPythonAsync(`
15-
from transformers_js import import_transformers_js
15+
from transformers_js_py import import_transformers_js
1616
transformers = await import_transformers_js()
1717
1818
pipeline = transformers.pipeline

pyodide-e2e/src/tests/pipeline.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ suite("transformers.pipeline", () => {
2020
});
2121

2222
await pyodide.runPythonAsync(`
23-
from transformers_js import import_transformers_js, as_url
23+
from transformers_js_py import import_transformers_js, as_url
2424
2525
transformers = await import_transformers_js()
2626
pipeline = transformers.pipeline

pyodide-e2e/src/tests/utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export async function setupPyodideForTest(): Promise<PyodideInterface> {
2626
}
2727

2828
await pyodide.runPythonAsync(`
29-
from transformers_js import import_transformers_js
29+
from transformers_js_py import import_transformers_js
3030
transformers = await import_transformers_js()
3131
`)
3232

pyodide-e2e/src/worker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ async function main() {
1616
await micropip.install(wheelUrl);
1717

1818
await pyodide.runPythonAsync(`
19-
from transformers_js import import_transformers_js
19+
from transformers_js_py import import_transformers_js
2020
transformers = await import_transformers_js()
2121
2222
pipeline = transformers.pipeline

pyproject.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ description = ""
55
authors = ["Yuichiro Tachibana (Tsuchiya) <[email protected]>"]
66
license = "Apache-2.0"
77
readme = "README.md"
8-
packages = [{include = "transformers_js"}]
8+
packages = [
9+
{include = "transformers_js_py"},
10+
{include = "transformers_js"},
11+
]
912
repository = "https://github.com/whitphx/transformers.js.py"
1013

1114
[tool.poetry.dependencies]

transformers_js/__init__.py

Lines changed: 6 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -1,97 +1,7 @@
1-
from typing import Any
1+
"""
2+
This module was created as an alias for `transformers_js_py`
3+
due to a historical reason that the original package name was `transformers_js`.
4+
Ref: https://github.com/whitphx/transformers.js.py/issues/26
5+
"""
26

3-
import js
4-
import pyodide.code
5-
import pyodide.ffi
6-
import pyodide.webloop
7-
8-
from .url import as_url
9-
10-
11-
class TjsModuleProxy:
12-
def __init__(self, js_obj: pyodide.ffi.JsProxy):
13-
if not isinstance(js_obj, pyodide.ffi.JsProxy) or js_obj.typeof != "object":
14-
raise TypeError("js_obj must be a JS module object")
15-
self.js_obj = js_obj
16-
17-
def __getattr__(self, name: str) -> Any:
18-
res = getattr(self.js_obj, name)
19-
if isinstance(res, pyodide.ffi.JsProxy):
20-
return TjsProxy(res)
21-
return res
22-
23-
def __repr__(self) -> str:
24-
return "TjsModuleProxy({})".format(", ".join(self.js_obj.object_keys()))
25-
26-
27-
class TjsProxy:
28-
def __init__(self, js_obj: pyodide.ffi.JsProxy):
29-
self._js_obj = js_obj
30-
31-
def __call__(self, *args: Any, **kwds: Any) -> Any:
32-
if hasattr(self._js_obj, "_call"):
33-
args = pyodide.ffi.to_js(args)
34-
kwds = pyodide.ffi.to_js(kwds)
35-
36-
# Transformers.js uses a custom _call() method
37-
# to make the JS classes callable.
38-
# https://github.com/xenova/transformers.js/blob/2.4.1/src/utils/core.js#L45-L77
39-
res = self._js_obj._call(*args, **kwds)
40-
else:
41-
res = self._js_obj(*args, **kwds)
42-
43-
return wrap_or_unwrap_proxy_object(res)
44-
45-
def __getattr__(self, name: str) -> Any:
46-
res = getattr(self._js_obj, name)
47-
return wrap_or_unwrap_proxy_object(res)
48-
49-
def __getitem__(self, key: Any) -> Any:
50-
res = self._js_obj[key]
51-
return wrap_or_unwrap_proxy_object(res)
52-
53-
def __setitem__(self, key: Any, value: Any) -> None:
54-
self._js_obj[key] = value
55-
56-
def __setattr__(self, __name: str, __value: Any) -> None:
57-
if __name == "_js_obj":
58-
super().__setattr__("_js_obj", __value)
59-
else:
60-
setattr(self._js_obj, __name, __value)
61-
62-
63-
def wrap_or_unwrap_proxy_object(obj):
64-
if isinstance(obj, pyodide.ffi.JsProxy):
65-
if obj.typeof == "object":
66-
return obj.to_py()
67-
return TjsProxy(obj)
68-
elif isinstance(obj, pyodide.webloop.PyodideFuture):
69-
return obj.then(wrap_or_unwrap_proxy_object)
70-
return obj
71-
72-
73-
async def import_transformers_js(version: str = "latest"):
74-
pyodide.code.run_js(
75-
"""
76-
async function loadTransformersJs(version) {
77-
const isBrowserMainThread = typeof window !== 'undefined';
78-
const isWorker = typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope;
79-
const isBrowser = isBrowserMainThread || isWorker;
80-
const transformers = await import(isBrowser ? 'https://cdn.jsdelivr.net/npm/@xenova/transformers@' + version : '@xenova/transformers');
81-
82-
transformers.env.allowLocalModels = false;
83-
84-
globalThis._transformers = { // Convert a module to an object.
85-
...transformers,
86-
};
87-
}
88-
""" # noqa: E501
89-
)
90-
loadTransformersJsFn = js.loadTransformersJs
91-
await loadTransformersJsFn(version)
92-
93-
transformers = js._transformers
94-
return TjsModuleProxy(transformers)
95-
96-
97-
__all__ = ["as_url", "import_transformers_js"]
7+
from transformers_js_py import * # noqa: F401, F403

transformers_js_py/__init__.py

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
from typing import Any
2+
3+
import js
4+
import pyodide.code
5+
import pyodide.ffi
6+
import pyodide.webloop
7+
8+
from .url import as_url
9+
10+
11+
class TjsModuleProxy:
12+
def __init__(self, js_obj: pyodide.ffi.JsProxy):
13+
if not isinstance(js_obj, pyodide.ffi.JsProxy) or js_obj.typeof != "object":
14+
raise TypeError("js_obj must be a JS module object")
15+
self.js_obj = js_obj
16+
17+
def __getattr__(self, name: str) -> Any:
18+
res = getattr(self.js_obj, name)
19+
if isinstance(res, pyodide.ffi.JsProxy):
20+
return TjsProxy(res)
21+
return res
22+
23+
def __repr__(self) -> str:
24+
return "TjsModuleProxy({})".format(", ".join(self.js_obj.object_keys()))
25+
26+
27+
class TjsProxy:
28+
def __init__(self, js_obj: pyodide.ffi.JsProxy):
29+
self._js_obj = js_obj
30+
31+
def __call__(self, *args: Any, **kwds: Any) -> Any:
32+
if hasattr(self._js_obj, "_call"):
33+
args = pyodide.ffi.to_js(args)
34+
kwds = pyodide.ffi.to_js(kwds)
35+
36+
# Transformers.js uses a custom _call() method
37+
# to make the JS classes callable.
38+
# https://github.com/xenova/transformers.js/blob/2.4.1/src/utils/core.js#L45-L77
39+
res = self._js_obj._call(*args, **kwds)
40+
else:
41+
res = self._js_obj(*args, **kwds)
42+
43+
return wrap_or_unwrap_proxy_object(res)
44+
45+
def __getattr__(self, name: str) -> Any:
46+
res = getattr(self._js_obj, name)
47+
return wrap_or_unwrap_proxy_object(res)
48+
49+
def __getitem__(self, key: Any) -> Any:
50+
res = self._js_obj[key]
51+
return wrap_or_unwrap_proxy_object(res)
52+
53+
def __setitem__(self, key: Any, value: Any) -> None:
54+
self._js_obj[key] = value
55+
56+
def __setattr__(self, __name: str, __value: Any) -> None:
57+
if __name == "_js_obj":
58+
super().__setattr__("_js_obj", __value)
59+
else:
60+
setattr(self._js_obj, __name, __value)
61+
62+
63+
def wrap_or_unwrap_proxy_object(obj):
64+
if isinstance(obj, pyodide.ffi.JsProxy):
65+
if obj.typeof == "object":
66+
return obj.to_py()
67+
return TjsProxy(obj)
68+
elif isinstance(obj, pyodide.webloop.PyodideFuture):
69+
return obj.then(wrap_or_unwrap_proxy_object)
70+
return obj
71+
72+
73+
async def import_transformers_js(version: str = "latest"):
74+
pyodide.code.run_js(
75+
"""
76+
async function loadTransformersJs(version) {
77+
const isBrowserMainThread = typeof window !== 'undefined';
78+
const isWorker = typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope;
79+
const isBrowser = isBrowserMainThread || isWorker;
80+
const transformers = await import(isBrowser ? 'https://cdn.jsdelivr.net/npm/@xenova/transformers@' + version : '@xenova/transformers');
81+
82+
transformers.env.allowLocalModels = false;
83+
84+
globalThis._transformers = { // Convert a module to an object.
85+
...transformers,
86+
};
87+
}
88+
""" # noqa: E501
89+
)
90+
loadTransformersJsFn = js.loadTransformersJs
91+
await loadTransformersJsFn(version)
92+
93+
transformers = js._transformers
94+
return TjsModuleProxy(transformers)
95+
96+
97+
__all__ = ["as_url", "import_transformers_js"]
File renamed without changes.

0 commit comments

Comments
 (0)