From 502b7b6a438de8b02b4262819c99f35ca4e29a0b Mon Sep 17 00:00:00 2001 From: AHReccese Date: Tue, 19 Nov 2024 19:48:02 -0500 Subject: [PATCH 1/6] add ability to select different protocols for the communication medium in `README.md` --- README.md | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 7b77623e..5efebf26 100644 --- a/README.md +++ b/README.md @@ -157,13 +157,15 @@ You can easily serve your ML model from a remote server using `ML streaming` fea ⚠️ In order to use `ML streaming` feature, make sure you've installed the `streaming` mode of PyMilo +You can choose either `REST` or `WebSocket` as the communication medium protocol. + #### Server -Let's assume you are in the remote server and you want to import the exported JSON file and start serving your model! +Let's assume you are in the remote server and you want to import the exported JSON file and start serving your model through `REST` protocol! ```pycon >>> from pymilo import Import ->>> from pymilo.streaming import PymiloServer +>>> from pymilo.streaming import PymiloServer, CommunicationProtocol >>> my_model = Import("model.json").to_model() ->>> communicator = PymiloServer(model=my_model, port=8000).communicator +>>> communicator = PymiloServer(model=my_model, port=8000, communication_protocol= CommunicationProtocol["REST"]).communicator >>> communicator.run() ``` Now `PymiloServer` runs on port `8000` and exposes REST API to `upload`, `download` and retrieve **attributes** either **data attributes** like `model._coef` or **method attributes** like `model.predict(x_test)`. @@ -171,13 +173,17 @@ Now `PymiloServer` runs on port `8000` and exposes REST API to `upload`, `downlo #### Client By using `PymiloClient` you can easily connect to the remote `PymiloServer` and execute any functionalities that the given ML model has, let's say you want to run `predict` function on your remote ML model and get the result: ```pycon ->>> from pymilo.streaming import PymiloClient ->>> pymilo_client = PymiloClient(mode=PymiloClient.Mode.LOCAL, server_url="SERVER_URL") +>>> from pymilo.streaming import PymiloClient, CommunicationProtocol +>>> pymilo_client = PymiloClient( +>>> mode=PymiloClient.Mode.LOCAL, +>>> server_url="SERVER_URL", +>>> communication_protocol=CommunicationProtocol["REST"], +>>> ) >>> pymilo_client.toggle_mode(PymiloClient.Mode.DELEGATE) >>> result = pymilo_client.predict(x_test) ``` -ℹ️ If you've deployed `PymiloServer` locally (on port `8000` for instance), then `SERVER_URL` would be `http://127.0.0.1:8000` +ℹ️ If you've deployed `PymiloServer` locally (on port `8000` for instance), then `SERVER_URL` would be `http://127.0.0.1:8000` or `ws://127.0.0.1:8000` based on the selected protocol for the communication medium. You can also download the remote ML model into your local and execute functions locally on your model. From 9c158f6493b96a8a0fa097c6d0a298a691744e10 Mon Sep 17 00:00:00 2001 From: AHReccese Date: Tue, 19 Nov 2024 19:48:44 -0500 Subject: [PATCH 2/6] `CHANGELOG.md` updated --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f1138c6c..cbb0fc6f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - PyMilo exception types added in `pymilo/exceptions/__init__.py` - PyMilo exception types added in `pymilo/__init__.py` ### Changed +- `README.md` updated - `communication_protocol` parameter added to `PyMiloClient` class - `communication_protocol` parameter added to `PyMiloServer` class - `ML Streaming` testcases updated to support protocol selection From 9c48368e7448b257e663da7f3dd5e3b76e3d8c9d Mon Sep 17 00:00:00 2001 From: AHReccese Date: Tue, 19 Nov 2024 19:59:01 -0500 Subject: [PATCH 3/6] enhance code snippets --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5efebf26..9838cc51 100644 --- a/README.md +++ b/README.md @@ -165,7 +165,11 @@ Let's assume you are in the remote server and you want to import the exported JS >>> from pymilo import Import >>> from pymilo.streaming import PymiloServer, CommunicationProtocol >>> my_model = Import("model.json").to_model() ->>> communicator = PymiloServer(model=my_model, port=8000, communication_protocol= CommunicationProtocol["REST"]).communicator +>>> communicator = PymiloServer( +>>> model=my_model, +>>> port=8000, +>>> communication_protocol=CommunicationProtocol["REST"], +>>> ).communicator >>> communicator.run() ``` Now `PymiloServer` runs on port `8000` and exposes REST API to `upload`, `download` and retrieve **attributes** either **data attributes** like `model._coef` or **method attributes** like `model.predict(x_test)`. From 0a2a0f2a217239365e21b4e3a67f78662c4acbe5 Mon Sep 17 00:00:00 2001 From: AHReccese Date: Wed, 20 Nov 2024 17:10:51 -0500 Subject: [PATCH 4/6] `CHANGELOG.md` updated --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cbb0fc6f..f1138c6c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,7 +24,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - PyMilo exception types added in `pymilo/exceptions/__init__.py` - PyMilo exception types added in `pymilo/__init__.py` ### Changed -- `README.md` updated - `communication_protocol` parameter added to `PyMiloClient` class - `communication_protocol` parameter added to `PyMiloServer` class - `ML Streaming` testcases updated to support protocol selection From f3ef68d8897bbe913c2d4554532c56d3d5e87932 Mon Sep 17 00:00:00 2001 From: AHReccese Date: Wed, 20 Nov 2024 17:11:45 -0500 Subject: [PATCH 5/6] convert `pycon` code snippets to `python` snippets --- README.md | 84 +++++++++++++++++++++++++++---------------------------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/README.md b/README.md index 9838cc51..cf444367 100644 --- a/README.md +++ b/README.md @@ -80,21 +80,21 @@ PyMilo is an open source Python package that provides a simple, efficient, and s ## Usage ### Import/Export Imagine you want to train a `LinearRegression` model representing this equation: $y = x_0 + 2x_1 + 3$. You will create data points (`X`, `y`) and train your model as follows. -```pycon ->>> import numpy as np ->>> from sklearn.linear_model import LinearRegression ->>> X = np.array([[1, 1], [1, 2], [2, 2], [2, 3]]) ->>> y = np.dot(X, np.array([1, 2])) + 3 - # y = 1 * x_0 + 2 * x_1 + 3 ->>> model = LinearRegression().fit(X, y) ->>> pred = model.predict(np.array([[3, 5]])) +```python +import numpy as np +from sklearn.linear_model import LinearRegression +X = np.array([[1, 1], [1, 2], [2, 2], [2, 3]]) +y = np.dot(X, np.array([1, 2])) + 3 +# y = 1 * x_0 + 2 * x_1 + 3 +model = LinearRegression().fit(X, y) +pred = model.predict(np.array([[3, 5]])) # pred = [16.] (=1 * 3 + 2 * 5 + 3) ``` Using PyMilo `Export` class you can easily serialize and export your trained model into a JSON file. -```pycon ->>> from pymilo import Export ->>> Export(model).save("model.json") +```python +from pymilo import Export +Export(model).save("model.json") ``` You can check out your model as a JSON file now. @@ -142,10 +142,10 @@ You can check out your model as a JSON file now. You can see all the learned parameters of the model in this file and change them if you want. This JSON representation is a transparent version of your model. Now let's load it back. You can do it easily by using PyMilo `Import` class. -```pycon ->>> from pymilo import Import ->>> model = Import("model.json").to_model() ->>> pred = model.predict(np.array([[3, 5]])) +```python +from pymilo import Import +model = Import("model.json").to_model() +pred = model.predict(np.array([[3, 5]])) # pred = [16.] (=1 * 3 + 2 * 5 + 3) ``` This loaded model is exactly the same as the original trained model. @@ -161,30 +161,30 @@ You can choose either `REST` or `WebSocket` as the communication medium protocol #### Server Let's assume you are in the remote server and you want to import the exported JSON file and start serving your model through `REST` protocol! -```pycon ->>> from pymilo import Import ->>> from pymilo.streaming import PymiloServer, CommunicationProtocol ->>> my_model = Import("model.json").to_model() ->>> communicator = PymiloServer( ->>> model=my_model, ->>> port=8000, ->>> communication_protocol=CommunicationProtocol["REST"], ->>> ).communicator ->>> communicator.run() +```python +from pymilo import Import +from pymilo.streaming import PymiloServer, CommunicationProtocol +my_model = Import("model.json").to_model() +communicator = PymiloServer( + model=my_model, + port=8000, + communication_protocol=CommunicationProtocol["REST"], + ).communicator +communicator.run() ``` Now `PymiloServer` runs on port `8000` and exposes REST API to `upload`, `download` and retrieve **attributes** either **data attributes** like `model._coef` or **method attributes** like `model.predict(x_test)`. #### Client By using `PymiloClient` you can easily connect to the remote `PymiloServer` and execute any functionalities that the given ML model has, let's say you want to run `predict` function on your remote ML model and get the result: -```pycon ->>> from pymilo.streaming import PymiloClient, CommunicationProtocol ->>> pymilo_client = PymiloClient( ->>> mode=PymiloClient.Mode.LOCAL, ->>> server_url="SERVER_URL", ->>> communication_protocol=CommunicationProtocol["REST"], ->>> ) ->>> pymilo_client.toggle_mode(PymiloClient.Mode.DELEGATE) ->>> result = pymilo_client.predict(x_test) +```python +from pymilo.streaming import PymiloClient, CommunicationProtocol +pymilo_client = PymiloClient( + mode=PymiloClient.Mode.LOCAL, + server_url="SERVER_URL", + communication_protocol=CommunicationProtocol["REST"], + ) +pymilo_client.toggle_mode(PymiloClient.Mode.DELEGATE) +result = pymilo_client.predict(x_test) ``` ℹ️ If you've deployed `PymiloServer` locally (on port `8000` for instance), then `SERVER_URL` would be `http://127.0.0.1:8000` or `ws://127.0.0.1:8000` based on the selected protocol for the communication medium. @@ -193,18 +193,18 @@ You can also download the remote ML model into your local and execute functions Calling `download` function on `PymiloClient` will sync the local model that `PymiloClient` wraps upon with the remote ML model, and it doesn't save model directly to a file. -```pycon ->>> pymilo_client.download() +```python +pymilo_client.download() ``` If you want to save the ML model to a file in your local, you can use `Export` class. -```pycon ->>> from pymilo import Export ->>> Export(pymilo_client.model).save("model.json") +```python +from pymilo import Export +Export(pymilo_client.model).save("model.json") ``` Now that you've synced the remote model with your local model, you can run functions. -```pycon ->>> pymilo_client.toggle_mode(mode=PymiloClient.Mode.LOCAL) ->>> result = pymilo_client.predict(x_test) +```python +pymilo_client.toggle_mode(mode=PymiloClient.Mode.LOCAL) +result = pymilo_client.predict(x_test) ``` `PymiloClient` wraps around the ML model, either to the local ML model or the remote ML model, and you can work with `PymiloClient` in the exact same way that you did with the ML model, you can run exact same functions with same signature. From 9af86d2d333aeba3895505e96153649301cae2e5 Mon Sep 17 00:00:00 2001 From: AHReccese Date: Wed, 20 Nov 2024 18:22:06 -0500 Subject: [PATCH 6/6] merge with latest state of dev --- dev-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-requirements.txt b/dev-requirements.txt index c4b2d4c8..412c3a72 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -4,7 +4,7 @@ scipy>=0.19.1 uvicorn==0.32.0 fastapi==0.115.5 requests==2.32.3 -pydantic>=1.5.0 +pydantic==1.10 websockets==10.4 setuptools>=40.8.0 vulture>=1.0