Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add APIs for working with Stardog Cloud public API #176

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

noahgorstein
Copy link
Member

@noahgorstein noahgorstein commented Oct 22, 2024

  • Adds stardog.cloud subpackage containing modules for working with the Stardog Cloud API
    • The main entrypoint for interacting with Stardog Cloud is creating and using either the synchronous stardog.cloud.client.Client or asynchronous stardog.cloud.client.AsyncClient.
    • The design I'm after is that the client's have "services" attached to them like VoiceboxApp which is the entrypoint for working with Voicebox. This pattern should be able to be extended if and when we extend the public api to contain non voicebox related apis.
    • Adds docs for working with Stardog Cloud/Voicebox. See https://github.com/stardog-union/pystardog/blob/cloud-api/docs/source/stardog.cloud.rst

Example using synchronous client:

import json
import os
import time

from stardog.cloud import Client
from stardog.cloud.exceptions import RateLimitExceededException, StardogCloudException

app_api_token = os.getenv("VOICEBOX_APP_TOKEN")

try:
    results = {}
    with Client(base_url="https://portal.stardoglabs.com/api") as client:
        program_start = time.time()
        app = client.voicebox_app(
            app_api_token=app_api_token, client_id="your-client-id"
        )
        for i in range(2):
            start = time.time()
            response = app.ask(question="How many sensors are there?")
            end = time.time()
            results[i] = {**response.model_dump(), "response_time": f"{end-start:.2f}"}
        program_end = time.time()
        print(json.dumps(results, indent=2))
        print(f"Total time taken: {program_end-program_start:.2f}")

except RateLimitExceededException as e:
    print("Rate limit error.")
except StardogCloudException as e:
    print(f"Error occurred: {e}")

Output:

{
  "0": {
    "content": "There are **27** sensors.",
    "conversation_id": "b714010d-a244-4268-bd59-ade25c37d0b3",
    "message_id": "634fa80d-20c6-4f9f-b104-29e3b0956cbf",
    "interpreted_question": "How many sensors are there?",
    "sparql_query": "# How many sensors are there?\n\nSELECT DISTINCT (COUNT( ?sensor0) AS  ?sensorCount) \nWHERE {\n   ?sensor0 a scm:Sensor . \n}",
    "response_time": "2.45"
  },
  "1": {
    "content": "There are **27** sensors.",
    "conversation_id": "51cbbf18-7d2f-4621-854b-0d5f49f6c13e",
    "message_id": "c134eb1c-850a-4ff2-a34a-fed194fe83ac",
    "interpreted_question": "How many sensors are there?",
    "sparql_query": "# How many sensors are there?\n\nSELECT DISTINCT (COUNT( ?sensor0) AS  ?sensorCount) \nWHERE {\n   ?sensor0 a scm:Sensor . \n}",
    "response_time": "2.01"
  }
}
Total time taken: 4.45

Example Using asynchronous AsyncClient:

import asyncio
import json
import os
import time

from stardog.cloud import AsyncClient
from stardog.cloud.exceptions import RateLimitExceededException, StardogCloudException
from stardog.cloud.voicebox import VoiceboxApp

app_api_token = os.getenv("VOICEBOX_APP_TOKEN")

results = {}


async def ask_and_persist(app: VoiceboxApp, index: int, question: str):
    start = time.time()
    answer = await app.async_ask(question)
    print(answer)
    end = time.time()
    results[index] = {**answer.model_dump(), "response_time": f"{end-start:.2f}"}


async def benchmark():
    try:
        async with AsyncClient(base_url="https://portal.stardoglabs.com/api") as client:
            app = client.voicebox_app(
                app_api_token=app_api_token, client_id="your-client-id"
            )
            tasks = [
                ask_and_persist(app, i, "How many sensors are there?") for i in range(2)
            ]
            program_start = time.time()
            await asyncio.gather(*tasks)
            program_end = time.time()
            print(json.dumps(results, indent=2))
            print(f"Total time taken: {program_end-program_start:.2f}")

    except RateLimitExceededException as e:
        print("Rate limit error.")
    except StardogCloudException as e:
        print(f"Error occurred: {e}")


asyncio.run(benchmark())

Output:

{
  "0": {
    "content": "There are **27** sensors.",
    "conversation_id": "c8e583d8-d5cd-4ea9-97a5-9c6055f64719",
    "message_id": "054c6c99-58c8-42b8-9366-45b1fcf8d728",
    "interpreted_question": "How many sensors are there?",
    "sparql_query": "# How many sensors are there?\n\nSELECT DISTINCT (COUNT( ?sensor0) AS  ?sensorCount) \nWHERE {\n   ?sensor0 a scm:Sensor . \n}",
    "response_time": "2.66"
  },
  "1": {
    "content": "There are **27** sensors.",
    "conversation_id": "22459fd5-35ef-44c4-80cd-26b5a71eb7c1",
    "message_id": "a30683d2-9535-4d57-a957-df25894d30f5",
    "interpreted_question": "How many sensors are there?",
    "sparql_query": "# How many sensors are there?\n\nSELECT DISTINCT (COUNT( ?sensor0) AS  ?sensorCount) \nWHERE {\n   ?sensor0 a scm:Sensor . \n}",
    "response_time": "2.66"
  }
}
Total time taken: 2.67

TODO: need to add tests

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant