SNET Onboarding Setup
Browse files- pag/monitor.py +38 -6
- tokens.txt +0 -0
- tokens_expired.txt +0 -6
- utils.py +71 -12
pag/monitor.py
CHANGED
@@ -321,24 +321,56 @@ def monitor_fields():
|
|
321 |
if field_name != "Select Field":
|
322 |
st.title(":orange[Field Health Forecast]")
|
323 |
st.write(f"Press the button below to predict {metric} for the next 30 weeks")
|
324 |
-
if
|
|
|
|
|
325 |
st.session_state['api_token'] = ''
|
326 |
st.session_state['api_token_confirmed'] = False
|
|
|
|
|
327 |
if not st.session_state['api_token_confirmed']:
|
328 |
st.warning("No Valid API Token Found")
|
329 |
-
st.
|
330 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
331 |
api_token = st.text_input("API Token", key="api_token_input", help="Enter the API Token From SNET")
|
332 |
if st.button("submit API Token", key="confirm_api_token"):
|
333 |
-
if utils.confirm_api_token(api_token):
|
334 |
st.session_state['api_token'] = api_token
|
335 |
st.session_state['api_token_confirmed'] = True
|
336 |
st.session_state['valid_until'] = utils.load_token_expiration(api_token).strftime('%Y-%m-%d %H:%M:%S')
|
337 |
st.rerun()
|
338 |
else:
|
339 |
-
st.error("Invalid API Token")
|
340 |
else:
|
341 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
342 |
lookback_days = st.slider("Select Lookback Days", 10, 360, 30, step=10,key="lookback_days", help="Large lookback days may take longer to load")
|
343 |
subcol1, subcol2, subcol3 = st.columns(3)
|
344 |
|
|
|
321 |
if field_name != "Select Field":
|
322 |
st.title(":orange[Field Health Forecast]")
|
323 |
st.write(f"Press the button below to predict {metric} for the next 30 weeks")
|
324 |
+
# Reset session state if any of the required keys are missing
|
325 |
+
required_keys = ['api_token', 'api_token_confirmed', 'valid_until']
|
326 |
+
if any(key not in st.session_state for key in required_keys):
|
327 |
st.session_state['api_token'] = ''
|
328 |
st.session_state['api_token_confirmed'] = False
|
329 |
+
st.session_state['valid_until'] = ''
|
330 |
+
|
331 |
if not st.session_state['api_token_confirmed']:
|
332 |
st.warning("No Valid API Token Found")
|
333 |
+
with st.expander("Need a new API Token?", expanded=True):
|
334 |
+
st.markdown(utils.NEW_TOKEN_INSTRUCTIONS, unsafe_allow_html=True)
|
335 |
+
with st.expander("Token Usage history", expanded=False):
|
336 |
+
filename = f'{current_user}_tokens.csv'
|
337 |
+
if os.path.exists(filename):
|
338 |
+
token_usage = pd.read_csv(filename)
|
339 |
+
token_usage['is_expired'] = token_usage['valid_until'].apply(lambda x: 'Yes' if datetime.strptime(x, '%Y-%m-%d %H:%M:%S') < datetime.now() else 'No')
|
340 |
+
st.write(token_usage)
|
341 |
+
else:
|
342 |
+
st.write("No Token Usage History Found")
|
343 |
api_token = st.text_input("API Token", key="api_token_input", help="Enter the API Token From SNET")
|
344 |
if st.button("submit API Token", key="confirm_api_token"):
|
345 |
+
if utils.confirm_api_token(api_token)['valid']:
|
346 |
st.session_state['api_token'] = api_token
|
347 |
st.session_state['api_token_confirmed'] = True
|
348 |
st.session_state['valid_until'] = utils.load_token_expiration(api_token).strftime('%Y-%m-%d %H:%M:%S')
|
349 |
st.rerun()
|
350 |
else:
|
351 |
+
st.error(f"Invalid API Token; {utils.confirm_api_token(api_token)['message']}")
|
352 |
else:
|
353 |
+
now = datetime.now()
|
354 |
+
valid_until = datetime.strptime(st.session_state['valid_until'], '%Y-%m-%d %H:%M:%S')
|
355 |
+
time_remaining = valid_until - now
|
356 |
+
minutes_remaining = int(time_remaining.total_seconds() // 60)
|
357 |
+
seconds_remaining = int(time_remaining.total_seconds() % 60)
|
358 |
+
time_left_column, clear_token_column = st.columns([1,1])
|
359 |
+
with time_left_column:
|
360 |
+
st.success(f"API Token Confirmed. Token valid for {minutes_remaining} minutes and {seconds_remaining} seconds")
|
361 |
+
with clear_token_column:
|
362 |
+
if st.button("Clear API Token", key="clear_api_token"):
|
363 |
+
st.session_state['api_token'] = ''
|
364 |
+
st.session_state['api_token_confirmed'] = False
|
365 |
+
st.session_state['valid_until'] = ''
|
366 |
+
st.rerun()
|
367 |
+
with st.expander("Need a new API Token?", expanded=False):
|
368 |
+
st.markdown(utils.NEW_TOKEN_INSTRUCTIONS, unsafe_allow_html=True)
|
369 |
+
with st.expander("Token Usage history", expanded=False):
|
370 |
+
token_usage = utils.manage_user_tokens(current_user, st.session_state['api_token'], valid_until.strftime('%Y-%m-%d %H:%M:%S'))
|
371 |
+
token_usage['is_expired'] = token_usage['valid_until'].apply(lambda x: 'Yes' if datetime.strptime(x, '%Y-%m-%d %H:%M:%S') < datetime.now() else 'No')
|
372 |
+
st.write(token_usage)
|
373 |
+
|
374 |
lookback_days = st.slider("Select Lookback Days", 10, 360, 30, step=10,key="lookback_days", help="Large lookback days may take longer to load")
|
375 |
subcol1, subcol2, subcol3 = st.columns(3)
|
376 |
|
tokens.txt
CHANGED
The diff for this file is too large to render.
See raw diff
|
|
tokens_expired.txt
DELETED
@@ -1,6 +0,0 @@
|
|
1 |
-
9mfg7acflhkbif70bnrn2lq3ult5t7l5,2024-07-26T20:38:48.882401
|
2 |
-
3swbgq8p1x6wo4kt8vn9apus3y1trlii,2024-07-26T20:08:55.102588
|
3 |
-
9mfg7acflhkbif70bnrn2lq3ult5t7l5,2024-07-26T20:09:19.569408
|
4 |
-
9mfg7acflhkbif70bnrn2lq3ult5t7l5,2024-07-26T19:39:42.164519
|
5 |
-
kfpo6khkcuirmkshjufdob6k1dn9a2oo,2025-07-26T20:45:07.000759
|
6 |
-
TEST_TOKEN,2025-07-26T20:45:07.000759
|
|
|
|
|
|
|
|
|
|
|
|
|
|
utils.py
CHANGED
@@ -15,10 +15,62 @@ import random
|
|
15 |
import string
|
16 |
import os
|
17 |
from datetime import datetime, timedelta
|
18 |
-
import streamlit as st
|
19 |
|
20 |
TOKEN_FILE = "tokens.txt"
|
21 |
EXPIRED_FILE = "tokens_expired.txt"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
22 |
|
23 |
def generate_random_unique_tokens(num_tokens=10, token_file=TOKEN_FILE):
|
24 |
'''Generates a list of random unique tokens and saves them to a file.'''
|
@@ -43,18 +95,25 @@ def generate_random_unique_tokens(num_tokens=10, token_file=TOKEN_FILE):
|
|
43 |
|
44 |
def confirm_api_token(token, token_file=TOKEN_FILE, expired_file=EXPIRED_FILE):
|
45 |
'''Checks if the given token is valid and not expired.'''
|
|
|
|
|
46 |
with open(token_file, 'r') as f:
|
47 |
-
tokens = set(f.read().splitlines())
|
48 |
-
if token in tokens:
|
49 |
now = datetime.now()
|
50 |
-
if token in load_expired_tokens(expired_file):
|
51 |
-
if now < load_token_expiration(token, expired_file):
|
52 |
-
return True
|
|
|
|
|
|
|
53 |
else:
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
|
|
|
|
58 |
|
59 |
def load_expired_tokens(expired_file=EXPIRED_FILE):
|
60 |
'''Loads expired tokens from the file.'''
|
@@ -63,8 +122,8 @@ def load_expired_tokens(expired_file=EXPIRED_FILE):
|
|
63 |
with open(expired_file, 'r') as f:
|
64 |
for line in f:
|
65 |
print(line)
|
66 |
-
|
67 |
-
|
68 |
token, expiry_date = line.strip().split(',')
|
69 |
expired_tokens[token] = datetime.fromisoformat(expiry_date)
|
70 |
return expired_tokens
|
|
|
15 |
import string
|
16 |
import os
|
17 |
from datetime import datetime, timedelta
|
|
|
18 |
|
19 |
TOKEN_FILE = "tokens.txt"
|
20 |
EXPIRED_FILE = "tokens_expired.txt"
|
21 |
+
NEW_TOKEN_INSTRUCTIONS="""<div style="background-color: #e6f2ff; padding: 20px; border-radius: 5px;">
|
22 |
+
<h3 style="color: #4CAF50;">Get Your SNET API Token</h3>
|
23 |
+
|
24 |
+
<p style="color: #666; font-size: 16px;">
|
25 |
+
To get an API token for the SNET platform:
|
26 |
+
<ol>
|
27 |
+
<li>Purchase tokens on the SNET platform using AGIX</li>
|
28 |
+
<li> <del> Input the email address you used to sign up for the dashboard </del>. Any text will work for testing purposes</li>
|
29 |
+
<li>An API token will be generated for you</li>
|
30 |
+
</ol>
|
31 |
+
|
32 |
+
The generated token will be valid for unlimited calls to the forecasting API for 15 minutes from your first call, for any of your fields.
|
33 |
+
</p>
|
34 |
+
|
35 |
+
<p style="color: #666; font-size: 16px;">
|
36 |
+
You can find us on the SNET platform at:
|
37 |
+
<a href="https://beta.singularitynet.io/servicedetails/org/EnigmaAi/service/farmingID" style="color: #007bff; text-decoration: none;">SNET Platform</a>
|
38 |
+
</p>
|
39 |
+
</div>
|
40 |
+
"""
|
41 |
+
|
42 |
+
import pandas as pd
|
43 |
+
import os
|
44 |
+
|
45 |
+
def manage_user_tokens(current_user, api_token, valid_until):
|
46 |
+
"""
|
47 |
+
Manages the storage and retrieval of user API tokens.
|
48 |
+
|
49 |
+
Args:
|
50 |
+
current_user (str): The username of the currently logged-in user.
|
51 |
+
api_token (str): The API token to be stored.
|
52 |
+
valid_until (str): The expiration date of the API token (in 'YYYY-MM-DD HH:MM:SS' format).
|
53 |
+
|
54 |
+
Returns:
|
55 |
+
None
|
56 |
+
"""
|
57 |
+
filename = f'{current_user}_tokens.csv'
|
58 |
+
# Check if the file exists
|
59 |
+
if not os.path.exists(filename):
|
60 |
+
# Create a new DataFrame and save it to the file
|
61 |
+
df = pd.DataFrame({'token': [api_token], 'valid_until': [valid_until]})
|
62 |
+
df.to_csv(filename, index=False)
|
63 |
+
else:
|
64 |
+
# Load the existing DataFrame
|
65 |
+
df = pd.read_csv(filename)
|
66 |
+
# Check if the token already exists in the DataFrame
|
67 |
+
if api_token not in df['token'].values:
|
68 |
+
# Append the new token and valid_until to the DataFrame
|
69 |
+
new_row = {'token': api_token, 'valid_until': valid_until}
|
70 |
+
new_row_df = pd.DataFrame(new_row, index=[0])
|
71 |
+
df = pd.concat([df, new_row_df], ignore_index=True)
|
72 |
+
df.to_csv(filename, index=False)
|
73 |
+
return df
|
74 |
|
75 |
def generate_random_unique_tokens(num_tokens=10, token_file=TOKEN_FILE):
|
76 |
'''Generates a list of random unique tokens and saves them to a file.'''
|
|
|
95 |
|
96 |
def confirm_api_token(token, token_file=TOKEN_FILE, expired_file=EXPIRED_FILE):
|
97 |
'''Checks if the given token is valid and not expired.'''
|
98 |
+
print(f'Checking token: {token} >>>>>>>>>>>>>>>>>>>')
|
99 |
+
msg = 'Token is valid'
|
100 |
with open(token_file, 'r') as f:
|
101 |
+
tokens = set(f.read().splitlines()) # Load All possible tokens
|
102 |
+
if token in tokens: # Check if the token is one of the possible tokens
|
103 |
now = datetime.now()
|
104 |
+
if token in load_expired_tokens(expired_file): # Check if the token have been used before
|
105 |
+
if now < load_token_expiration(token, expired_file): # Check if the token has been expired
|
106 |
+
return {'valid': True, 'message': msg}
|
107 |
+
else: # If the token has been expired, return invalid
|
108 |
+
msg = 'Token has expired'
|
109 |
+
return {'valid': False, 'message': msg}
|
110 |
else:
|
111 |
+
msg = 'Token is valid'
|
112 |
+
expiry_date = now + timedelta(minutes=15)
|
113 |
+
save_expired_token(token, expiry_date, expired_file) # If the token is valid and have not been used before, set the expiration date to 15 minutes
|
114 |
+
return {'valid': True, 'message': msg}
|
115 |
+
msg = 'Token is invalid'
|
116 |
+
return {'valid': False, 'message': msg}
|
117 |
|
118 |
def load_expired_tokens(expired_file=EXPIRED_FILE):
|
119 |
'''Loads expired tokens from the file.'''
|
|
|
122 |
with open(expired_file, 'r') as f:
|
123 |
for line in f:
|
124 |
print(line)
|
125 |
+
print(line.strip().split(','))
|
126 |
+
print('------------')
|
127 |
token, expiry_date = line.strip().split(',')
|
128 |
expired_tokens[token] = datetime.fromisoformat(expiry_date)
|
129 |
return expired_tokens
|