Skip to content

Instantly share code, notes, and snippets.

@oeway
Last active Jul 17, 2022
Embed
What would you like to do?

Hypha

Hypha is a server software for creating computational platforms consists of computational and user interface components.

Hypha server act as a hub for connecting different components through imjoy-rpc.

Installation

pip install hypha

Usage

Start the server

Start the hypha server with the following command:

python3 -m hypha.server --host=0.0.0.0 --port=9000

To test it, you should be able to visit http://localhost:9000 and see the version of the hypha server.

In addition to run your own server, you can also use our public testing server: https://ai.imjoy.io

Connect from a client

We currently provide native support for both Python and Javascript client, for other languages, you can use access services using the built-in HTTP proxy of Hypha.

Keep the above server running, and now you can connect to it with the hypha module under imjoy-rpc in a client script. You can either register a service or use an existing service.

Register a service

In Python, you can install the imjoy-rpc library:

pip install imjoy-rpc

Here is a complete client example in Python, you can save the following content as hello-world-worker.py and start the server via python hello-world-worker.py:

import asyncio
from imjoy_rpc.hypha import connect_to_server

async def start_server(server_url):
    server = await connect_to_server({"server_url": server_url})
    
    def hello(name):
        print("Hello " + name)
        return "Hello " + name

    await server.register_service({
        "name": "Hello World",
        "id": "hello-world",
        "config": {
            "visibility": "public"
        },
        "hello": hello
    })
    
    print(f"hello world service regisered at workspace: {api.config.workspace}")
    print(f"Test it with the http proxy: {server_url}/{api.config.workspace}/services/hello-world/hello?name=John")

if __name__ == "__main__":
    server_url = "http://localhost:9000"
    loop = asyncio.get_event_loop()
    loop.create_task(start_server(server_url))
    loop.run_forever()

You don't need to run the client script on the same server, just make sure you change the corresponding server_url (to an URL with the external ip or domain name of the server) if you try to connect to the server from another computer.

Using the service

If you keep the above python service running, you can also connect from either a Python client or Javascript client (on the same or a different host):

In Python:

pip install imjoy-rpc
import asyncio
from imjoy_rpc.hypha import connect_to_server

async def main():
    server = await connect_to_server({"server_url":  "http://localhost:9000"})

    # get an existing service
    # since hello-world is registered as a public service, we can access it with only the name "hello-world"
    svc = await server.get_service("hello-world")
    ret = await svc.hello("John")
    print(ret)

asyncio.run(main())

In Javascript:

Make sure you load the imjoy-rpc client:

<script src="https://cdn.jsdelivr.net/npm/imjoy-rpc@0.5.6/dist/hypha-rpc-websocket.min.js"></script>

Then in a javascript you can do:

async function main(){
    const server = await hyphaWebsocketClient.connectToServer({"server_url": "http://localhost:9000"})
    const svc = await server.getService("hello-world")
    const ret = await svc.hello("John")
    console.log(ret)
}

Service Authorization

In the above example, we registered a public service (config.visibility = "public") which can be access by any clients. There are two ways for providing authorization if you want to limit the service access to a subset of the client.

  1. Connecting to the same workspace. In this case, we can set config.visibility to "private", the authorization is achived by generating a token from the client which registered the service (via server.config.workspace and server.generate_token()), and another client can connect to the same workspace using the token (connect_to_server({"workspace": xxxx, "token": xxxx, "server_url": xxxx})).
  2. Using user context. When registering a service, set config.require_context to True and config.visibility to "public" (you can also set config.visibility to "private" if yo want to limit the access for clients from the same workspace). Each of the service functions will need to accept a keyword argument called context. For each service function call the server will be responsible to providing the context information containing user. Each service function can then check whether the context.user.id is allowed to access the service. On the client which uses the service, it need to login and generate a token from https://ai.imjoy.io/apps/built-in/account-manager.html. The token is then used in connect_to_server({"token": xxxx, "server_url": xxxx}).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment