beamlit 0.0.20rc4__py3-none-any.whl → 0.0.20rc5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,7 @@
1
1
  from .apikey import ApiKeyProvider
2
2
  from .authentication import (PublicProvider, RunClientWithCredentials,
3
+ get_authentication_headers,
4
+ new_client_from_settings,
3
5
  new_client_with_credentials)
4
6
  from .credentials import (Config, ContextConfig, Credentials, WorkspaceConfig,
5
7
  load_credentials, load_credentials_from_settings)
@@ -11,6 +13,8 @@ __all__ = (
11
13
  "PublicProvider",
12
14
  "RunClientWithCredentials",
13
15
  "new_client_with_credentials",
16
+ "new_client_from_settings",
17
+ "get_authentication_headers",
14
18
  "Config",
15
19
  "ContextConfig",
16
20
  "Credentials",
@@ -8,6 +8,12 @@ class ApiKeyProvider(Auth):
8
8
  self.credentials = credentials
9
9
  self.workspace_name = workspace_name
10
10
 
11
+ def get_headers(self):
12
+ return {
13
+ 'X-Beamlit-Api-Key': self.credentials.api_key,
14
+ 'X-Beamlit-Workspace': self.workspace_name
15
+ }
16
+
11
17
  def auth_flow(self, request: Request) -> Generator[Request, Response, None]:
12
18
  request.headers['X-Beamlit-Api-Key'] = self.credentials.api_key
13
19
  request.headers['X-Beamlit-Workspace'] = self.workspace_name
@@ -1,12 +1,13 @@
1
1
  from dataclasses import dataclass
2
- from typing import Generator
2
+ from typing import Dict, Generator
3
3
 
4
+ from beamlit.common.settings import Settings
4
5
  from httpx import Auth, Request, Response
5
6
 
6
7
  from ..client import AuthenticatedClient
7
8
  from .apikey import ApiKeyProvider
8
9
  from .clientcredentials import ClientCredentials
9
- from .credentials import Credentials
10
+ from .credentials import Credentials, load_credentials_from_settings
10
11
  from .device_mode import BearerToken
11
12
 
12
13
 
@@ -24,6 +25,15 @@ class RunClientWithCredentials:
24
25
  run_url: str = "https://run.beamlit.dev/v0"
25
26
 
26
27
 
28
+ def new_client_from_settings(settings: Settings):
29
+ credentials = load_credentials_from_settings(settings)
30
+
31
+ client_config = RunClientWithCredentials(
32
+ credentials=credentials,
33
+ workspace=settings.workspace,
34
+ )
35
+ return new_client_with_credentials(client_config)
36
+
27
37
  def new_client_with_credentials(config: RunClientWithCredentials):
28
38
  provider: Auth = None
29
39
  if config.credentials.api_key:
@@ -36,3 +46,22 @@ def new_client_with_credentials(config: RunClientWithCredentials):
36
46
  provider = PublicProvider()
37
47
 
38
48
  return AuthenticatedClient(base_url=config.api_url, provider=provider)
49
+
50
+ def get_authentication_headers(settings: Settings) -> Dict[str, str]:
51
+ credentials = load_credentials_from_settings(settings)
52
+ config = RunClientWithCredentials(
53
+ credentials=credentials,
54
+ workspace=settings.workspace,
55
+ )
56
+ provider = None
57
+ if config.credentials.api_key:
58
+ provider = ApiKeyProvider(config.credentials, config.workspace)
59
+ elif config.credentials.access_token:
60
+ provider = BearerToken(config.credentials, config.workspace, config.api_url)
61
+ elif config.credentials.client_credentials:
62
+ provider = ClientCredentials(config.credentials, config.workspace, config.api_url)
63
+
64
+ if provider is None:
65
+ return None
66
+
67
+ return provider.get_headers()
@@ -23,7 +23,27 @@ class ClientCredentials(Auth):
23
23
  self.workspace_name = workspace_name
24
24
  self.base_url = base_url
25
25
 
26
+ def get_headers(self):
27
+ err = self.refresh_if_needed()
28
+ if err:
29
+ raise err
30
+
31
+ return {
32
+ 'X-Beamlit-Authorization': f'Bearer {self.credentials.access_token}',
33
+ 'X-Beamlit-Workspace': self.workspace_name
34
+ }
35
+
26
36
  def refresh_if_needed(self) -> Optional[Exception]:
37
+ settings = get_settings()
38
+ if self.credentials.client_credentials and not self.credentials.refresh_token:
39
+ headers = { "Authorization": f"Basic {self.credentials.client_credentials}" }
40
+ body = { "grant_type": "client_credentials" }
41
+ response = requests.post(f"{settings.base_url}/oauth/token", headers=headers, json=body)
42
+ response.raise_for_status()
43
+ self.credentials.access_token = response.json()['access_token']
44
+ self.credentials.refresh_token = response.json()['refresh_token']
45
+ self.credentials.expires_in = response.json()['expires_in']
46
+
27
47
  # Need to refresh token if expires in less than 10 minutes
28
48
  parts = self.credentials.access_token.split('.')
29
49
  if len(parts) != 3:
@@ -42,15 +62,6 @@ class ClientCredentials(Auth):
42
62
  return None
43
63
 
44
64
  def auth_flow(self, request: Request) -> Generator[Request, Response, None]:
45
- settings = get_settings()
46
- if self.credentials.client_credentials and not self.credentials.refresh_token:
47
- headers = { "Authorization": f"Basic {self.credentials.client_credentials}" }
48
- body = { "grant_type": "client_credentials" }
49
- response = requests.post(f"{settings.base_url}/oauth/token", headers=headers, json=body)
50
- response.raise_for_status()
51
- self.credentials.access_token = response.json()['access_token']
52
- self.credentials.refresh_token = response.json()['refresh_token']
53
- self.credentials.expires_in = response.json()['expires_in']
54
65
  err = self.refresh_if_needed()
55
66
  if err:
56
67
  return err
@@ -14,6 +14,7 @@ class Credentials:
14
14
  expires_in: int = 0
15
15
  device_code: str = ""
16
16
  client_credentials: str = ""
17
+
17
18
  @dataclass
18
19
  class WorkspaceConfig:
19
20
  name: str
@@ -2,7 +2,7 @@ import base64
2
2
  import json
3
3
  import time
4
4
  from dataclasses import dataclass
5
- from typing import Generator, Optional
5
+ from typing import Dict, Generator, Optional
6
6
 
7
7
  from httpx import Auth, Request, Response, post
8
8
 
@@ -45,6 +45,15 @@ class BearerToken(Auth):
45
45
  self.workspace_name = workspace_name
46
46
  self.base_url = base_url
47
47
 
48
+ def get_headers(self) -> Dict[str, str]:
49
+ err = self.refresh_if_needed()
50
+ if err:
51
+ raise err
52
+ return {
53
+ 'X-Beamlit-Authorization': f'Bearer {self.credentials.access_token}',
54
+ 'X-Beamlit-Workspace': self.workspace_name
55
+ }
56
+
48
57
  def refresh_if_needed(self) -> Optional[Exception]:
49
58
  # Need to refresh token if expires in less than 10 minutes
50
59
  parts = self.credentials.access_token.split('.')
beamlit/common/logger.py CHANGED
@@ -19,6 +19,8 @@ class ColoredFormatter(logging.Formatter):
19
19
  def init(log_level: str):
20
20
  logging.getLogger("uvicorn.access").handlers.clear()
21
21
  logging.getLogger("uvicorn.access").propagate = False
22
+ logging.getLogger("uvicorn.error").handlers.clear()
23
+ logging.getLogger("uvicorn.error").propagate = False
22
24
  logging.getLogger("httpx").handlers.clear()
23
25
  logging.getLogger("httpx").propagate = False
24
26
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: beamlit
3
- Version: 0.0.20rc4
3
+ Version: 0.0.20rc5
4
4
  Summary: Add your description here
5
5
  Author-email: cploujoux <ch.ploujoux@gmail.com>
6
6
  Requires-Python: >=3.12
@@ -125,14 +125,14 @@ beamlit/api/workspaces/list_workspaces.py,sha256=FnmUumyrJeA-akmKDoz0K_DRiv-iiF_
125
125
  beamlit/api/workspaces/remove_workspace_user.py,sha256=AxEG15Vwe-dFspQD21pYqEjsY-RO0_K-eoLpdkY-VEc,2667
126
126
  beamlit/api/workspaces/update_workspace.py,sha256=qa5DV2UJSUYuB_ibALb4E9ghKpT1HaEIzIb9MOcDKv4,4241
127
127
  beamlit/api/workspaces/update_workspace_user_role.py,sha256=Yn9iuJ4tKtauzBiJyU4-wYUMS9g98X2Om8zs7UkzrY8,4917
128
- beamlit/authentication/__init__.py,sha256=4XS2flLWtu6deM9lE_dAVOMsNF-YzRofu2K0jvW6igw,872
129
- beamlit/authentication/apikey.py,sha256=HvqWEd2IqcUuISvftqpi_lhd2fTQDHTf8M4O_k7HerU,489
130
- beamlit/authentication/authentication.py,sha256=Al_ioKYVfGdS9urfENFqE12drzChD6l3sGWM68jHfXA,1219
131
- beamlit/authentication/clientcredentials.py,sha256=OUzV_Kc5A2BIteM5u8r26NwQMs8oTHPqz9qAkSxwxH0,3744
132
- beamlit/authentication/credentials.py,sha256=Ro7Pb_GRNuLF9MuDdOhRolnksnIFIWn5KPRNnT7c7_w,4830
133
- beamlit/authentication/device_mode.py,sha256=Y4WVDH6guhdQKn8zIV5s93VWvtAIn4BsTikq_UnZw4c,3409
128
+ beamlit/authentication/__init__.py,sha256=H3_0gARm3kJxKp-rZRGOCSlJcoeWYI_aw7T6u1LPxcc,1050
129
+ beamlit/authentication/apikey.py,sha256=qU4NRCgXT9GFJIBGyOcouuNwswMIkk_CQi1gOXrtXgw,658
130
+ beamlit/authentication/authentication.py,sha256=PyxPN8RgteT8MBtPgN2mD0Bc5IpRMljEL_E8mroNdH0,2310
131
+ beamlit/authentication/clientcredentials.py,sha256=i7ko_-vAkPvRoFKxIWX4N7bbjXfXinbZFdJPP2weA4M,4015
132
+ beamlit/authentication/credentials.py,sha256=IsmRbQth95my9kkWCpoPKZLLWDpIUwn5OaGIkK8keeA,4831
133
+ beamlit/authentication/device_mode.py,sha256=cN_bBer0YwNZD1L0_RvW2TL1YveOhJ4L_bIAF5m__iA,3702
134
134
  beamlit/common/generate.py,sha256=C6Z0ifDwrSMrtrHwgC8YQm0JklsDaPCkagzpK9v9SrQ,7172
135
- beamlit/common/logger.py,sha256=zuUVHsSSwH0REij0rDhBgZ0U7YvToDQu-SVS6ZBIDUg,948
135
+ beamlit/common/logger.py,sha256=6VnjHuFHfHQEbWZyDEoPCdArVzhVL7rDGF65ZjXj7aM,1061
136
136
  beamlit/common/settings.py,sha256=FoOymkCcrwzya55ZOxOnNdMePYWBAgMTHxmPxHWGXAE,4186
137
137
  beamlit/common/utils.py,sha256=0KaC8vMa0AyIm4jTNgAJSsOYA1b191Q8AUF1up1RxFs,634
138
138
  beamlit/models/__init__.py,sha256=Jv0iTOtTs9G2zQRjbCmDjmNz8T9fX-MHoSt3b3zlRcI,8929
@@ -277,6 +277,6 @@ beamlit/models/websocket_channel.py,sha256=tyNtsVR0cOwd6BK--ehBCH8bIjxtyPhiAkrxY
277
277
  beamlit/models/workspace.py,sha256=5l6-YSgpEgZEyVoBX3PvE5HVO07j7pe3ZA1jdOBR-Fs,3998
278
278
  beamlit/models/workspace_labels.py,sha256=crX235uLVWlu_R3Y4t5AiELY0OJukNAUF9_RO3mZaj8,1252
279
279
  beamlit/models/workspace_user.py,sha256=yCGwPQsVkbGMDkxbATMoEYRxkdx9yIJSsAunVbf8-14,3429
280
- beamlit-0.0.20rc4.dist-info/METADATA,sha256=gNKtjfqwFOBhTLehc4mKL63lTzmlS8dEmqq3_DkeIVE,1746
281
- beamlit-0.0.20rc4.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
282
- beamlit-0.0.20rc4.dist-info/RECORD,,
280
+ beamlit-0.0.20rc5.dist-info/METADATA,sha256=NBnYBiQDiZepBdzW_VLxiLL7XeXhFIc90G2O8ulpC_0,1746
281
+ beamlit-0.0.20rc5.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
282
+ beamlit-0.0.20rc5.dist-info/RECORD,,