libentry 1.13__py3-none-any.whl → 1.15__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.
libentry/schema.py CHANGED
@@ -11,9 +11,10 @@ __all__ = [
11
11
  ]
12
12
 
13
13
  import enum
14
- from dataclasses import dataclass
14
+ from dataclasses import asdict, dataclass, is_dataclass
15
15
  from inspect import signature
16
- from typing import Any, Iterable, List, Literal, Mapping, MutableMapping, NoReturn, Optional, Sequence, Union, get_args, \
16
+ from typing import Any, Dict, Iterable, List, Literal, Mapping, MutableMapping, NoReturn, Optional, Sequence, Union, \
17
+ get_args, \
17
18
  get_origin
18
19
 
19
20
  from pydantic import BaseModel, Field, create_model
@@ -27,6 +28,7 @@ class SchemaField(BaseModel):
27
28
  is_required: bool = Field(True)
28
29
  title: str = Field()
29
30
  description: Optional[str] = Field(None)
31
+ metadata: Dict[str, Any] = Field(default_factory=dict)
30
32
 
31
33
 
32
34
  class Schema(BaseModel):
@@ -85,7 +87,7 @@ def _parse_dict(context: ParseContext):
85
87
  key_type = "str"
86
88
  value_type = parse_type(dict_args[1], context.schemas)
87
89
  if isinstance(value_type, list):
88
- raise TypeError("\"Union\" cannot be used as the type of list elements.")
90
+ raise TypeError("\"Union\" cannot be used as the type of dict elements.")
89
91
  return f"Dict[{key_type},{value_type}]"
90
92
  else:
91
93
  return "Dict"
@@ -127,18 +129,25 @@ def _parse_base_model(context: ParseContext):
127
129
  fields = origin.model_fields
128
130
  assert isinstance(fields, Mapping)
129
131
  for name, field in fields.items():
130
-
131
132
  try:
132
- schema.fields.append(SchemaField(
133
+ default = field.default if field.default is not PydanticUndefined else None
134
+ title = field.title
135
+ if title is None:
136
+ title = "".join(word.capitalize() for word in name.split("_"))
137
+ schema_field = SchemaField(
133
138
  name=name,
134
139
  type=parse_type(field.annotation, context.schemas),
135
- default=field.default if field.default is not PydanticUndefined else None,
140
+ default=default,
136
141
  is_required=field.is_required(),
137
- title="".join(word.capitalize() for word in name.split("_")),
142
+ title=title,
138
143
  description=field.description
139
- ))
144
+ )
140
145
  except TypeError as e:
141
146
  raise TypeError(f"{name}: {str(e)}")
147
+ for md in field.metadata:
148
+ if is_dataclass(md):
149
+ schema_field.metadata.update(asdict(md))
150
+ schema.fields.append(schema_field)
142
151
  context.schemas[model_name] = schema
143
152
 
144
153
  return model_name
@@ -177,13 +186,13 @@ def generic_parser(fn):
177
186
 
178
187
  @generic_parser
179
188
  def _parse_any(context: ParseContext):
180
- if context.origin is Any:
189
+ if context.origin is Any or str(context.origin) == str(Any):
181
190
  return "Any"
182
191
 
183
192
 
184
193
  @generic_parser
185
194
  def _parse_union(context: ParseContext):
186
- if context.origin is Union:
195
+ if context.origin is Union or str(context.origin) == str(Union):
187
196
  return [
188
197
  parse_type(arg, context.schemas)
189
198
  for arg in get_args(context.annotation)
@@ -192,7 +201,7 @@ def _parse_union(context: ParseContext):
192
201
 
193
202
  @generic_parser
194
203
  def _parse_literal(context: ParseContext):
195
- if context.origin is Literal:
204
+ if context.origin is Literal or str(context.origin) == str(Literal):
196
205
  enum_args = get_args(context.annotation)
197
206
  return f"Enum[{','.join(map(str, enum_args))}]"
198
207
 
libentry/service/flask.py CHANGED
@@ -149,8 +149,9 @@ class FlaskWrapper:
149
149
  params = signature(fn).parameters
150
150
  if len(params) == 1:
151
151
  for name, value in params.items():
152
- if issubclass(value.annotation, BaseModel):
153
- self.input_schema = value.annotation
152
+ annotation = value.annotation
153
+ if isinstance(annotation, type) and issubclass(annotation, BaseModel):
154
+ self.input_schema = annotation
154
155
 
155
156
  def __call__(self):
156
157
  if request.method == "POST":
@@ -161,6 +162,11 @@ class FlaskWrapper:
161
162
  return self.app.error(f"Unsupported method \"{request.method}\".")
162
163
 
163
164
  if self.input_schema is not None:
165
+ # Note that "input_schema is not None" means:
166
+ # (1) The function has only one argument;
167
+ # (2) The arguments is a BaseModel.
168
+ # In this case, the request data can be directly validated as a "BaseModel" and
169
+ # subsequently passed to the function as a single object.
164
170
  try:
165
171
  input_data = self.input_schema.model_validate(input_json)
166
172
  response = self.fn(input_data)
@@ -169,6 +175,8 @@ class FlaskWrapper:
169
175
  raise e
170
176
  return self.app.error(self.dumper.dump_error(e))
171
177
  else:
178
+ # The function has multiple arguments, and the request data bundle them as a single object.
179
+ # So, they should be unpacked before pass to the function.
172
180
  try:
173
181
  response = self.fn(**input_json)
174
182
  except Exception as e:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: libentry
3
- Version: 1.13
3
+ Version: 1.15
4
4
  Summary: Entries for experimental utilities.
5
5
  Home-page: https://github.com/XoriieInpottn/libentry
6
6
  Author: xi
@@ -6,18 +6,18 @@ libentry/executor.py,sha256=cTV0WxJi0nU1TP-cOwmeodN8DD6L1691M2HIQsJtGrU,6582
6
6
  libentry/experiment.py,sha256=ejgAHDXWIe9x4haUzIFuz1WasLY0_aD1z_vyEVGjTu8,4922
7
7
  libentry/json.py,sha256=1-Kv5ZRb5dBrOTU84n6sZtYZV3xE-O6wEt_--ynbSaU,1209
8
8
  libentry/logging.py,sha256=IiYoCUzm8XTK1fduA-NA0FI2Qz_m81NEPV3d3tEfgdI,1349
9
- libentry/schema.py,sha256=ZlQnqUrL0YQ5koZnka7RNfOSzaH5llQ5XhQI6ig02xk,7629
9
+ libentry/schema.py,sha256=BO7EE7i43Cb4xn_OLsBM-HDwWOT6V5fPs91Am3QqnNQ,8178
10
10
  libentry/server.py,sha256=gYPoZXd0umlDYZf-6ZV0_vJadg3YQvnLDc6JFDJh9jc,1503
11
11
  libentry/service/__init__.py,sha256=1oLL20yLB1GL9IbFiZD8OReDqiCpFr-yetIR6x1cNkI,23
12
12
  libentry/service/common.py,sha256=OVaW2afgKA6YqstJmtnprBCqQEUZEWotZ6tHavmJJeU,42
13
- libentry/service/flask.py,sha256=_5bU9A44CmsRQFGMOuaUEZpJqVs08FAblVcCIphCQNY,11986
13
+ libentry/service/flask.py,sha256=0sYFI8TJY65AEs-gNJdoKqg8_eWk4rSOfKMPauzHQLc,12550
14
14
  libentry/service/list.py,sha256=ElHWhTgShGOhaxMUEwVbMXos0NQKjHsODboiQ-3AMwE,1397
15
15
  libentry/service/running.py,sha256=FrPJoJX6wYxcHIysoatAxhW3LajCCm0Gx6l7__6sULQ,5105
16
16
  libentry/service/start.py,sha256=mZT7b9rVULvzy9GTZwxWnciCHgv9dbGN2JbxM60OMn4,1270
17
17
  libentry/service/stop.py,sha256=wOpwZgrEJ7QirntfvibGq-XsTC6b3ELhzRW2zezh-0s,1187
18
- libentry-1.13.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
19
- libentry-1.13.dist-info/METADATA,sha256=5FKTWuTb2otAHMY4pZThJ21OlZyFv2kp402tUNolqyI,791
20
- libentry-1.13.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
21
- libentry-1.13.dist-info/top_level.txt,sha256=u2uF6-X5fn2Erf9PYXOg_6tntPqTpyT-yzUZrltEd6I,9
22
- libentry-1.13.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
23
- libentry-1.13.dist-info/RECORD,,
18
+ libentry-1.15.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
19
+ libentry-1.15.dist-info/METADATA,sha256=Vlvcl_kB5qp_0xM_eLNJykdEzv0slsqh7LitUa-dpo4,791
20
+ libentry-1.15.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
21
+ libentry-1.15.dist-info/top_level.txt,sha256=u2uF6-X5fn2Erf9PYXOg_6tntPqTpyT-yzUZrltEd6I,9
22
+ libentry-1.15.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
23
+ libentry-1.15.dist-info/RECORD,,