Skip to content

Commit

Permalink
Improve get_service and the apps (#648)
Browse files Browse the repository at this point in the history
* Improve get_service and the apps

* Remove python 3.8 support
  • Loading branch information
oeway authored Aug 6, 2024
1 parent 6d8b816 commit 6721c92
Show file tree
Hide file tree
Showing 29 changed files with 361 additions and 491 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.8", "3.9", "3.10", "3.11"]
python-version: ["3.9", "3.10", "3.11", "3.12"]

steps:
- uses: actions/[email protected]
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ Hypha server act as a hub for connecting different components through [hypya-rpc

## Change log

### 0.20.14

- Make `get_service` more restricted to support only service id string, see [migration guide](./docs/migration-guide.md) for more details.
- Clean up http endpoints for the services, now we also support /services/:service_id/:function_name
- Remove local cache of the server apps, we now always use s3 as the primary storage.

### 0.20.12

- New Feature: In order to support large language models' function calling feature, hypha support built-in type annotation. With `hypha-rpc>=0.20.12`, we also support type annotation for the service functions in JSON Schema format. In Python, you can use `Pydantic` or simple python type hint, or directly write the json schema for Javascript service functions. This allows you to specify the inputs spec for functions.
Expand Down
2 changes: 1 addition & 1 deletion docs/CNAME
Original file line number Diff line number Diff line change
@@ -1 +1 @@
ha.amun.ai
docs.amun.ai
2 changes: 1 addition & 1 deletion docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ if __name__ == "__main__":
Include the following script in your HTML file to load the `hypha-rpc` client:

```html
<script src="https://cdn.jsdelivr.net/npm/[email protected].13/dist/hypha-rpc-websocket.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected].14/dist/hypha-rpc-websocket.min.js"></script>
```

Use the following code in JavaScript to connect to the server and access an existing service:
Expand Down
71 changes: 61 additions & 10 deletions docs/migration-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ To connect to the server, instead of installing the `imjoy-rpc` module, you will
pip install -U hypha-rpc # new install
```

We also changed our versioning strategy, we use the same version number for the server and client, so it's easier to match the client and server versions. For example, `hypha-rpc` version `0.20.13` is compatible with Hypha server version `0.20.13`.
We also changed our versioning strategy, we use the same version number for the server and client, so it's easier to match the client and server versions. For example, `hypha-rpc` version `0.20.14` is compatible with Hypha server version `0.20.14`.

#### 2. Change the imports to use `hypha-rpc`

Expand Down Expand Up @@ -60,7 +60,21 @@ async def start_server(server_url):
print(await svc.hello("John"))
```

#### 4. Optionally, annotate functions with JSON schema using Pydantic
#### 4. Changes in getting service

In the new version, we make the argument of `get_service(service_id)` a string (dictionary is not supported anymore).

The full service id format: `{workspace}/{client_id}:{service_id}@{app_id}`. We support the following shorted formats with conversion:

- short service id format: `{service_id}`=>`{current_workspace}/*/{service_id}`, e.g. `await server.get_service("hello-world")`
- service id format with workspace: `{workspace}/{service_id}` => `{workspace}/*/{service_id}`, e.g. `await server.get_service("public/hello-world")`
- service id format with app id: `{service_id}@{app_id}` => `{current_workspace}/*/{service_id}@{app_id}`, e.g. `await server.get_service("hello-world@my-app-id")`
- service id format with client id: `{client_id}:{service_id}` => `{current_workspace}/{client_id}:{service_id}`, e.g. `await server.get_service("my-client-id:hello-world")`
- service id format with client id and app id: `{client_id}:{service_id}@{app_id}` => `{current_workspace}/{client_id}:{service_id}@{app_id}`, e.g. `await server.get_service("my-client-id:hello-world@my-app-id")`

**Note: Instead of return null, the new `get_service()` function will raise error if not found**

#### 5. Optionally, annotate functions with JSON schema using Pydantic

To make your functions more compatible with LLMs, you can optionally use Pydantic to annotate them with JSON schema. This helps in creating well-defined interfaces for your services.

Expand All @@ -69,6 +83,7 @@ We created a tutorial to introduce this new feature: [service type annotation](.
Here is a quick example using Pydantic:

```python
import asyncio
from pydantic import BaseModel, Field
from hypha_rpc.utils.schema import schema_function

Expand All @@ -79,9 +94,27 @@ class UserInfo(BaseModel):
address: str = Field(..., description="Address of the user")

@schema_function
def register_user(user_info: UserInfo) -> str:
async def register_user(user_info: UserInfo) -> str:
"""Register a new user."""
return f"User {user_info.name} registered"


async def main():
server = await connect_to_server({"server_url": "https://hypha.aicell.io"})

svc = await server.register_service({
"name": "User Service",
"id": "user-service",
"config": {
"visibility": "public"
},
"description": "Service for registering users",
"register_user": register_user
})

loop = asyncio.get_event_loop()
loop.create_task(main())
loop.run_forever()
```

### JavaScript
Expand All @@ -91,10 +124,10 @@ def register_user(user_info: UserInfo) -> str:
To connect to the server, instead of using the `imjoy-rpc` module, you will need to use the `hypha-rpc` module. The `hypha-rpc` module is a standalone module that provides the RPC connection to the Hypha server. You can include it in your HTML using a script tag:

```html
<script src="https://cdn.jsdelivr.net/npm/[email protected].13/dist/hypha-rpc-websocket.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected].14/dist/hypha-rpc-websocket.min.js"></script>
```

We also changed our versioning strategy, we use the same version number for the server and client, so it's easier to match the client and server versions. For example, `hypha-rpc` version `0.20.13` is compatible with Hypha server version `0.20.13`.
We also changed our versioning strategy, we use the same version number for the server and client, so it's easier to match the client and server versions. For example, `hypha-rpc` version `0.20.14` is compatible with Hypha server version `0.20.14`.

#### 2. Change the connection method and use camelCase for service function names

Expand All @@ -112,7 +145,7 @@ Here is a suggested list of search and replace operations to update your code:
Here is an example of how the updated code might look:

```html
<script src="https://cdn.jsdelivr.net/npm/[email protected].13/dist/hypha-rpc-websocket.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected].14/dist/hypha-rpc-websocket.min.js"></script>
<script>
async function main(){
const server = await hyphaWebsocketClient.connectToServer({"server_url": "https://hypha.aicell.io"});
Expand All @@ -135,7 +168,23 @@ main();
</script>
```

#### 3. Optionally, manually annotate functions with JSON schema
#### 3. Changes in getting service

**Input Argument Change for `getService`**
In the new version, we make the argument of `getService(serviceId)` a string (object is not supported anymore).

The full service id format: `{workspace}/{clientId}:{serviceId}@{appId}`. We support the following shorted formats with conversion:

- short service id format: `{serviceId}`=>`{currentWorkspace}/*/{serviceId}`, e.g. `await server.getService("hello-world")`
- service id format with workspace: `{workspace}/{serviceId}` => `{workspace}/*/{serviceId}`, e.g. `await server.getService("public/hello-world")`
- service id format with app id: `{serviceId}@{appId}` => `{currentWorkspace}/*/{serviceId}@{appId}`, e.g. `await server.getService("hello-world@my-app-id")`
- service id format with client id: `{clientId}:{serviceId}` => `{currentWorkspace}/{clientId}:{serviceId}`, e.g. `await server.getService("my-client-id:hello-world")`
- service id format with client id and app id: `{clientId}:{serviceId}@{appId}` => `{currentWorkspace}/{clientId}:{serviceId}@{appId}`, e.g. `await server.getService("my-client-id:hello-world@my-app-id")`


**Note: Instead of return null, the new `getService()` function will raise error if not found**

#### 4. Optionally, manually annotate functions with JSON schema

To make your functions more compatible with LLMs, you can optionally annotate them with JSON schema. This helps in creating well-defined interfaces for your services.

Expand All @@ -144,10 +193,12 @@ We created a tutorial to introduce this new feature: [service type annotation](.
Here is a quick example in JavaScript:

```html
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/hypha-rpc-websocket.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/hypha-rpc-websocket.min.js"></script>

<script>
async function main(){
const server = await hyphaWebsocketClient.connectToServer({"server_url": "https://hypha.aicell.io"});
const { connectToServer, schemaFunction } = hyphaWebsocketClient;
const server = await connectToServer({"server_url": "https://hypha.aicell.io"});
function getCurrentWeather(location, unit = "fahrenheit") {
if (location.toLowerCase().includes("tokyo")) {
Expand All @@ -161,7 +212,7 @@ async function main(){
}
}
const getCurrentWeatherAnnotated = hyphaWebsocketClient.schemaFunction(getCurrentWeather, {
const getCurrentWeatherAnnotated = schemaFunction(getCurrentWeather, {
name: "getCurrentWeather",
description: "Get the current weather in a given location",
parameters: {
Expand Down
25 changes: 13 additions & 12 deletions docs/service-type-annotation.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,7 @@ Manual JSON schema generation can be tedious, so we provide decorators `schema_f
Here is an example of using the `schema_function` decorator with Pydantic models:

```python
from

pydantic import BaseModel, Field
from pydantic import BaseModel, Field
from hypha_rpc.utils.schema import schema_function

class UserInfo(BaseModel):
Expand All @@ -80,6 +78,7 @@ Now, let's create a service in a Python client, then connect to it with another
```python
from pydantic import BaseModel, Field
from hypha_rpc import connect_to_server
from hypha_rpc.utils.schema import schema_function

async def main():
server = await connect_to_server({"server_url": "https://hypha.aicell.io"})
Expand All @@ -101,10 +100,11 @@ async def main():
"register_user": register_user
})

import asyncio
loop = asyncio.get_event_loop()
loop.create_task(main())
loop.run_forever()
if __name__ == "__main__":
import asyncio
loop = asyncio.get_event_loop()
loop.create_task(main())
loop.run_forever()
```

**Python Client: Service Usage**
Expand All @@ -124,16 +124,17 @@ async def main():
})
print(result)

import asyncio
loop = asyncio.get_event_loop()
loop.create_task(main())
loop.run_forever()
if __name__ == "__main__":
import asyncio
loop = asyncio.get_event_loop()
loop.create_task(main())
loop.run_forever()
```

**JavaScript Client: Service Usage**

```html
<script src="https://cdn.jsdelivr.net/npm/[email protected].13/dist/hypha-rpc-websocket.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected].14/dist/hypha-rpc-websocket.min.js"></script>
<script>
async function main() {
const server = await hyphaWebsocketClient.connectToServer({"server_url": "https://hypha.aicell.io"});
Expand Down
2 changes: 1 addition & 1 deletion hypha/VERSION
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"version": "0.20.13.post1"
"version": "0.20.14"
}
Loading

0 comments on commit 6721c92

Please sign in to comment.