Spaces:
Sleeping
Sleeping
Update main.py
Browse files
main.py
CHANGED
|
@@ -22,41 +22,18 @@ from urllib.error import HTTPError
|
|
| 22 |
# Load optional .env if present in same directory
|
| 23 |
load_dotenv()
|
| 24 |
|
| 25 |
-
import sys
|
| 26 |
-
|
| 27 |
# ==============================================================================
|
| 28 |
# LOGGING (Task 5)
|
| 29 |
# ==============================================================================
|
| 30 |
-
# Force line buffering for standard output to guarantee HF Spaces captures it
|
| 31 |
-
try:
|
| 32 |
-
sys.stdout.reconfigure(line_buffering=True)
|
| 33 |
-
sys.stderr.reconfigure(line_buffering=True)
|
| 34 |
-
except AttributeError:
|
| 35 |
-
pass # Python < 3.7 fallback
|
| 36 |
-
|
| 37 |
IST = timezone(timedelta(hours=5, minutes=30))
|
| 38 |
logging.Formatter.converter = lambda *args: datetime.fromtimestamp(args[-1], tz=IST).timetuple()
|
| 39 |
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
logger
|
| 46 |
-
|
| 47 |
-
if not logger.handlers:
|
| 48 |
-
# Explicitly attach to stdout
|
| 49 |
-
stdout_handler = logging.StreamHandler(sys.stdout)
|
| 50 |
-
stdout_handler.setLevel(logging.INFO)
|
| 51 |
-
formatter = logging.Formatter(
|
| 52 |
-
fmt='[%(asctime)s] %(levelname)s: %(message)s',
|
| 53 |
-
datefmt='%I:%M:%S %p'
|
| 54 |
-
)
|
| 55 |
-
stdout_handler.setFormatter(formatter)
|
| 56 |
-
logger.addHandler(stdout_handler)
|
| 57 |
-
|
| 58 |
-
# Provide a root warning override just in case, but rely entirely on our dedicated logger
|
| 59 |
-
logging.getLogger("uvicorn.access").setLevel(logging.WARNING)
|
| 60 |
|
| 61 |
# ==============================================================================
|
| 62 |
# CONFIGURATION
|
|
@@ -686,7 +663,7 @@ def start_loop():
|
|
| 686 |
FAST_MODE_UNTIL = 0
|
| 687 |
time.sleep(sleep_seconds)
|
| 688 |
continue
|
| 689 |
-
|
| 690 |
process_tick()
|
| 691 |
|
| 692 |
# Polling loop: Wait in exact intervals without stacking HTTP request delays
|
|
@@ -728,13 +705,6 @@ def background_scraper_loop():
|
|
| 728 |
|
| 729 |
@asynccontextmanager
|
| 730 |
async def lifespan(app: FastAPI):
|
| 731 |
-
# Hijack Uvicorn's loggers recursively after they start up
|
| 732 |
-
logging.getLogger("uvicorn.access").setLevel(logging.WARNING)
|
| 733 |
-
for log_name in ("uvicorn", "uvicorn.error", "uvicorn.access", "fastapi"):
|
| 734 |
-
l = logging.getLogger(log_name)
|
| 735 |
-
l.handlers = []
|
| 736 |
-
l.propagate = True
|
| 737 |
-
|
| 738 |
# Startup
|
| 739 |
threading.Thread(target=background_scraper_loop, daemon=True).start()
|
| 740 |
yield
|
|
@@ -1022,6 +992,33 @@ if __name__ == "__main__":
|
|
| 1022 |
args = parser.parse_args()
|
| 1023 |
logger.debug(f"Parsed arguments: {args}")
|
| 1024 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1025 |
if args.list_all:
|
| 1026 |
list_all_events()
|
| 1027 |
elif args.latest:
|
|
@@ -1033,9 +1030,8 @@ if __name__ == "__main__":
|
|
| 1033 |
elif args.run:
|
| 1034 |
# Launch FastAPI which internally starts the loop
|
| 1035 |
port = int(os.getenv("PORT", 7860))
|
| 1036 |
-
|
| 1037 |
-
uvicorn.run(app, host="0.0.0.0", port=port)
|
| 1038 |
else:
|
| 1039 |
# Default behavior: run FastAPI
|
| 1040 |
port = int(os.getenv("PORT", 7860))
|
| 1041 |
-
uvicorn.run(app, host="0.0.0.0", port=port)
|
|
|
|
| 22 |
# Load optional .env if present in same directory
|
| 23 |
load_dotenv()
|
| 24 |
|
|
|
|
|
|
|
| 25 |
# ==============================================================================
|
| 26 |
# LOGGING (Task 5)
|
| 27 |
# ==============================================================================
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 28 |
IST = timezone(timedelta(hours=5, minutes=30))
|
| 29 |
logging.Formatter.converter = lambda *args: datetime.fromtimestamp(args[-1], tz=IST).timetuple()
|
| 30 |
|
| 31 |
+
logging.basicConfig(
|
| 32 |
+
level=logging.INFO,
|
| 33 |
+
format='[%(asctime)s] %(levelname)s: %(message)s',
|
| 34 |
+
datefmt='%I:%M:%S %p'
|
| 35 |
+
)
|
| 36 |
+
logger = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 37 |
|
| 38 |
# ==============================================================================
|
| 39 |
# CONFIGURATION
|
|
|
|
| 663 |
FAST_MODE_UNTIL = 0
|
| 664 |
time.sleep(sleep_seconds)
|
| 665 |
continue
|
| 666 |
+
|
| 667 |
process_tick()
|
| 668 |
|
| 669 |
# Polling loop: Wait in exact intervals without stacking HTTP request delays
|
|
|
|
| 705 |
|
| 706 |
@asynccontextmanager
|
| 707 |
async def lifespan(app: FastAPI):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 708 |
# Startup
|
| 709 |
threading.Thread(target=background_scraper_loop, daemon=True).start()
|
| 710 |
yield
|
|
|
|
| 992 |
args = parser.parse_args()
|
| 993 |
logger.debug(f"Parsed arguments: {args}")
|
| 994 |
|
| 995 |
+
# Uvicorn Logging Configuration Override for HF Spaces
|
| 996 |
+
# This completely replaces Uvicorn's silent default with an explicit stdout stream.
|
| 997 |
+
LOGGING_CONFIG = {
|
| 998 |
+
"version": 1,
|
| 999 |
+
"disable_existing_loggers": False,
|
| 1000 |
+
"formatters": {
|
| 1001 |
+
"default": {
|
| 1002 |
+
"()": "uvicorn.logging.DefaultFormatter",
|
| 1003 |
+
"fmt": "[%(asctime)s] %(levelname)s: %(message)s",
|
| 1004 |
+
"use_colors": None,
|
| 1005 |
+
},
|
| 1006 |
+
},
|
| 1007 |
+
"handlers": {
|
| 1008 |
+
"default": {
|
| 1009 |
+
"formatter": "default",
|
| 1010 |
+
"class": "logging.StreamHandler",
|
| 1011 |
+
"stream": "ext://sys.stdout",
|
| 1012 |
+
},
|
| 1013 |
+
},
|
| 1014 |
+
"loggers": {
|
| 1015 |
+
"uvicorn": {"handlers": ["default"], "level": "INFO", "propagate": False},
|
| 1016 |
+
"uvicorn.error": {"level": "INFO"},
|
| 1017 |
+
"uvicorn.access": {"handlers": ["default"], "level": "WARNING", "propagate": False},
|
| 1018 |
+
"bip_notifier": {"handlers": ["default"], "level": "INFO", "propagate": False},
|
| 1019 |
+
},
|
| 1020 |
+
}
|
| 1021 |
+
|
| 1022 |
if args.list_all:
|
| 1023 |
list_all_events()
|
| 1024 |
elif args.latest:
|
|
|
|
| 1030 |
elif args.run:
|
| 1031 |
# Launch FastAPI which internally starts the loop
|
| 1032 |
port = int(os.getenv("PORT", 7860))
|
| 1033 |
+
uvicorn.run(app, host="0.0.0.0", port=port, log_config=LOGGING_CONFIG)
|
|
|
|
| 1034 |
else:
|
| 1035 |
# Default behavior: run FastAPI
|
| 1036 |
port = int(os.getenv("PORT", 7860))
|
| 1037 |
+
uvicorn.run(app, host="0.0.0.0", port=port, log_config=LOGGING_CONFIG)
|