DinoPLayZ commited on
Commit
f34ff33
·
verified ·
1 Parent(s): 29f02d8

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +36 -40
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
- # Create a dedicated named logger instead of fighting Uvicorn over the root logger
41
- logger = logging.getLogger("bip_notifier")
42
- logger.setLevel(logging.INFO)
43
-
44
- # Prevent log messages from propagating to the root logger (where Uvicorn might swallow them)
45
- logger.propagate = False
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
- # Remove log_config=None because it completely disables Uvicorn's stdout handling
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)