Skip to content

Commit

Permalink
Authorization integration (#783)
Browse files Browse the repository at this point in the history
* Add sagemaker auth integration

* Update the implementation, no env vars are used except for AWS_OPIK_AUTH now

* Remove error catching, rename functions

* Remove config import

* Update env variable to check

* Fix url update

* Convert httpx url to string before passing get_signed_request

* Update hooks mechanism to support many hooks. Move all sagemaker hook logic into the hook so that it is executed when httpx client is created and not on import when env vars can still be not set

* Fix lint errors, rename registered hooks list

* Rename hooks list

---------

Co-authored-by: Nimrod Lahav <[email protected]>
  • Loading branch information
alexkuzmik and Nimrod007 authored Dec 2, 2024
1 parent 217cfee commit 0c3956f
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 3 deletions.
3 changes: 3 additions & 0 deletions sdks/python/src/opik/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from . import package_version
from .plugins.pytest.decorator import llm_unit
from .evaluation import evaluate, evaluate_experiment
from .integrations.sagemaker import auth as sagemaker_auth

_logging.setup()

Expand All @@ -27,3 +28,5 @@
"configure",
"Prompt",
]

sagemaker_auth.setup_aws_sagemaker_session_hook()
12 changes: 10 additions & 2 deletions sdks/python/src/opik/hooks.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
import httpx
from typing import Callable, List

_registered_httpx_client_hooks: List[Callable[[httpx.Client], None]] = []

def httpx_client_hook(client: httpx.Client) -> None:
pass

def register_httpx_client_hook(hook: Callable[[httpx.Client], httpx.Client]) -> None:
_registered_httpx_client_hooks.append(hook)


def run_httpx_client_hooks(client: httpx.Client) -> None:
for hook in _registered_httpx_client_hooks:
hook(client)
2 changes: 1 addition & 1 deletion sdks/python/src/opik/httpx_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def get(workspace: str, api_key: Optional[str]) -> httpx.Client:
headers = _prepare_headers(workspace=workspace, api_key=api_key)
client.headers.update(headers)

hooks.httpx_client_hook(client)
hooks.run_httpx_client_hooks(client)

return client

Expand Down
Empty file.
46 changes: 46 additions & 0 deletions sdks/python/src/opik/integrations/sagemaker/auth.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import logging
import os
import httpx

from typing import Any

import opik.hooks

LOGGER = logging.getLogger(__name__)


def _in_aws_sagemaker() -> bool:
return os.getenv("AWS_PARTNER_APP_AUTH") is not None


class SagemakerAuth(httpx.Auth):
def __init__(self, auth_provider: Any) -> None:
self.auth_provider = auth_provider

def auth_flow(self, request): # type: ignore
if not _in_aws_sagemaker():
yield request

url, signed_headers = self.auth_provider.get_signed_request(
str(request.url), request.method, request.headers, request.content
)

request.url = httpx.URL(url)
request.headers.update(signed_headers)

yield request


def setup_aws_sagemaker_session_hook() -> None:
def sagemaker_auth_client_hook(client: httpx.Client) -> None:
if not _in_aws_sagemaker():
return

import sagemaker

auth_provider = sagemaker.PartnerAppAuthProvider()
sagemaker_auth = SagemakerAuth(auth_provider)

client.auth = sagemaker_auth

opik.hooks.register_httpx_client_hook(sagemaker_auth_client_hook)

0 comments on commit 0c3956f

Please sign in to comment.