aio-kong 3.3.2__py3-none-any.whl → 3.5.0__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,29 +1,19 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: aio-kong
3
- Version: 3.3.2
3
+ Version: 3.5.0
4
4
  Summary: Asynchronous Kong Client
5
5
  License: BSD-3-Clause
6
6
  Author: Luca
7
7
  Author-email: luca@quantmind.com
8
8
  Requires-Python: >=3.10,<4.0
9
- Classifier: Development Status :: 5 - Production/Stable
10
- Classifier: Environment :: Web Environment
11
- Classifier: Framework :: AsyncIO
12
- Classifier: Intended Audience :: Developers
13
9
  Classifier: License :: OSI Approved :: BSD License
14
- Classifier: Operating System :: OS Independent
15
- Classifier: Programming Language :: JavaScript
16
- Classifier: Programming Language :: Python
17
10
  Classifier: Programming Language :: Python :: 3
18
11
  Classifier: Programming Language :: Python :: 3.10
19
12
  Classifier: Programming Language :: Python :: 3.11
20
- Classifier: Topic :: Software Development
21
- Classifier: Topic :: Software Development :: Libraries
22
- Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
23
- Classifier: Topic :: Software Development :: Libraries :: Python Modules
24
- Classifier: Typing :: Typed
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Programming Language :: Python :: 3.13
25
15
  Requires-Dist: PyYAML (>=6.0,<7.0)
26
- Requires-Dist: aiohttp (>=3.8.1,<4.0.0)
16
+ Requires-Dist: aiohttp (>=3.9.5,<4.0.0)
27
17
  Requires-Dist: click (>=8.1.3,<9.0.0)
28
18
  Project-URL: Issues, https://github.com/quantmind/aio-kong/issues
29
19
  Project-URL: Repository, https://github.com/quantmind/aio-kong
@@ -38,7 +28,7 @@ Description-Content-Type: text/markdown
38
28
  [![Downloads](https://img.shields.io/pypi/dd/aio-kong.svg)](https://pypi.org/project/aio-kong/)
39
29
 
40
30
 
41
- Tested with [kong][] v3.3
31
+ Tested with [kong][] v3.8
42
32
 
43
33
  ## Installation & Testing
44
34
 
@@ -0,0 +1,19 @@
1
+ kong/__init__.py,sha256=B7HArV6-6zGHI3LOefG855TT4UVJKSDSy5xjDZb9BLQ,54
2
+ kong/acls.py,sha256=1HR66CKp6SVOmtauXOnj77moLMeHfL7gsfBRwlbJK1U,127
3
+ kong/auths.py,sha256=1aNSQ6Sw5rjh8lbJppH9GOXVMG6KL7-bO4P75MsFKJU,2337
4
+ kong/certificates.py,sha256=7QYS0BLg5QKyjdi1dUDGErXBZHQK4ARv_iYFluXX3RM,275
5
+ kong/cli.py,sha256=TbzNWkx1rj2bnfarC28e2tndwwXWoW61ONJPpr5485c,1953
6
+ kong/client.py,sha256=2GmJ_0AArwBF9RpycT-gGBzwB7Ev46Qy8Mq8HTPRUXc,3887
7
+ kong/components.py,sha256=ZT3bSsfFzKOH-ipXFDFAsMCjWydqqCGsakbhB26CBfM,5471
8
+ kong/consumers.py,sha256=SDR9W6zY3PAIq_iC0EOSKbn0lyTl4C7WbsyM7MA7hLs,2715
9
+ kong/plugins.py,sha256=GmuL-EnrpHeZEzv0bjDvXE0oTtG3DYWpGi0AZHMmY7E,2730
10
+ kong/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
+ kong/routes.py,sha256=e1n5hIIirwkAVacbFnJ_C1AwQN_IC10gISyXU8ex-g0,1493
12
+ kong/services.py,sha256=iuJu2Y8QzLtTBwLNT5yCunJbY3AHSmejz7gXAbvC4bY,2515
13
+ kong/snis.py,sha256=QxjHFUtMGvlBcfCdiye5hQ9n8D1PRSQQThqaB-OekLI,716
14
+ kong/utils.py,sha256=Uoe5DRclN-t1DX8AvwgidYn8GMMvLUXVjMgzqs6mUAE,932
15
+ aio_kong-3.5.0.dist-info/LICENSE,sha256=4S4Rfy2EEQkrBsn1cu8_EZkf2Q8XfOoxjabtI0BOhdQ,1461
16
+ aio_kong-3.5.0.dist-info/METADATA,sha256=OueTmt1drm9zHn0iUXefJjylKlKWAZ3Zj_lbGyvvBCE,2962
17
+ aio_kong-3.5.0.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
18
+ aio_kong-3.5.0.dist-info/entry_points.txt,sha256=Wp_emFiShNNMtqwMxwwdo7qQDiLMxYqZwk9sP4YbEp4,41
19
+ aio_kong-3.5.0.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 1.6.1
2
+ Generator: poetry-core 1.9.1
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
kong/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
1
  """Asynchronous Kong client"""
2
2
 
3
- __version__ = "3.3.2"
3
+ __version__ = "3.5.0"
kong/acls.py ADDED
@@ -0,0 +1,9 @@
1
+ from .components import CrudComponent, KongEntity
2
+
3
+
4
+ class Acl(KongEntity):
5
+ pass
6
+
7
+
8
+ class Acls(CrudComponent[Acl]):
9
+ pass
kong/auths.py CHANGED
@@ -11,10 +11,14 @@ if TYPE_CHECKING:
11
11
  def auth_factory(consumer: Consumer, auth_type: str) -> ConsumerAuth:
12
12
  known_types = {"basic-auth": BasicAuth, "key-auth": KeyAuth}
13
13
  constructor = known_types.get(auth_type, ConsumerAuth)
14
- return constructor(consumer, auth_type)
14
+ return constructor(consumer, Auth, auth_type)
15
15
 
16
16
 
17
- class ConsumerAuth(CrudComponent):
17
+ class Auth(KongEntity):
18
+ pass
19
+
20
+
21
+ class ConsumerAuth(CrudComponent[Auth]):
18
22
  unique_field: str = ""
19
23
 
20
24
  @property
@@ -37,13 +41,13 @@ class ConsumerAuth(CrudComponent):
37
41
  except StopIteration:
38
42
  return None
39
43
 
40
- async def create_or_update_credentials(self, creds_config: dict) -> KongEntity:
44
+ async def create_or_update_credentials(self, creds_config: dict) -> Auth:
41
45
  if existing_id := await self.get_existing_id(creds_config):
42
46
  return await self.update_credentials(existing_id, data=creds_config)
43
47
  else:
44
48
  return await self.create_credentials(data=creds_config)
45
49
 
46
- async def update_credentials(self, id_: str, **kw: Any) -> KongEntity:
50
+ async def update_credentials(self, id_: str, **kw: Any) -> Auth:
47
51
  url = f"{self.url}/{id_}"
48
52
 
49
53
  return await self.cli.execute(
@@ -54,7 +58,7 @@ class ConsumerAuth(CrudComponent):
54
58
  **kw,
55
59
  )
56
60
 
57
- async def create_credentials(self, **kw: Any) -> KongEntity:
61
+ async def create_credentials(self, **kw: Any) -> Auth:
58
62
  return await self.cli.execute(
59
63
  self.url,
60
64
  "post",
@@ -63,7 +67,7 @@ class ConsumerAuth(CrudComponent):
63
67
  **kw,
64
68
  )
65
69
 
66
- async def get_or_create(self) -> KongEntity:
70
+ async def get_or_create(self) -> Auth:
67
71
  secrets = await self.get_list(limit=1)
68
72
  return secrets[0] if secrets else await self.create()
69
73
 
kong/certificates.py CHANGED
@@ -1,14 +1,12 @@
1
1
  from .components import CrudComponent, KongEntity
2
- from .snis import Snis
2
+ from .snis import Sni, Snis
3
3
 
4
4
 
5
5
  class Certificate(KongEntity):
6
6
  @property
7
7
  def snis(self) -> Snis:
8
- return Snis(self)
8
+ return Snis(self, Sni)
9
9
 
10
10
 
11
- class Certificates(CrudComponent):
11
+ class Certificates(CrudComponent[Certificate]):
12
12
  """Kong TLS certificate component"""
13
-
14
- Entity = Certificate
kong/cli.py CHANGED
@@ -1,9 +1,10 @@
1
1
  import asyncio
2
- import click
3
2
  import json
4
- import yaml as _yaml
5
3
  from typing import Any, cast
6
4
 
5
+ import click
6
+ import yaml as _yaml
7
+
7
8
  from . import __version__
8
9
  from .client import Kong, KongError
9
10
  from .consumers import Consumer
@@ -51,7 +52,7 @@ async def _yml(yaml: Any, clear: bool) -> None:
51
52
  result = await cli.apply_json(_yaml.safe_load(yaml), clear=clear)
52
53
  click.echo(json.dumps(result, indent=4))
53
54
  except KongError as exc:
54
- raise click.ClickException(str(exc))
55
+ raise click.ClickException(str(exc)) from None
55
56
 
56
57
 
57
58
  async def _auth_key(consumer: str) -> None:
@@ -65,4 +66,4 @@ async def _auth_key(consumer: str) -> None:
65
66
  key = await c.keyauths.create()
66
67
  click.echo(json.dumps(key.data, indent=4))
67
68
  except KongError as exc:
68
- raise click.ClickException(str(exc))
69
+ raise click.ClickException(str(exc)) from None
kong/client.py CHANGED
@@ -7,18 +7,19 @@ from typing import Any, Callable, Dict, Optional
7
7
  from aiohttp import ClientResponse, ClientSession
8
8
 
9
9
  from . import __version__
10
- from .certificates import Certificates
11
- from .components import CrudComponent, KongError, KongResponseError
12
- from .consumers import Consumers
13
- from .plugins import Plugins
14
- from .routes import Routes
15
- from .services import Services
16
- from .snis import Snis
10
+ from .acls import Acl, Acls
11
+ from .certificates import Certificate, Certificates
12
+ from .components import KongError, KongResponseError
13
+ from .consumers import Consumer, Consumers
14
+ from .plugins import Plugin, Plugins
15
+ from .routes import Route, Routes
16
+ from .services import Service, Services
17
+ from .snis import Sni, Snis
17
18
 
18
19
  __all__ = ["Kong", "KongError", "KongResponseError"]
19
20
 
20
21
  DEFAULT_USER_AGENT = (
21
- f"Python/{'.'.join(map(str, sys.version_info[:2]))} aio-kong/{__version__}"
22
+ f"python/{'.'.join(map(str, sys.version_info[:2]))} aio-kong/{__version__}"
22
23
  )
23
24
 
24
25
 
@@ -41,13 +42,13 @@ class Kong:
41
42
  self.session = session
42
43
  self.user_agent = user_agent
43
44
  self.request_kwargs = request_kwargs or {}
44
- self.services = Services(self)
45
- self.routes = Routes(self)
46
- self.plugins = Plugins(self)
47
- self.consumers = Consumers(self)
48
- self.certificates = Certificates(self)
49
- self.acls = CrudComponent(self, "acls")
50
- self.snis = Snis(self)
45
+ self.services = Services(self, Service)
46
+ self.routes = Routes(self, Route)
47
+ self.plugins = Plugins(self, Plugin)
48
+ self.consumers = Consumers(self, Consumer)
49
+ self.certificates = Certificates(self, Certificate)
50
+ self.acls = Acls(self, Acl)
51
+ self.snis = Snis(self, Sni)
51
52
 
52
53
  def __repr__(self) -> str:
53
54
  return self.url
kong/components.py CHANGED
@@ -1,8 +1,17 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import json
4
+ from typing import (
5
+ TYPE_CHECKING,
6
+ Any,
7
+ AsyncIterator,
8
+ Generic,
9
+ Iterator,
10
+ Mapping,
11
+ TypeVar,
12
+ )
13
+
4
14
  from aiohttp import ClientResponse
5
- from typing import TYPE_CHECKING, Any, AsyncIterator, Iterator, Mapping
6
15
 
7
16
  from .utils import UUID, as_dict, as_params, uid
8
17
 
@@ -89,11 +98,16 @@ class KongEntity(Mapping[str, Any]):
89
98
  return await self.root.execute(url, method, **params)
90
99
 
91
100
 
92
- class CrudComponent:
93
- Entity = KongEntity
101
+ Entity = TypeVar("Entity", bound=KongEntity)
102
+
103
+
104
+ class CrudComponent(Generic[Entity]):
94
105
 
95
- def __init__(self, root: Kong | KongEntity, name: str = "") -> None:
106
+ def __init__(
107
+ self, root: Kong | KongEntity, factory: type[Entity], name: str = ""
108
+ ) -> None:
96
109
  self.root = root
110
+ self.factory = factory
97
111
  self.name = name or self.__class__.__name__.lower()
98
112
 
99
113
  def __repr__(self) -> str:
@@ -120,7 +134,7 @@ class CrudComponent:
120
134
  async def apply_json(self, data: JsonType, clear: bool = True) -> list:
121
135
  raise NotImplementedError
122
136
 
123
- async def paginate(self, **params: Any) -> AsyncIterator[KongEntity]:
137
+ async def paginate(self, **params: Any) -> AsyncIterator[Entity]:
124
138
  url = self.list_create_url()
125
139
  next_ = url
126
140
  exec_params = as_params(**params)
@@ -132,14 +146,14 @@ class CrudComponent:
132
146
  for d in data["data"]:
133
147
  yield self.wrap(d)
134
148
 
135
- async def get_list(self, **params: Any) -> list[KongEntity]:
149
+ async def get_list(self, **params: Any) -> list[Entity]:
136
150
  url = self.list_create_url()
137
151
  return await self.execute(url, params=as_params(**params), wrap=self.wrap_list)
138
152
 
139
- async def get_full_list(self, **params: Any) -> list[KongEntity]:
153
+ async def get_full_list(self, **params: Any) -> list[Entity]:
140
154
  return [d async for d in self.paginate(**params)]
141
155
 
142
- async def get(self, id_: str | UUID) -> KongEntity:
156
+ async def get(self, id_: str | UUID) -> Entity:
143
157
  url = f"{self.url}/{uid(id_)}"
144
158
  return await self.execute(url, wrap=self.wrap)
145
159
 
@@ -147,11 +161,11 @@ class CrudComponent:
147
161
  url = f"{self.url}/{uid(id_)}"
148
162
  return await self.execute(url, "get", callback=self.head)
149
163
 
150
- async def create(self, **params: Any) -> KongEntity:
164
+ async def create(self, **params: Any) -> Entity:
151
165
  url = self.list_create_url()
152
166
  return await self.execute(url, "post", json=params, wrap=self.wrap)
153
167
 
154
- async def update(self, id_: str | UUID, **params: Any) -> KongEntity:
168
+ async def update(self, id_: str | UUID, **params: Any) -> Entity:
155
169
  url = f"{self.url}/{uid(id_)}"
156
170
  return await self.execute(url, "patch", json=params, wrap=self.wrap)
157
171
 
@@ -174,10 +188,10 @@ class CrudComponent:
174
188
  else: # pragma: no cover
175
189
  raise KongResponseError(response)
176
190
 
177
- def wrap(self, data: dict) -> KongEntity:
178
- return self.Entity(self, data)
191
+ def wrap(self, data: dict) -> Entity:
192
+ return self.factory(self, data)
179
193
 
180
- def wrap_list(self, data: dict) -> list[KongEntity]:
194
+ def wrap_list(self, data: dict) -> list[Entity]:
181
195
  return [self.wrap(d) for d in data["data"]]
182
196
 
183
197
  def list_create_url(self) -> str:
kong/consumers.py CHANGED
@@ -1,5 +1,6 @@
1
1
  from typing import cast
2
2
 
3
+ from .acls import Acl, Acls
3
4
  from .auths import ConsumerAuth, auth_factory
4
5
  from .components import CrudComponent, JsonType, KongError, KongResponseError
5
6
  from .plugins import KongEntityWithPlugins
@@ -11,8 +12,8 @@ class Consumer(KongEntityWithPlugins):
11
12
  return self.data.get("username", "")
12
13
 
13
14
  @property
14
- def acls(self) -> CrudComponent:
15
- return CrudComponent(self, "acls")
15
+ def acls(self) -> Acls:
16
+ return Acls(self, Acl)
16
17
 
17
18
  @property
18
19
  def jwts(self) -> ConsumerAuth:
@@ -27,8 +28,7 @@ class Consumer(KongEntityWithPlugins):
27
28
  return auth_factory(self, "basic-auth")
28
29
 
29
30
 
30
- class Consumers(CrudComponent):
31
- Entity = Consumer
31
+ class Consumers(CrudComponent[Consumer]):
32
32
 
33
33
  async def apply_credentials(self, auths: list[dict], consumer: Consumer) -> None:
34
34
  for auth_data in auths:
kong/plugins.py CHANGED
@@ -8,8 +8,12 @@ if TYPE_CHECKING:
8
8
  from .client import Kong
9
9
 
10
10
 
11
- class Plugins(CrudComponent):
12
- async def create(self, **params: Any) -> KongEntity:
11
+ class Plugin(KongEntity):
12
+ pass
13
+
14
+
15
+ class Plugins(CrudComponent[Plugin]):
16
+ async def create(self, **params: Any) -> Plugin:
13
17
  params = await self.preprocess_parameters(params)
14
18
  return await super().create(**params)
15
19
 
@@ -50,7 +54,7 @@ class Plugins(CrudComponent):
50
54
  params = await preprocessor(self.cli, params)
51
55
  return params
52
56
 
53
- async def update(self, id_: str | UUID, **params: Any) -> KongEntity:
57
+ async def update(self, id_: str | UUID, **params: Any) -> Plugin:
54
58
  params = await self.preprocess_parameters(params)
55
59
  return await super().update(id_, **params)
56
60
 
@@ -58,7 +62,7 @@ class Plugins(CrudComponent):
58
62
  class KongEntityWithPlugins(KongEntity):
59
63
  @property
60
64
  def plugins(self) -> Plugins:
61
- return Plugins(self)
65
+ return Plugins(self, Plugin)
62
66
 
63
67
 
64
68
  async def consumer_id_from_username(cli: Kong, params: dict) -> dict:
kong/routes.py CHANGED
@@ -5,14 +5,16 @@ from .plugins import KongEntityWithPlugins
5
5
  from .utils import as_list
6
6
 
7
7
 
8
+ class Route(KongEntityWithPlugins):
9
+ pass
10
+
11
+
8
12
  class Routes(CrudComponent):
9
13
  """Kong Routes
10
14
 
11
15
  Routes are always associated with a Service
12
16
  """
13
17
 
14
- Entity = KongEntityWithPlugins
15
-
16
18
  async def delete(self, id_: str | UUID) -> bool:
17
19
  route = cast(KongEntityWithPlugins, self.wrap({"id": id_}))
18
20
  await route.plugins.delete_all()
kong/services.py CHANGED
@@ -2,7 +2,7 @@ from typing import cast
2
2
 
3
3
  from .components import UUID, CrudComponent, JsonType, KongError
4
4
  from .plugins import KongEntityWithPlugins
5
- from .routes import Routes
5
+ from .routes import Route, Routes
6
6
  from .utils import local_ip
7
7
 
8
8
  REMOVE = frozenset(("absent", "remove"))
@@ -14,18 +14,16 @@ class Service(KongEntityWithPlugins):
14
14
 
15
15
  @property
16
16
  def routes(self) -> Routes:
17
- return Routes(self)
17
+ return Routes(self, Route)
18
18
 
19
19
  @property
20
20
  def host(self) -> str:
21
21
  return self.data.get("host", "")
22
22
 
23
23
 
24
- class Services(CrudComponent):
24
+ class Services(CrudComponent[Service]):
25
25
  """Kong Services"""
26
26
 
27
- Entity = Service
28
-
29
27
  async def delete(self, id_: str | UUID) -> bool:
30
28
  srv = cast(Service, self.wrap({"id": id_}))
31
29
  await srv.routes.delete_all()
kong/snis.py CHANGED
@@ -1,7 +1,11 @@
1
- from .components import CrudComponent, JsonType
1
+ from .components import CrudComponent, JsonType, KongEntity
2
2
 
3
3
 
4
- class Snis(CrudComponent):
4
+ class Sni(KongEntity):
5
+ pass
6
+
7
+
8
+ class Snis(CrudComponent[Sni]):
5
9
  """Kong SNI API component"""
6
10
 
7
11
  async def apply_json(self, data: JsonType, clear: bool = True) -> list:
kong/utils.py CHANGED
@@ -1,8 +1,9 @@
1
1
  import socket
2
- from multidict import MultiDict
3
2
  from typing import Any
4
3
  from uuid import UUID
5
4
 
5
+ from multidict import MultiDict
6
+
6
7
 
7
8
  def as_list(key: str, data: dict) -> dict:
8
9
  if key in data:
@@ -1,18 +0,0 @@
1
- kong/__init__.py,sha256=M2UuAVGr9PKyw_LuyuKNc-r10DwOh7Kc-BwTbMnP0Xg,54
2
- kong/auths.py,sha256=QcY6pT_4Jf9R8KNafMoAHNV-ixjew5Nq63dlgo3wadc,2314
3
- kong/certificates.py,sha256=MFRmFz7X2oqZN434VD7BzB7ozsUj-HD0Jv5anZZkYHw,278
4
- kong/cli.py,sha256=NiOb4vqAwnrdBDPd9gkeKai38oNRfAE803wQ4ZRca-o,1932
5
- kong/client.py,sha256=RP-Hhhtzd16jzRvR4hZQPAmsgse5D7ke5xjfrZOcmGw,3782
6
- kong/components.py,sha256=JrQrxkVSdq7ZsBvb_nG28TMEL8uFpNsdApODRr0T5o4,5342
7
- kong/consumers.py,sha256=PRIa07WU8xNRfod5XmeK2V_f59wfTlOP6ZK8iR1iAkY,2720
8
- kong/plugins.py,sha256=QlxPuWmui64iiauJ-pXTjZd84wrNARe45v1yIMGCPAU,2685
9
- kong/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
- kong/routes.py,sha256=GkNfaKZDuO9BDDhri3Ah3b2qy_VfAHcAmamRHlbOA0k,1482
11
- kong/services.py,sha256=ForaPLtEKyITZb9GqVb-XJUf4iOvKYh26YZSfo1SY6k,2514
12
- kong/snis.py,sha256=UfEVp_PAwXYVH9mK-ND7HCtf_H6T9RqUEoHU2sne_bY,665
13
- kong/utils.py,sha256=j3KmyZ4dtszteIl5saaxJa0JJaNTSearIAHOZrw8O7M,931
14
- aio_kong-3.3.2.dist-info/LICENSE,sha256=4S4Rfy2EEQkrBsn1cu8_EZkf2Q8XfOoxjabtI0BOhdQ,1461
15
- aio_kong-3.3.2.dist-info/METADATA,sha256=jaEBX8NjbUhEniriGgc9CONtk1ERyjVmCD1-_j6txuk,3452
16
- aio_kong-3.3.2.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
17
- aio_kong-3.3.2.dist-info/entry_points.txt,sha256=Wp_emFiShNNMtqwMxwwdo7qQDiLMxYqZwk9sP4YbEp4,41
18
- aio_kong-3.3.2.dist-info/RECORD,,