libentry 1.12__py3-none-any.whl → 1.14__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 +13 -8
- libentry/service/flask.py +18 -6
- {libentry-1.12.dist-info → libentry-1.14.dist-info}/METADATA +1 -1
- {libentry-1.12.dist-info → libentry-1.14.dist-info}/RECORD +8 -8
- {libentry-1.12.dist-info → libentry-1.14.dist-info}/LICENSE +0 -0
- {libentry-1.12.dist-info → libentry-1.14.dist-info}/WHEEL +0 -0
- {libentry-1.12.dist-info → libentry-1.14.dist-info}/top_level.txt +0 -0
- {libentry-1.12.dist-info → libentry-1.14.dist-info}/zip-safe +0 -0
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,
|
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):
|
@@ -127,18 +129,21 @@ 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
|
-
|
133
|
+
schema_field = SchemaField(
|
133
134
|
name=name,
|
134
135
|
type=parse_type(field.annotation, context.schemas),
|
135
136
|
default=field.default if field.default is not PydanticUndefined else None,
|
136
137
|
is_required=field.is_required(),
|
137
138
|
title="".join(word.capitalize() for word in name.split("_")),
|
138
139
|
description=field.description
|
139
|
-
)
|
140
|
+
)
|
140
141
|
except TypeError as e:
|
141
142
|
raise TypeError(f"{name}: {str(e)}")
|
143
|
+
for md in field.metadata:
|
144
|
+
if is_dataclass(md):
|
145
|
+
schema_field.metadata.update(asdict(md))
|
146
|
+
schema.fields.append(schema_field)
|
142
147
|
context.schemas[model_name] = schema
|
143
148
|
|
144
149
|
return model_name
|
@@ -177,13 +182,13 @@ def generic_parser(fn):
|
|
177
182
|
|
178
183
|
@generic_parser
|
179
184
|
def _parse_any(context: ParseContext):
|
180
|
-
if context.origin is Any:
|
185
|
+
if context.origin is Any or str(context.origin) == str(Any):
|
181
186
|
return "Any"
|
182
187
|
|
183
188
|
|
184
189
|
@generic_parser
|
185
190
|
def _parse_union(context: ParseContext):
|
186
|
-
if context.origin is Union:
|
191
|
+
if context.origin is Union or str(context.origin) == str(Union):
|
187
192
|
return [
|
188
193
|
parse_type(arg, context.schemas)
|
189
194
|
for arg in get_args(context.annotation)
|
@@ -192,7 +197,7 @@ def _parse_union(context: ParseContext):
|
|
192
197
|
|
193
198
|
@generic_parser
|
194
199
|
def _parse_literal(context: ParseContext):
|
195
|
-
if context.origin is Literal:
|
200
|
+
if context.origin is Literal or str(context.origin) == str(Literal):
|
196
201
|
enum_args = get_args(context.annotation)
|
197
202
|
return f"Enum[{','.join(map(str, enum_args))}]"
|
198
203
|
|
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
|
-
|
153
|
-
|
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:
|
@@ -334,21 +342,25 @@ def run_service(
|
|
334
342
|
port: int = 8888,
|
335
343
|
num_workers: int = 1,
|
336
344
|
num_threads: int = 20,
|
337
|
-
num_connections: Optional[int] =
|
338
|
-
backlog: Optional[int] =
|
345
|
+
num_connections: Optional[int] = 1000,
|
346
|
+
backlog: Optional[int] = 1000,
|
339
347
|
worker_class: str = "gthread",
|
340
348
|
timeout: int = 60,
|
341
349
|
keyfile: Optional[str] = None,
|
342
350
|
certfile: Optional[str] = None
|
343
351
|
):
|
344
352
|
logger.info("Starting gunicorn server.")
|
353
|
+
if num_connections is None or num_connections < num_threads * 2:
|
354
|
+
num_connections = num_threads * 2
|
355
|
+
if backlog is None or backlog < num_threads * 2:
|
356
|
+
backlog = num_threads * 2
|
345
357
|
options = {
|
346
358
|
"bind": f"{host}:{port}",
|
347
359
|
"workers": num_workers,
|
348
360
|
"threads": num_threads,
|
349
361
|
"timeout": timeout,
|
350
|
-
"worker_connections": num_connections
|
351
|
-
"backlog": backlog
|
362
|
+
"worker_connections": num_connections,
|
363
|
+
"backlog": backlog,
|
352
364
|
"keyfile": keyfile,
|
353
365
|
"certfile": certfile,
|
354
366
|
"worker_class": worker_class
|
@@ -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=
|
9
|
+
libentry/schema.py,sha256=zXqRsz9-29WdjVFJAJ4qJPyGerzRApHviMxfB1dE6bM,8024
|
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=
|
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.
|
19
|
-
libentry-1.
|
20
|
-
libentry-1.
|
21
|
-
libentry-1.
|
22
|
-
libentry-1.
|
23
|
-
libentry-1.
|
18
|
+
libentry-1.14.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
19
|
+
libentry-1.14.dist-info/METADATA,sha256=rJKa26tvjSA1n7BQRQxGUnekJEROocjRIhpNAv8pTfM,791
|
20
|
+
libentry-1.14.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
|
21
|
+
libentry-1.14.dist-info/top_level.txt,sha256=u2uF6-X5fn2Erf9PYXOg_6tntPqTpyT-yzUZrltEd6I,9
|
22
|
+
libentry-1.14.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
23
|
+
libentry-1.14.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|