1+ """
2+ Predict node
3+
4+ fetches news, runs sentiment model, uploads results to supabase
5+ """
6+
17import hashlib # hash
28import datetime
39import pandas as pd
10+ import logging
11+
412from tensorflow .keras .preprocessing .sequence import pad_sequences
513from finvizfinance .news import News
14+ from zoneinfo import ZoneInfo
615
7- from upstock .config import model_path , tokenizer_path , supabase
8- from upstock .models .artifacts import check_all_model , load_pickle
16+ from upstock .config import paths , supabase
17+ from upstock .models .artifacts import load_model_safe , load_pickle
18+
19+ logger = logging .getLogger (__name__ )
920
1021def run_predict ():
1122
12- model = check_all_model (model_path , 'Sentiment Model .keras version' )
13- tokenizer = load_pickle (tokenizer_path , 'Tokenizer' )
23+ model = load_model_safe (paths .model , 'Sentiment Model (.keras) version' )
24+ tokenizer = load_pickle (paths .tokenizer , 'Tokenizer' )
25+
26+ if model is None or tokenizer is None :
27+ logger .error ('model or tokenizer not available' ) # flow task check
28+ return
1429
1530 # def load_news():
1631 # fnews = News()
@@ -26,14 +41,18 @@ def run_predict():
2641 all_news = fnews .get_news ()
2742 news_df = all_news ['news' ]
2843 except Exception as e :
29- print (f'finviz news parse fail : { e } ' )
30-
31- # string to date time
32- news_df ['parsed_date' ] = pd .to_datetime (news_df ['Date' ], errors = 'coerce' ) # BUG format 지정
44+ logger .error (f'finviz news parse failed : { e } ' )
45+ return
3346
47+ # print(news_df['Date'].head(10))
3448 today = datetime .date .today () # today
35- today_news = news_df [news_df ['parsed_date' ].dt .date == today ] # today == parse data date
3649
50+ # string to date time
51+ news_df ['parsed_date' ] = pd .to_datetime (
52+ news_df ['Date' ],
53+ errors = 'coerce'
54+ )
55+ today_news = news_df [news_df ['parsed_date' ].dt .date == today ] # today == parse data date
3756 predict_texts = today_news ['Title' ].tolist () # insert pare data
3857
3958 # past predict data
@@ -47,7 +66,6 @@ def run_predict():
4766
4867 predict_data = tokenizer .texts_to_sequences (predict_texts )
4968 predict_data = pad_sequences (predict_data , maxlen = 141 ) # str.len result 95% 141
50-
5169 prediction = model .predict (predict_data )
5270 # print(prediction)
5371
@@ -65,19 +83,19 @@ def run_predict():
6583
6684 for text , percent in zip (predict_texts , prediction ):
6785 # 강한 긍정과 강한 부정만 끌어다가 쓰기
68- score = float (percent [0 ])
86+ score = float (percent [0 ]) # float 필수
6987 if score >= 0.8 :
7088 label = "positive"
7189 elif score <= 0.3 :
7290 label = "negative"
7391 else :
7492 continue
7593
76- print (f"[{ label } ] { text } \n : { score :.2f} \n " ) # :.2f
94+ logger . info (f"[{ label } ] { text } : { score :.2f} \n " ) # :.2f
7795
7896 sb_result .append ({
7997 'text' : text ,
80- 'percent' : score , # BUG type error float32
98+ 'percent' : score ,
8199 'label' : label ,
82100 'source' : 'finviz' ,
83101 'run_at' : datetime .datetime .now (datetime .timezone .utc ).isoformat (), # utc time
@@ -91,11 +109,11 @@ def run_predict():
91109 .upsert (sb_result , on_conflict = 'hash' )
92110 .execute ()
93111 )
94- print (f'supbase upload complete : { len (response .data )} ' )
112+ logger . info (f'supbase upload complete : { len (response .data )} rows ' )
95113
96114 except Exception as e :
97- print (f'supabase upload fail : { e } ' )
115+ logger . error (f'supabase upload failed : { e } ' )
98116
99117 else :
100- print ('upload data not exist' )
118+ logger . warning ('upload data not exist' )
101119
0 commit comments