soia-client 1.0.9__py3-none-any.whl → 1.0.11__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.

Potentially problematic release.


This version of soia-client might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: soia-client
3
- Version: 1.0.9
3
+ Version: 1.0.11
4
4
  Author-email: Tyler Fibonacci <gepheum@gmail.com>
5
5
  License: MIT License
6
6
 
@@ -1,23 +1,25 @@
1
- soia_client-1.0.9.dist-info/licenses/LICENSE,sha256=SaAftKkX6hfSOiPdENQPS70tifH3PDHgazq8eK2Pwfw,1064
2
- soialib/__init__.py,sha256=h_ENkLJEdrh1mGhCoKgIadDasSulW3zK9_qhEsTviXY,429
1
+ soia_client-1.0.11.dist-info/licenses/LICENSE,sha256=SaAftKkX6hfSOiPdENQPS70tifH3PDHgazq8eK2Pwfw,1064
2
+ soialib/_.py,sha256=I4SxBM3brmE9D6hyrDrdkbfVnDLVRWaGwnj0C9Zxh54,52
3
+ soialib/__init__.py,sha256=UyNrMaKEwCmYecsEwgsglMJvjKzIbDp7idbIxLdBz_k,499
3
4
  soialib/keyed_items.py,sha256=q7MCn82obf-0jh7FcAhuw4eh9-wtuHIpkEFcSfc8EaY,338
4
5
  soialib/method.py,sha256=2qWG4jMqYhS3hA8y8YDu3iqzhXA_AKebpB38RWNmsYQ,452
5
6
  soialib/module_initializer.py,sha256=Riq6B6cS9HUG1W8tyaa0GkiG3F4fGX70bKU0UOCnrRw,4205
6
7
  soialib/never.py,sha256=bYU63XyNX4e2wOUXQHhHWGO-an4IFr9_ur1ut6GmGN0,47
7
8
  soialib/serializer.py,sha256=jSDanuJ4TEPWEO0ssYSKy2CDLUPV0zwCUzNGHk6uFRQ,3122
8
9
  soialib/serializers.py,sha256=vNLNsfuu6dF0ivJF6v7wQj5Yr6uo2kZHXG5tMrYiVTA,2564
10
+ soialib/service_client.py,sha256=DvBu5-w64FKvuu8Ew9v3Ph6FYGTMcfCwz4eEwKRE2Dc,2284
9
11
  soialib/spec.py,sha256=w-eMMUqOchOlCJaXppyAa2JpSBrMo9lrMvqz8VaEX4I,3699
10
12
  soialib/timestamp.py,sha256=lXBNH8mPmzflkNjSKZSBl2XS-ot9N8N92B_zGO2SMtU,4078
11
13
  soialib/impl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
- soialib/impl/arrays.py,sha256=4p-4FoM_hrQfwSIF1KmYGjJyP6SGyV7rD_L7D46d9Z4,4863
14
+ soialib/impl/arrays.py,sha256=fghIo1Uhn0wx-b4IjZVOqqPyKHI0KmcAfboNhCdzAi0,4871
13
15
  soialib/impl/enums.py,sha256=kSH0Puub0pZJ4hAVw52y0ktDX1IkHpPan3IDp6OHIIs,15990
14
16
  soialib/impl/function_maker.py,sha256=MvCDv1WwzKGJzZbNCnJ_8-MP3m1xTIabumXA-9Ydd9M,5639
15
17
  soialib/impl/optionals.py,sha256=pWuhfTIYM7669Rko-oVlBhHLqO3vgASW7fL0Yos3AWM,2076
16
18
  soialib/impl/primitives.py,sha256=AHMVvs3BWvPfggsdFnY5dwwqAwiNVFYJa_rJ-WjMJfk,7424
17
19
  soialib/impl/repr.py,sha256=7WX0bEAVENTjlyZIcbT8TcJylS7IRIyafGCmqaIMxFM,1413
18
- soialib/impl/structs.py,sha256=GKTw6p_HasS9E520l74QFldIjUhjxM8sm4poPnR7fFg,25539
20
+ soialib/impl/structs.py,sha256=g__J0w6FAteHW2ZF69yuhZGNfm5-XCorBQW_T1r3PCg,25621
19
21
  soialib/impl/type_adapter.py,sha256=e72nBDqOP0uWNY10EtG7qOvRTzujA-LUVA30Ff7eeac,1935
20
- soia_client-1.0.9.dist-info/METADATA,sha256=ACwdLcQ3vRHTS1sWzLRk1A14mQxlhEP7WX0KtQU_8FY,1666
21
- soia_client-1.0.9.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
22
- soia_client-1.0.9.dist-info/top_level.txt,sha256=2vPmAo5G0SrCxYrNdJKJJVdpalYppgjO2mmz2PtsFUI,8
23
- soia_client-1.0.9.dist-info/RECORD,,
22
+ soia_client-1.0.11.dist-info/METADATA,sha256=c0HD3ulDxxyRoi2V-r6tOxlq0oI-hwm16X_ejUExWO0,1667
23
+ soia_client-1.0.11.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
24
+ soia_client-1.0.11.dist-info/top_level.txt,sha256=2vPmAo5G0SrCxYrNdJKJJVdpalYppgjO2mmz2PtsFUI,8
25
+ soia_client-1.0.11.dist-info/RECORD,,
soialib/_.py ADDED
@@ -0,0 +1,3 @@
1
+ from typing import Any, Final
2
+
3
+ _: Final[Any] = None
soialib/__init__.py CHANGED
@@ -6,12 +6,14 @@ from soialib.serializers import (
6
6
  optional_serializer,
7
7
  primitive_serializer,
8
8
  )
9
+ from soialib.service_client import ServiceClient
9
10
  from soialib.timestamp import Timestamp
10
11
 
11
12
  __all__ = [
12
13
  "KeyedItems",
13
14
  "Method",
14
15
  "Serializer",
16
+ "ServiceClient",
15
17
  "Timestamp",
16
18
  "array_serializer",
17
19
  "optional_serializer",
soialib/impl/arrays.py CHANGED
@@ -118,14 +118,14 @@ def _new_listuple_class() -> type:
118
118
  return Listuple
119
119
 
120
120
 
121
- def _new_keyed_items_class(attributes: tuple[str, ...], default_expr: ExprLike):
121
+ def _new_keyed_items_class(key_attributes: tuple[str, ...], default_expr: ExprLike):
122
122
  key_items = make_function(
123
123
  name="key_items",
124
124
  params=["items"],
125
125
  body=[
126
126
  "ret = {}",
127
127
  "for item in items:",
128
- f" ret[item.{'.'.join(attributes)}] = item",
128
+ f" ret[item.{'.'.join(key_attributes)}] = item",
129
129
  "return ret",
130
130
  ],
131
131
  )
soialib/impl/structs.py CHANGED
@@ -457,6 +457,8 @@ def _make_eq_fn(
457
457
  """
458
458
 
459
459
  builder = BodyBuilder()
460
+ builder.append_ln("if other is self:")
461
+ builder.append_ln(" return True")
460
462
  builder.append_ln("if other.__class__ is self.__class__:")
461
463
  operands: list[ExprLike]
462
464
  if fields:
@@ -0,0 +1,70 @@
1
+ import http.client
2
+ from typing import Final, Mapping, TypeVar
3
+ from urllib.parse import urlparse
4
+
5
+ from soialib import Method
6
+
7
+ Request = TypeVar("Request")
8
+ Response = TypeVar("Response")
9
+
10
+
11
+ class ServiceClient:
12
+ _scheme: Final[str]
13
+ _host: Final[str] # May include the port
14
+ _path: Final[str]
15
+
16
+ def __init__(self, service_url: str, use_https: bool = False):
17
+ parsed_url = urlparse(service_url)
18
+ if parsed_url.query:
19
+ raise ValueError("Service URL must not contain a query string")
20
+ scheme = parsed_url.scheme
21
+ if scheme not in ["http", "https"]:
22
+ raise ValueError("Service URL must start with http:// or https://")
23
+ self._scheme = scheme
24
+ self._host = parsed_url.netloc
25
+ self._path = parsed_url.path
26
+
27
+ def invoke_remote(
28
+ self,
29
+ method: Method[Request, Response],
30
+ request: Request,
31
+ headers: Mapping[str, str] = {},
32
+ ) -> Response:
33
+ request_json = method.request_serializer.to_json_code(request)
34
+ body = ":".join(
35
+ [
36
+ method.name,
37
+ str(method.number),
38
+ "",
39
+ request_json,
40
+ ]
41
+ )
42
+ headers = {
43
+ **headers,
44
+ "Content-Type": "text/plain; charset=utf-8",
45
+ "Content-Length": str(len(body)),
46
+ }
47
+ if self._scheme == "https":
48
+ conn = http.client.HTTPSConnection(self._host)
49
+ else:
50
+ conn = http.client.HTTPConnection(self._host)
51
+ try:
52
+ conn.request(
53
+ "POST",
54
+ self._path,
55
+ body=body,
56
+ headers=headers,
57
+ )
58
+ response = conn.getresponse()
59
+ status_code = response.status
60
+ content_type = response.getheader("Content-Type")
61
+ response_data = response.read().decode("utf-8", errors="ignore")
62
+ finally:
63
+ conn.close()
64
+ if status_code in range(200, 300):
65
+ return method.response_serializer.from_json_code(response_data)
66
+ else:
67
+ message = f"HTTP response status {status_code}"
68
+ if content_type == "text/plain":
69
+ message = f"{message}: {response_data}"
70
+ raise RuntimeError(message)