diff --git a/apps/opik-backend/src/main/resources/openapi_template.yml b/apps/opik-backend/src/main/resources/openapi_template.yml index 91d611ed1b..62a2a981cb 100644 --- a/apps/opik-backend/src/main/resources/openapi_template.yml +++ b/apps/opik-backend/src/main/resources/openapi_template.yml @@ -1,20 +1,38 @@ openapi: 3.1.0 info : - description : "APIs" + description : | + The Opik REST API is currently in beta and subject to change. If you have any questions or feedback about the APIs, please reach out on GitHub: https://github.com/comet-ml/opik. + + All of the methods listed in this documentation are used by either the SDK or the UI to interact with the Opik server. As a result, + the methods have been optimized for these use-cases in mind. If you are looking for a method that is not listed above, please create + and issue on GitHub or raise a PR! + + Opik includes two main deployment options that results in slightly different API usage: + + - **Self-hosted Opik instance:** You will simply need to specify the URL as `http://localhost:5173/api/` or similar. This is the default option for the docs. + - **Opik Cloud:** You will need to specify the Opik API Key and Opik Workspace in the header. The format of the header should be: + + ``` + { + "Comet-Workspace": "your-workspace-name", + "authorization": "your-api-key" + } + ``` + + Do take note here that the authorization header value does not include the `Bearer ` prefix. To switch to using the Opik Cloud in the documentation, you can + click on the edit button displayed when hovering over the `Base URL` displayed on the right hand side of the docs. + version : "1.0.0" - title : "APIs" + title : "Opik REST API" contact : - name : "Support" - email : "support@comet.com" + name : "Github Repository" + url : "https://github.com/comet-ml/opik" license : name : "Apache 2.0" url : "http://www.apache.org/licenses/LICENSE-2.0.html" servers : - - url : "{basePath}/{apiVersion}" - description : "Local server" - variables: - basePath: - default: "http://localhost:8080" - apiVersion: - default: "v1" \ No newline at end of file + - url: http://localhost:5173/api + description: Local server + - url: https://www.comet.com/opik/api + description: Opik Cloud diff --git a/apps/opik-frontend/Dockerfile b/apps/opik-frontend/Dockerfile index 3540ca0901..dacf61c131 100644 --- a/apps/opik-frontend/Dockerfile +++ b/apps/opik-frontend/Dockerfile @@ -21,7 +21,9 @@ FROM nginx:alpine # Copy the built files from the builder stage COPY --from=builder /opt/frontend/dist /usr/share/nginx/html +RUN sed -i '/access_log.*main/d' /etc/nginx/nginx.conf + EXPOSE 5173 # Start Nginx -CMD ["nginx", "-g", "daemon off;"] \ No newline at end of file +CMD ["nginx", "-g", "daemon off;"] diff --git a/apps/opik-frontend/src/lib/utils.ts b/apps/opik-frontend/src/lib/utils.ts index 0d2d86d013..3afa0aaa65 100644 --- a/apps/opik-frontend/src/lib/utils.ts +++ b/apps/opik-frontend/src/lib/utils.ts @@ -8,7 +8,7 @@ const BASE_COMET_URL = import.meta.env.VITE_BASE_COMET_URL; export const buildDocsUrl = (path: string, hash: string = "") => { const url = BASE_COMET_URL - ? `${BASE_COMET_URL}/docs/opik` + ? `${BASE_COMET_URL}docs/opik` : "https://comet.com/docs/opik"; return `${url}${path}?from=llm${hash}`; diff --git a/sdks/python/src/opik/message_processing/streamer.py b/sdks/python/src/opik/message_processing/streamer.py index 4c5c0dac1c..7f722329b3 100644 --- a/sdks/python/src/opik/message_processing/streamer.py +++ b/sdks/python/src/opik/message_processing/streamer.py @@ -1,11 +1,16 @@ import queue import threading +import logging from typing import Any, List, Optional from . import messages, queue_consumer from .. import synchronization from .batching import batch_manager +from .. import url_helpers + +LOGGER = logging.getLogger(__name__) + class Streamer: def __init__( @@ -26,6 +31,9 @@ def __init__( if self._batch_manager is not None: self._batch_manager.start() + # Used to know when to display the project URL + self._project_name_most_recent_trace: Optional[str] = None + def put(self, message: messages.BaseMessage) -> None: with self._lock: if self._drain: @@ -39,6 +47,19 @@ def put(self, message: messages.BaseMessage) -> None: else: self._message_queue.put(message) + # Display message in console + if isinstance(message, messages.CreateTraceMessage): + projects_url = url_helpers.get_projects_url() + project_name = message.project_name + if ( + self._project_name_most_recent_trace is None + or self._project_name_most_recent_trace != project_name + ): + LOGGER.info( + f'Started logging traces to the "{project_name}" project at {projects_url}.' + ) + self._project_name_most_recent_trace = project_name + def close(self, timeout: Optional[int]) -> bool: """ Stops data sending threads diff --git a/sdks/python/src/opik/url_helpers.py b/sdks/python/src/opik/url_helpers.py index e786840080..463c329c28 100644 --- a/sdks/python/src/opik/url_helpers.py +++ b/sdks/python/src/opik/url_helpers.py @@ -6,3 +6,10 @@ def get_ui_url() -> str: opik_url_override = config.url_override return opik_url_override.rstrip("/api") + + +def get_projects_url() -> str: + config = opik.config.OpikConfig() + ui_url = get_ui_url() + + return f"{ui_url}/{config.workspace}/projects" diff --git a/version.txt b/version.txt index d8a023ec10..baa9837854 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -0.1.19 +0.1.20