@vercel/python 6.18.1 → 6.19.0
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.
- package/package.json +3 -3
- package/vc_init_dev.py +182 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vercel/python",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.19.0",
|
|
4
4
|
"main": "./dist/index.js",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/python",
|
|
@@ -35,9 +35,9 @@
|
|
|
35
35
|
"which": "3.0.0",
|
|
36
36
|
"get-port": "5.1.1",
|
|
37
37
|
"is-port-reachable": "3.1.0",
|
|
38
|
-
"@vercel/
|
|
38
|
+
"@vercel/build-utils": "13.6.1",
|
|
39
39
|
"@vercel/error-utils": "2.0.3",
|
|
40
|
-
"@vercel/
|
|
40
|
+
"@vercel/python-runtime": "0.5.3"
|
|
41
41
|
},
|
|
42
42
|
"scripts": {
|
|
43
43
|
"build": "node ../../utils/build-builder.mjs",
|
package/vc_init_dev.py
CHANGED
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
import sys
|
|
5
5
|
import os
|
|
6
6
|
import inspect
|
|
7
|
+
import logging
|
|
8
|
+
import logging.config
|
|
7
9
|
from os import path as _p
|
|
8
10
|
from importlib import util as _importlib_util
|
|
9
11
|
import mimetypes
|
|
@@ -23,6 +25,175 @@ def _color(text: str, code: str) -> str:
|
|
|
23
25
|
return f"{code}{text}{_RESET}"
|
|
24
26
|
|
|
25
27
|
|
|
28
|
+
# Configure logging to output DEBUG-WARNING to the stdout
|
|
29
|
+
# and ERROR-CRITICAL to the stderr.
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
# We need a custom filter for the stdout stream
|
|
33
|
+
# so it won't print anything higher than WARNING.
|
|
34
|
+
class _MaxLevelFilter(logging.Filter):
|
|
35
|
+
def __init__(self, max_level):
|
|
36
|
+
super().__init__()
|
|
37
|
+
self.max_level = max_level
|
|
38
|
+
|
|
39
|
+
def filter(self, record):
|
|
40
|
+
return record.levelno <= self.max_level
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def _build_log_config(loggers, _filter_ref=None) -> dict:
|
|
44
|
+
if _filter_ref is None:
|
|
45
|
+
_filter_ref = "vc_init_dev._MaxLevelFilter"
|
|
46
|
+
|
|
47
|
+
return {
|
|
48
|
+
"version": 1,
|
|
49
|
+
"disable_existing_loggers": False,
|
|
50
|
+
"filters": {
|
|
51
|
+
"max_warning": {
|
|
52
|
+
"()": _filter_ref,
|
|
53
|
+
"max_level": logging.WARNING,
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
"handlers": {
|
|
57
|
+
"stdout": {
|
|
58
|
+
"class": "logging.StreamHandler",
|
|
59
|
+
"stream": "ext://sys.stdout",
|
|
60
|
+
"filters": ["max_warning"],
|
|
61
|
+
},
|
|
62
|
+
"stderr": {
|
|
63
|
+
"class": "logging.StreamHandler",
|
|
64
|
+
"stream": "ext://sys.stderr",
|
|
65
|
+
"level": "ERROR",
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
"loggers": loggers,
|
|
69
|
+
"root": {
|
|
70
|
+
"handlers": ["stdout", "stderr"],
|
|
71
|
+
"level": "INFO",
|
|
72
|
+
},
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def _setup_server_log_routing(logger_name=None):
|
|
77
|
+
loggers = {}
|
|
78
|
+
|
|
79
|
+
if logger_name:
|
|
80
|
+
loggers[logger_name] = {
|
|
81
|
+
"handlers": ["stdout", "stderr"],
|
|
82
|
+
"level": "INFO",
|
|
83
|
+
"propagate": False,
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
logging.config.dictConfig(
|
|
87
|
+
_build_log_config(
|
|
88
|
+
loggers=loggers,
|
|
89
|
+
_filter_ref=_MaxLevelFilter,
|
|
90
|
+
),
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def _build_uvicorn_log_config(default_fmt=None, access_fmt=None) -> dict:
|
|
95
|
+
try:
|
|
96
|
+
from uvicorn.config import LOGGING_CONFIG # type: ignore
|
|
97
|
+
|
|
98
|
+
uvicorn_fmts = LOGGING_CONFIG["formatters"]
|
|
99
|
+
except ImportError:
|
|
100
|
+
uvicorn_fmts = {
|
|
101
|
+
"default": {
|
|
102
|
+
"()": "uvicorn.logging.DefaultFormatter",
|
|
103
|
+
"fmt": "%(levelprefix)s %(message)s",
|
|
104
|
+
"use_colors": None,
|
|
105
|
+
},
|
|
106
|
+
"access": {
|
|
107
|
+
"()": "uvicorn.logging.AccessFormatter",
|
|
108
|
+
"fmt": '%(levelprefix)s %(client_addr)s - "%(request_line)s" %(status_code)s',
|
|
109
|
+
},
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
cfg = _build_log_config(
|
|
113
|
+
loggers={
|
|
114
|
+
"uvicorn": {
|
|
115
|
+
"handlers": ["stdout", "stderr"],
|
|
116
|
+
"level": "INFO",
|
|
117
|
+
"propagate": False,
|
|
118
|
+
},
|
|
119
|
+
"uvicorn.error": {"level": "INFO"},
|
|
120
|
+
"uvicorn.access": {
|
|
121
|
+
"handlers": ["access"],
|
|
122
|
+
"level": "INFO",
|
|
123
|
+
"propagate": False,
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
if default_fmt is None:
|
|
129
|
+
default_fmt = {**uvicorn_fmts["default"], "use_colors": not _NO_COLOR}
|
|
130
|
+
|
|
131
|
+
if access_fmt is None:
|
|
132
|
+
access_fmt = {**uvicorn_fmts["access"], "use_colors": not _NO_COLOR}
|
|
133
|
+
|
|
134
|
+
cfg["formatters"] = {"default": default_fmt, "access": access_fmt}
|
|
135
|
+
cfg["handlers"]["stdout"]["formatter"] = "default"
|
|
136
|
+
cfg["handlers"]["stderr"]["formatter"] = "default"
|
|
137
|
+
cfg["handlers"]["access"] = {
|
|
138
|
+
"class": "logging.StreamHandler",
|
|
139
|
+
"stream": "ext://sys.stdout",
|
|
140
|
+
"formatter": "access",
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return cfg
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def _build_hypercorn_log_config():
|
|
147
|
+
return _build_log_config(
|
|
148
|
+
loggers={
|
|
149
|
+
"hypercorn.error": {
|
|
150
|
+
"handlers": ["stdout", "stderr"],
|
|
151
|
+
"level": "INFO",
|
|
152
|
+
"propagate": False,
|
|
153
|
+
},
|
|
154
|
+
"hypercorn.access": {
|
|
155
|
+
"handlers": ["stdout"],
|
|
156
|
+
"level": "INFO",
|
|
157
|
+
"propagate": False,
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
def _patch_fastapi_cli_log_config():
|
|
164
|
+
try:
|
|
165
|
+
import fastapi_cli.utils.cli as _fcli # type: ignore
|
|
166
|
+
import fastapi_cli.cli as _fcli_cli # type: ignore
|
|
167
|
+
|
|
168
|
+
_orig_get_config = _fcli.get_uvicorn_log_config # to ensure it's there
|
|
169
|
+
_fcli_cli.get_uvicorn_log_config # to ensure it's there
|
|
170
|
+
except (ImportError, AttributeError):
|
|
171
|
+
return
|
|
172
|
+
|
|
173
|
+
def _get_routed_config():
|
|
174
|
+
orig = _orig_get_config()
|
|
175
|
+
return _build_uvicorn_log_config(
|
|
176
|
+
default_fmt={
|
|
177
|
+
"()": "fastapi_cli.utils.cli.CustomFormatter",
|
|
178
|
+
"fmt": orig["formatters"]["default"].get(
|
|
179
|
+
"fmt", "%(levelprefix)s %(message)s"
|
|
180
|
+
),
|
|
181
|
+
"use_colors": orig["formatters"]["default"].get("use_colors"),
|
|
182
|
+
},
|
|
183
|
+
access_fmt={
|
|
184
|
+
"()": "fastapi_cli.utils.cli.CustomFormatter",
|
|
185
|
+
"fmt": orig["formatters"]["access"].get(
|
|
186
|
+
"fmt",
|
|
187
|
+
"%(levelprefix)s %(client_addr)s - '%(request_line)s' %(status_code)s",
|
|
188
|
+
),
|
|
189
|
+
},
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
_fcli.get_uvicorn_log_config = _get_routed_config
|
|
193
|
+
# we need to patch the local binding as well
|
|
194
|
+
_fcli_cli.get_uvicorn_log_config = _get_routed_config
|
|
195
|
+
|
|
196
|
+
|
|
26
197
|
def _normalize_service_route_prefix(raw_prefix):
|
|
27
198
|
if not raw_prefix:
|
|
28
199
|
return ""
|
|
@@ -71,6 +242,11 @@ def _strip_service_route_prefix(path_value):
|
|
|
71
242
|
return path_value, ""
|
|
72
243
|
|
|
73
244
|
|
|
245
|
+
# Pre-configure the root logger before user module import so that any log
|
|
246
|
+
# calls emitted at import time are routed to stdout/stderr correctly.
|
|
247
|
+
_setup_server_log_routing()
|
|
248
|
+
|
|
249
|
+
|
|
74
250
|
# ASGI/WSGI app detection
|
|
75
251
|
_MODULE_NAME = "__VC_DEV_MODULE_NAME__"
|
|
76
252
|
_ENTRY_ABS = "__VC_DEV_ENTRY_ABS__"
|
|
@@ -355,7 +531,8 @@ if __name__ == "__main__":
|
|
|
355
531
|
try:
|
|
356
532
|
from werkzeug.serving import run_simple # type: ignore
|
|
357
533
|
|
|
358
|
-
|
|
534
|
+
_setup_server_log_routing("werkzeug")
|
|
535
|
+
run_simple(host, port, wsgi_app, use_reloader=True, threaded=True)
|
|
359
536
|
except Exception:
|
|
360
537
|
print(
|
|
361
538
|
_color(
|
|
@@ -376,6 +553,7 @@ if __name__ == "__main__":
|
|
|
376
553
|
fastapi_dev = None
|
|
377
554
|
|
|
378
555
|
if fastapi_dev is not None:
|
|
556
|
+
_patch_fastapi_cli_log_config()
|
|
379
557
|
fastapi_dev(
|
|
380
558
|
entrypoint="vc_init_dev:asgi_app", host=host, port=port, reload=True
|
|
381
559
|
)
|
|
@@ -390,6 +568,7 @@ if __name__ == "__main__":
|
|
|
390
568
|
port=port,
|
|
391
569
|
use_colors=True,
|
|
392
570
|
reload=True,
|
|
571
|
+
log_config=_build_uvicorn_log_config(),
|
|
393
572
|
)
|
|
394
573
|
except Exception:
|
|
395
574
|
try:
|
|
@@ -399,6 +578,8 @@ if __name__ == "__main__":
|
|
|
399
578
|
|
|
400
579
|
config = Config()
|
|
401
580
|
config.bind = [f"{host}:{port}"]
|
|
581
|
+
config.use_reloader = True
|
|
582
|
+
config.logconfig_dict = _build_hypercorn_log_config()
|
|
402
583
|
|
|
403
584
|
async def _run():
|
|
404
585
|
await serve(asgi_app, config)
|