livekit-api 0.4.4__tar.gz → 0.5.1__tar.gz

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.
Files changed (25) hide show
  1. {livekit-api-0.4.4 → livekit_api-0.5.1}/PKG-INFO +3 -3
  2. {livekit-api-0.4.4 → livekit_api-0.5.1}/livekit/api/__init__.py +2 -1
  3. {livekit-api-0.4.4 → livekit_api-0.5.1}/livekit/api/_service.py +11 -3
  4. {livekit-api-0.4.4 → livekit_api-0.5.1}/livekit/api/access_token.py +21 -0
  5. {livekit-api-0.4.4 → livekit_api-0.5.1}/livekit/api/livekit_api.py +6 -0
  6. livekit_api-0.5.1/livekit/api/sip_service.py +134 -0
  7. livekit_api-0.5.1/livekit/api/version.py +1 -0
  8. {livekit-api-0.4.4 → livekit_api-0.5.1}/livekit_api.egg-info/PKG-INFO +3 -3
  9. {livekit-api-0.4.4 → livekit_api-0.5.1}/livekit_api.egg-info/SOURCES.txt +1 -0
  10. {livekit-api-0.4.4 → livekit_api-0.5.1}/livekit_api.egg-info/requires.txt +1 -1
  11. {livekit-api-0.4.4 → livekit_api-0.5.1}/setup.py +2 -2
  12. {livekit-api-0.4.4 → livekit_api-0.5.1}/tests/test_access_token.py +4 -1
  13. livekit-api-0.4.4/livekit/api/version.py +0 -1
  14. {livekit-api-0.4.4 → livekit_api-0.5.1}/README.md +0 -0
  15. {livekit-api-0.4.4 → livekit_api-0.5.1}/livekit/api/egress_service.py +0 -0
  16. {livekit-api-0.4.4 → livekit_api-0.5.1}/livekit/api/ingress_service.py +0 -0
  17. {livekit-api-0.4.4 → livekit_api-0.5.1}/livekit/api/py.typed +0 -0
  18. {livekit-api-0.4.4 → livekit_api-0.5.1}/livekit/api/room_service.py +0 -0
  19. {livekit-api-0.4.4 → livekit_api-0.5.1}/livekit/api/twirp_client.py +0 -0
  20. {livekit-api-0.4.4 → livekit_api-0.5.1}/livekit/api/webhook.py +0 -0
  21. {livekit-api-0.4.4 → livekit_api-0.5.1}/livekit_api.egg-info/dependency_links.txt +0 -0
  22. {livekit-api-0.4.4 → livekit_api-0.5.1}/livekit_api.egg-info/top_level.txt +0 -0
  23. {livekit-api-0.4.4 → livekit_api-0.5.1}/pyproject.toml +0 -0
  24. {livekit-api-0.4.4 → livekit_api-0.5.1}/setup.cfg +0 -0
  25. {livekit-api-0.4.4 → livekit_api-0.5.1}/tests/test_webhook.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: livekit-api
3
- Version: 0.4.4
3
+ Version: 0.5.1
4
4
  Summary: Python Server API for LiveKit
5
5
  Home-page: https://github.com/livekit/python-sdks
6
6
  License: Apache-2.0
@@ -19,13 +19,13 @@ Classifier: Programming Language :: Python :: 3.8
19
19
  Classifier: Programming Language :: Python :: 3.9
20
20
  Classifier: Programming Language :: Python :: 3.10
21
21
  Classifier: Programming Language :: Python :: 3 :: Only
22
- Requires-Python: >=3.8.0
22
+ Requires-Python: >=3.9.0
23
23
  Description-Content-Type: text/markdown
24
24
  Requires-Dist: pyjwt>=2.0.0
25
25
  Requires-Dist: aiohttp>=3.9.0
26
26
  Requires-Dist: protobuf>=3
27
27
  Requires-Dist: types-protobuf<5,>=4
28
- Requires-Dist: livekit-protocol<1,>=0.3.0
28
+ Requires-Dist: livekit-protocol<2,>=0.5.1
29
29
 
30
30
  # LiveKit Server APIs
31
31
 
@@ -21,9 +21,10 @@ from livekit.protocol.ingress import *
21
21
  from livekit.protocol.models import *
22
22
  from livekit.protocol.room import *
23
23
  from livekit.protocol.webhook import *
24
+ from livekit.protocol.sip import *
24
25
 
25
26
  from .twirp_client import TwirpError, TwirpErrorCode
26
27
  from .livekit_api import LiveKitAPI
27
- from .access_token import VideoGrants, AccessToken, TokenVerifier
28
+ from .access_token import VideoGrants, SIPGrants, AccessToken, TokenVerifier
28
29
  from .webhook import WebhookReceiver
29
30
  from .version import __version__
@@ -1,8 +1,10 @@
1
+ from __future__ import annotations
2
+
1
3
  from typing import Dict
2
4
  import aiohttp
3
5
  from abc import ABC
4
6
  from .twirp_client import TwirpClient
5
- from .access_token import AccessToken, VideoGrants
7
+ from .access_token import AccessToken, VideoGrants, SIPGrants
6
8
 
7
9
  AUTHORIZATION = "authorization"
8
10
 
@@ -15,8 +17,14 @@ class Service(ABC):
15
17
  self.api_key = api_key
16
18
  self.api_secret = api_secret
17
19
 
18
- def _auth_header(self, grants: VideoGrants) -> Dict[str, str]:
19
- token = AccessToken(self.api_key, self.api_secret).with_grants(grants).to_jwt()
20
+ def _auth_header(
21
+ self, grants: VideoGrants, sip: SIPGrants | None = None
22
+ ) -> Dict[str, str]:
23
+ tok = AccessToken(self.api_key, self.api_secret).with_grants(grants)
24
+ if sip is not None:
25
+ tok = tok.with_sip_grants(sip)
26
+
27
+ token = tok.to_jwt()
20
28
 
21
29
  headers = {}
22
30
  headers[AUTHORIZATION] = "Bearer {}".format(token)
@@ -63,11 +63,20 @@ class VideoGrants:
63
63
  agent: bool = False
64
64
 
65
65
 
66
+ @dataclasses.dataclass
67
+ class SIPGrants:
68
+ # manage sip resources
69
+ admin: bool = False
70
+ # make outbound calls
71
+ call: bool = False
72
+
73
+
66
74
  @dataclasses.dataclass
67
75
  class Claims:
68
76
  identity: str = ""
69
77
  name: str = ""
70
78
  video: VideoGrants = dataclasses.field(default_factory=VideoGrants)
79
+ sip: SIPGrants = dataclasses.field(default_factory=SIPGrants)
71
80
  metadata: str = ""
72
81
  sha256: str = ""
73
82
 
@@ -100,6 +109,10 @@ class AccessToken:
100
109
  self.claims.video = grants
101
110
  return self
102
111
 
112
+ def with_sip_grants(self, grants: SIPGrants) -> "AccessToken":
113
+ self.claims.sip = grants
114
+ return self
115
+
103
116
  def with_identity(self, identity: str) -> "AccessToken":
104
117
  self.identity = identity
105
118
  return self
@@ -173,10 +186,18 @@ class TokenVerifier:
173
186
  }
174
187
  video = VideoGrants(**video_dict)
175
188
 
189
+ sip_dict = claims.get("sip", dict())
190
+ sip_dict = {camel_to_snake(k): v for k, v in sip_dict.items()}
191
+ sip_dict = {
192
+ k: v for k, v in sip_dict.items() if k in SIPGrants.__dataclass_fields__
193
+ }
194
+ sip = SIPGrants(**sip_dict)
195
+
176
196
  return Claims(
177
197
  identity=claims.get("sub", ""),
178
198
  name=claims.get("name", ""),
179
199
  video=video,
200
+ sip=sip,
180
201
  metadata=claims.get("metadata", ""),
181
202
  sha256=claims.get("sha256", ""),
182
203
  )
@@ -3,6 +3,7 @@ import os
3
3
  from .room_service import RoomService
4
4
  from .egress_service import EgressService
5
5
  from .ingress_service import IngressService
6
+ from .sip_service import SipService
6
7
  from typing import Optional
7
8
 
8
9
 
@@ -29,6 +30,7 @@ class LiveKitAPI:
29
30
  self._room = RoomService(self._session, url, api_key, api_secret)
30
31
  self._ingress = IngressService(self._session, url, api_key, api_secret)
31
32
  self._egress = EgressService(self._session, url, api_key, api_secret)
33
+ self._sip = SipService(self._session, url, api_key, api_secret)
32
34
 
33
35
  @property
34
36
  def room(self):
@@ -42,5 +44,9 @@ class LiveKitAPI:
42
44
  def egress(self):
43
45
  return self._egress
44
46
 
47
+ @property
48
+ def sip(self):
49
+ return self._sip
50
+
45
51
  async def aclose(self):
46
52
  await self._session.close()
@@ -0,0 +1,134 @@
1
+ import aiohttp
2
+ from livekit.protocol import sip as proto_sip
3
+ from ._service import Service
4
+ from .access_token import VideoGrants, SIPGrants
5
+
6
+ SVC = "SIP"
7
+
8
+
9
+ class SipService(Service):
10
+ def __init__(
11
+ self, session: aiohttp.ClientSession, url: str, api_key: str, api_secret: str
12
+ ):
13
+ super().__init__(session, url, api_key, api_secret)
14
+
15
+ async def create_sip_trunk(
16
+ self, create: proto_sip.CreateSIPTrunkRequest
17
+ ) -> proto_sip.SIPTrunkInfo:
18
+ return await self._client.request(
19
+ SVC,
20
+ "CreateSIPTrunk",
21
+ create,
22
+ self._auth_header(VideoGrants(), sip=SIPGrants(admin=True)),
23
+ proto_sip.SIPTrunkInfo,
24
+ )
25
+
26
+ async def create_sip_inbound_trunk(
27
+ self, create: proto_sip.CreateSIPInboundTrunkRequest
28
+ ) -> proto_sip.SIPInboundTrunkInfo:
29
+ return await self._client.request(
30
+ SVC,
31
+ "CreateSIPInboundTrunk",
32
+ create,
33
+ self._auth_header(VideoGrants(), sip=SIPGrants(admin=True)),
34
+ proto_sip.SIPInboundTrunkInfo,
35
+ )
36
+
37
+ async def create_sip_outbound_trunk(
38
+ self, create: proto_sip.CreateSIPOutboundTrunkRequest
39
+ ) -> proto_sip.SIPOutboundTrunkInfo:
40
+ return await self._client.request(
41
+ SVC,
42
+ "CreateSIPOutboundTrunk",
43
+ create,
44
+ self._auth_header(VideoGrants(), sip=SIPGrants(admin=True)),
45
+ proto_sip.SIPOutboundTrunkInfo,
46
+ )
47
+
48
+ async def list_sip_trunk(
49
+ self, list: proto_sip.ListSIPTrunkRequest
50
+ ) -> proto_sip.ListSIPTrunkResponse:
51
+ return await self._client.request(
52
+ SVC,
53
+ "ListSIPTrunk",
54
+ list,
55
+ self._auth_header(VideoGrants(), sip=SIPGrants(admin=True)),
56
+ proto_sip.ListSIPTrunkResponse,
57
+ )
58
+
59
+ async def list_sip_inbound_trunk(
60
+ self, list: proto_sip.ListSIPInboundTrunkRequest
61
+ ) -> proto_sip.ListSIPInboundTrunkResponse:
62
+ return await self._client.request(
63
+ SVC,
64
+ "ListSIPInboundTrunk",
65
+ list,
66
+ self._auth_header(VideoGrants(), sip=SIPGrants(admin=True)),
67
+ proto_sip.ListSIPInboundTrunkResponse,
68
+ )
69
+
70
+ async def list_sip_outbound_trunk(
71
+ self, list: proto_sip.ListSIPOutboundTrunkRequest
72
+ ) -> proto_sip.ListSIPOutboundTrunkResponse:
73
+ return await self._client.request(
74
+ SVC,
75
+ "ListSIPOutboundTrunk",
76
+ list,
77
+ self._auth_header(VideoGrants(), sip=SIPGrants(admin=True)),
78
+ proto_sip.ListSIPOutboundTrunkResponse,
79
+ )
80
+
81
+ async def delete_sip_trunk(
82
+ self, delete: proto_sip.DeleteSIPTrunkRequest
83
+ ) -> proto_sip.SIPTrunkInfo:
84
+ return await self._client.request(
85
+ SVC,
86
+ "DeleteSIPTrunk",
87
+ delete,
88
+ self._auth_header(VideoGrants(), sip=SIPGrants(admin=True)),
89
+ proto_sip.SIPTrunkInfo,
90
+ )
91
+
92
+ async def create_sip_dispatch_rule(
93
+ self, create: proto_sip.CreateSIPDispatchRuleRequest
94
+ ) -> proto_sip.SIPDispatchRuleInfo:
95
+ return await self._client.request(
96
+ SVC,
97
+ "CreateSIPDispatchRule",
98
+ create,
99
+ self._auth_header(VideoGrants(), sip=SIPGrants(admin=True)),
100
+ proto_sip.SIPDispatchRuleInfo,
101
+ )
102
+
103
+ async def list_sip_dispatch_rule(
104
+ self, list: proto_sip.ListSIPDispatchRuleRequest
105
+ ) -> proto_sip.ListSIPDispatchRuleResponse:
106
+ return await self._client.request(
107
+ SVC,
108
+ "ListSIPDispatchRule",
109
+ list,
110
+ self._auth_header(VideoGrants(), sip=SIPGrants(admin=True)),
111
+ proto_sip.ListSIPDispatchRuleResponse,
112
+ )
113
+
114
+ async def delete_sip_dispatch_rule(
115
+ self, delete: proto_sip.DeleteSIPDispatchRuleRequest
116
+ ) -> proto_sip.SIPDispatchRuleInfo:
117
+ return await self._client.request(
118
+ SVC,
119
+ "DeleteSIPDispatchRule",
120
+ delete,
121
+ self._auth_header(VideoGrants(), sip=SIPGrants(admin=True)),
122
+ proto_sip.SIPDispatchRuleInfo,
123
+ )
124
+
125
+ async def create_sip_participant(
126
+ self, create: proto_sip.CreateSIPParticipantRequest
127
+ ) -> proto_sip.SIPParticipantInfo:
128
+ return await self._client.request(
129
+ SVC,
130
+ "CreateSIPParticipant",
131
+ create,
132
+ self._auth_header(VideoGrants(), sip=SIPGrants(call=True)),
133
+ proto_sip.SIPParticipantInfo,
134
+ )
@@ -0,0 +1 @@
1
+ __version__ = "0.5.1"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: livekit-api
3
- Version: 0.4.4
3
+ Version: 0.5.1
4
4
  Summary: Python Server API for LiveKit
5
5
  Home-page: https://github.com/livekit/python-sdks
6
6
  License: Apache-2.0
@@ -19,13 +19,13 @@ Classifier: Programming Language :: Python :: 3.8
19
19
  Classifier: Programming Language :: Python :: 3.9
20
20
  Classifier: Programming Language :: Python :: 3.10
21
21
  Classifier: Programming Language :: Python :: 3 :: Only
22
- Requires-Python: >=3.8.0
22
+ Requires-Python: >=3.9.0
23
23
  Description-Content-Type: text/markdown
24
24
  Requires-Dist: pyjwt>=2.0.0
25
25
  Requires-Dist: aiohttp>=3.9.0
26
26
  Requires-Dist: protobuf>=3
27
27
  Requires-Dist: types-protobuf<5,>=4
28
- Requires-Dist: livekit-protocol<1,>=0.3.0
28
+ Requires-Dist: livekit-protocol<2,>=0.5.1
29
29
 
30
30
  # LiveKit Server APIs
31
31
 
@@ -9,6 +9,7 @@ livekit/api/ingress_service.py
9
9
  livekit/api/livekit_api.py
10
10
  livekit/api/py.typed
11
11
  livekit/api/room_service.py
12
+ livekit/api/sip_service.py
12
13
  livekit/api/twirp_client.py
13
14
  livekit/api/version.py
14
15
  livekit/api/webhook.py
@@ -2,4 +2,4 @@ pyjwt>=2.0.0
2
2
  aiohttp>=3.9.0
3
3
  protobuf>=3
4
4
  types-protobuf<5,>=4
5
- livekit-protocol<1,>=0.3.0
5
+ livekit-protocol<2,>=0.5.1
@@ -47,13 +47,13 @@ setuptools.setup(
47
47
  keywords=["webrtc", "realtime", "audio", "video", "livekit"],
48
48
  license="Apache-2.0",
49
49
  packages=setuptools.find_namespace_packages(include=["livekit.*"]),
50
- python_requires=">=3.8.0",
50
+ python_requires=">=3.9.0",
51
51
  install_requires=[
52
52
  "pyjwt>=2.0.0",
53
53
  "aiohttp>=3.9.0",
54
54
  "protobuf>=3",
55
55
  "types-protobuf>=4,<5",
56
- "livekit-protocol>=0.3.0,<1",
56
+ "livekit-protocol>=0.5.1,<2",
57
57
  ],
58
58
  package_data={
59
59
  "livekit.api": ["py.typed", "*.pyi", "**/*.pyi"],
@@ -1,7 +1,7 @@
1
1
  import datetime
2
2
 
3
3
  import pytest # type: ignore
4
- from livekit.api import AccessToken, TokenVerifier, VideoGrants
4
+ from livekit.api import AccessToken, TokenVerifier, VideoGrants, SIPGrants
5
5
 
6
6
  TEST_API_KEY = "myapikey"
7
7
  TEST_API_SECRET = "thiskeyistotallyunsafe"
@@ -9,12 +9,14 @@ TEST_API_SECRET = "thiskeyistotallyunsafe"
9
9
 
10
10
  def test_verify_token():
11
11
  grants = VideoGrants(room_join=True, room="test_room")
12
+ sip = SIPGrants(admin=True)
12
13
 
13
14
  token = (
14
15
  AccessToken(TEST_API_KEY, TEST_API_SECRET)
15
16
  .with_identity("test_identity")
16
17
  .with_metadata("test_metadata")
17
18
  .with_grants(grants)
19
+ .with_sip_grants(sip)
18
20
  .to_jwt()
19
21
  )
20
22
 
@@ -24,6 +26,7 @@ def test_verify_token():
24
26
  assert claims.identity == "test_identity"
25
27
  assert claims.metadata == "test_metadata"
26
28
  assert claims.video == grants
29
+ assert claims.sip == sip
27
30
 
28
31
 
29
32
  def test_verify_token_invalid():
@@ -1 +0,0 @@
1
- __version__ = "0.4.4"
File without changes
File without changes
File without changes