future-framework 3.1.1__tar.gz → 3.1.2__tar.gz
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.
- {future_framework-3.1.1 → future_framework-3.1.2}/PKG-INFO +1 -1
- {future_framework-3.1.1 → future_framework-3.1.2}/future/logger.py +43 -26
- {future_framework-3.1.1 → future_framework-3.1.2}/pyproject.toml +1 -1
- {future_framework-3.1.1 → future_framework-3.1.2}/pyproject.toml.orig +1 -1
- {future_framework-3.1.1 → future_framework-3.1.2}/LICENSE +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/README.md +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/__init__.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/application.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/authentication/Auth0Authentication.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/authentication/AzureADAuthentication.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/authentication/BasicAuthentication.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/authentication/KerberosAuthentication.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/authentication/KeycloakAuthentication.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/authentication/OAuth2Authentication.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/authentication/OpenIdConnectAuthentication.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/authentication/SAMLAuthentication.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/authentication/__init__.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/cli.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/controllers/DebugController.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/controllers/GraphQLController.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/controllers/OpenAPIController.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/controllers/WebSocketController.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/controllers/WelcomeController.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/controllers/__init__.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/database.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/databases/ClickhouseDatabase.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/databases/ElasticsearchDatabase.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/databases/MongoDBDatabase.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/databases/MySQLDatabase.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/databases/PostgresDatabase.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/databases/RedisDatabase.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/databases/SQLiteDatabase.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/databases/__init__.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/exceptions.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/interfaces/IAuthentication.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/interfaces/IController.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/interfaces/IDatabase.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/interfaces/IMiddleware.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/interfaces/IModel.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/interfaces/IPlugin.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/interfaces/ITask.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/interfaces/__init__.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/interfacing.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/lifespan.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/middleware/BruteforcePreventionMiddleware.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/middleware/CORSMiddleware.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/middleware/CSRFMiddleware.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/middleware/GZipMiddleware.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/middleware/HTAccessConfuserMiddleware.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/middleware/HeaderConfuserMiddleware.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/middleware/RateLimitMiddleware.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/middleware/ResponseCodeConfuserMiddleware.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/middleware/SQLiConfuserMiddleware.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/middleware/ScopeValidationMiddleware.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/middleware/SessionMiddleware.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/middleware/TestMiddlewareRequest.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/middleware/TestMiddlewareResponse.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/middleware/WebServerConfuserMiddleware.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/middleware/__init__.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/migrations.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/models/PostModel.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/models/Query.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/models/UserModel.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/models/__init__.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/openapi.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/plugins/ElasticsearchPlugin.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/plugins/__init__.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/request.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/response.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/routing.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/scheduling.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/seeder.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/settings.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/tasks/CheckDNSTask.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/tasks/CheckDiskUsageTask.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/tasks/CheckHttpStatusTask.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/tasks/CheckMemoryUsageTask.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/tasks/CheckSSHBannerTask.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/tasks/CheckSystemUptimeTask.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/tasks/DailyBackupTask.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/tasks/SyncTaskExample.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/tasks/__init__.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/taskscheduler.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/testclient.py +0 -0
- {future_framework-3.1.1 → future_framework-3.1.2}/future/types.py +0 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import atexit
|
|
2
|
+
import http
|
|
2
3
|
import logging
|
|
3
4
|
import logging.config
|
|
4
5
|
import logging.handlers
|
|
@@ -11,36 +12,41 @@ from uvicorn.logging import AccessFormatter, DefaultFormatter
|
|
|
11
12
|
from future.settings import LOGGING_CONFIG
|
|
12
13
|
|
|
13
14
|
|
|
15
|
+
RESET = "\033[0m"
|
|
16
|
+
LEVEL_COLORS = {
|
|
17
|
+
logging.DEBUG: "\033[36m", # Cyan
|
|
18
|
+
logging.INFO: "\033[32m", # Green
|
|
19
|
+
logging.WARNING: "\033[38;5;208m", # Orange
|
|
20
|
+
logging.ERROR: "\033[31m", # Red
|
|
21
|
+
logging.CRITICAL: "\033[91m", # Bright red
|
|
22
|
+
}
|
|
23
|
+
HTTP_STATUS_COLORS = {
|
|
24
|
+
1: "\033[96m", # Bright cyan
|
|
25
|
+
2: "\033[97m", # Bright white
|
|
26
|
+
3: "\033[92m", # Bright green
|
|
27
|
+
4: "\033[91m", # Bright red
|
|
28
|
+
5: "\033[94m", # Bright blue
|
|
29
|
+
}
|
|
30
|
+
DEFAULT_LOG_FORMAT = "%(asctime)s %(levelprefix)s %(message)s"
|
|
31
|
+
ACCESS_LOG_FORMAT = '%(asctime)s %(levelprefix)s %(client_addr)s - "%(request_line)s" %(status_code)s'
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _colorize(value: str, color: str | None) -> str:
|
|
35
|
+
return f"{color}{value}{RESET}" if color else value
|
|
36
|
+
|
|
37
|
+
|
|
14
38
|
class UtcTimestampFormatter:
|
|
15
39
|
"""Render log timestamps as unambiguous ISO 8601 UTC values."""
|
|
16
40
|
|
|
17
41
|
def formatTime(self, record: logging.LogRecord, datefmt: str | None = None) -> str:
|
|
18
42
|
return datetime.fromtimestamp(record.created, timezone.utc).isoformat(timespec="milliseconds").replace("+00:00", "Z")
|
|
19
43
|
|
|
44
|
+
def color_level_name(self, level_name: str, level_no: int) -> str:
|
|
45
|
+
return _colorize(level_name, LEVEL_COLORS.get(level_no))
|
|
20
46
|
|
|
21
|
-
# ANSI color codes
|
|
22
|
-
class ColoredFormatter(UtcTimestampFormatter, logging.Formatter):
|
|
23
|
-
"""Custom formatter with colors like uvicorn"""
|
|
24
47
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
"INFO": "\033[32m", # Green
|
|
28
|
-
"WARNING": "\033[33m", # Yellow
|
|
29
|
-
"ERROR": "\033[31m", # Red
|
|
30
|
-
"CRITICAL": "\033[35m", # Magenta
|
|
31
|
-
}
|
|
32
|
-
RESET = "\033[0m"
|
|
33
|
-
|
|
34
|
-
def format(self, record: logging.LogRecord) -> str:
|
|
35
|
-
message = super().format(record)
|
|
36
|
-
timestamp = self.formatTime(record)
|
|
37
|
-
levelname = record.levelname
|
|
38
|
-
if levelname in self.COLORS:
|
|
39
|
-
# Calculate padding based on original levelname length BEFORE adding colors
|
|
40
|
-
padding = " " * (9 - len(levelname)) # 9 is max level length (CRITICAL) + 1
|
|
41
|
-
colored_levelname = f"{self.COLORS[levelname]}{levelname}{self.RESET}"
|
|
42
|
-
return f"{timestamp} {colored_levelname}:{padding}{message}"
|
|
43
|
-
return f"{timestamp} {levelname}: {message}"
|
|
48
|
+
class ColoredFormatter(UtcTimestampFormatter, DefaultFormatter):
|
|
49
|
+
"""Shared timestamp and level formatter for Future and Uvicorn."""
|
|
44
50
|
|
|
45
51
|
|
|
46
52
|
class UvicornDefaultFormatter(UtcTimestampFormatter, DefaultFormatter):
|
|
@@ -50,6 +56,16 @@ class UvicornDefaultFormatter(UtcTimestampFormatter, DefaultFormatter):
|
|
|
50
56
|
class UvicornAccessFormatter(UtcTimestampFormatter, AccessFormatter):
|
|
51
57
|
"""Uvicorn access formatter using Future's UTC timestamp format."""
|
|
52
58
|
|
|
59
|
+
def get_status_code(self, status_code: int) -> str:
|
|
60
|
+
try:
|
|
61
|
+
status_phrase = http.HTTPStatus(status_code).phrase
|
|
62
|
+
except ValueError:
|
|
63
|
+
status_phrase = ""
|
|
64
|
+
status_and_phrase = f"{status_code} {status_phrase}"
|
|
65
|
+
if not self.use_colors:
|
|
66
|
+
return status_and_phrase
|
|
67
|
+
return _colorize(status_and_phrase, HTTP_STATUS_COLORS.get(status_code // 100))
|
|
68
|
+
|
|
53
69
|
|
|
54
70
|
def create_uvicorn_logging_config() -> dict[str, Any]:
|
|
55
71
|
"""Return a fresh Uvicorn logging config for each server invocation."""
|
|
@@ -59,12 +75,13 @@ def create_uvicorn_logging_config() -> dict[str, Any]:
|
|
|
59
75
|
"formatters": {
|
|
60
76
|
"default": {
|
|
61
77
|
"()": UvicornDefaultFormatter,
|
|
62
|
-
"fmt":
|
|
63
|
-
"use_colors":
|
|
78
|
+
"fmt": DEFAULT_LOG_FORMAT,
|
|
79
|
+
"use_colors": True,
|
|
64
80
|
},
|
|
65
81
|
"access": {
|
|
66
82
|
"()": UvicornAccessFormatter,
|
|
67
|
-
"fmt":
|
|
83
|
+
"fmt": ACCESS_LOG_FORMAT,
|
|
84
|
+
"use_colors": True,
|
|
68
85
|
},
|
|
69
86
|
},
|
|
70
87
|
"handlers": {
|
|
@@ -91,7 +108,7 @@ def create_uvicorn_logging_config() -> dict[str, Any]:
|
|
|
91
108
|
logging.config.dictConfig(LOGGING_CONFIG)
|
|
92
109
|
|
|
93
110
|
log = logging.getLogger("future")
|
|
94
|
-
formatter = ColoredFormatter(
|
|
111
|
+
formatter = ColoredFormatter(DEFAULT_LOG_FORMAT, use_colors=True)
|
|
95
112
|
|
|
96
113
|
# QueueHandler itself does not format; the listener's stdout handler does.
|
|
97
114
|
# Handler level NOTSET so Future's log.setLevel(APP_DEBUG) alone controls filtering.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{future_framework-3.1.1 → future_framework-3.1.2}/future/authentication/Auth0Authentication.py
RENAMED
|
File without changes
|
{future_framework-3.1.1 → future_framework-3.1.2}/future/authentication/AzureADAuthentication.py
RENAMED
|
File without changes
|
{future_framework-3.1.1 → future_framework-3.1.2}/future/authentication/BasicAuthentication.py
RENAMED
|
File without changes
|
{future_framework-3.1.1 → future_framework-3.1.2}/future/authentication/KerberosAuthentication.py
RENAMED
|
File without changes
|
{future_framework-3.1.1 → future_framework-3.1.2}/future/authentication/KeycloakAuthentication.py
RENAMED
|
File without changes
|
{future_framework-3.1.1 → future_framework-3.1.2}/future/authentication/OAuth2Authentication.py
RENAMED
|
File without changes
|
|
File without changes
|
{future_framework-3.1.1 → future_framework-3.1.2}/future/authentication/SAMLAuthentication.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{future_framework-3.1.1 → future_framework-3.1.2}/future/middleware/HTAccessConfuserMiddleware.py
RENAMED
|
File without changes
|
{future_framework-3.1.1 → future_framework-3.1.2}/future/middleware/HeaderConfuserMiddleware.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{future_framework-3.1.1 → future_framework-3.1.2}/future/middleware/SQLiConfuserMiddleware.py
RENAMED
|
File without changes
|
{future_framework-3.1.1 → future_framework-3.1.2}/future/middleware/ScopeValidationMiddleware.py
RENAMED
|
File without changes
|
|
File without changes
|
{future_framework-3.1.1 → future_framework-3.1.2}/future/middleware/TestMiddlewareRequest.py
RENAMED
|
File without changes
|
{future_framework-3.1.1 → future_framework-3.1.2}/future/middleware/TestMiddlewareResponse.py
RENAMED
|
File without changes
|
{future_framework-3.1.1 → future_framework-3.1.2}/future/middleware/WebServerConfuserMiddleware.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|