KeyError: 'st.session_state has no key in Streamlit - python

`
import streamlit as st
from streamlit_option_menu import option_menu
import json
from streamlit_lottie import st_lottie
import pickle
import requests
from db1 import insert_review, fetch_all_reviews, get_movie_review
movies = pickle.load(open('movie_list.pkl', 'rb'))
similarity = pickle.load(open('similarity.pkl', 'rb'))
`
`
if selected == "Review":
st.title("Reviews")
with st.form("my_form"):
st.write("Type your Review")
user_name_rev = st.text_input("User Name")
movie_list = movies['title'].values
selected_movie = st.selectbox(
"Type or select a movie from the dropdown",
movie_list
)
slider_val = st.slider("Rating", 1, 10)
# st.write(f"{slider_val}")
movie_rev = st.text_area("Write your review")
#checkbox_val = st.checkbox("Form checkbox")
submitted = st.form_submit_button("Submit")
if "load_state" not in st.session_state:
st.session_state.load_state = False
if submitted or st.session_state.load_state:
st.session_state.load_state = True
user = str(st.session_state[user_name_rev])
movies = str(st.session_state[selected_movie])
rate = st.session_state[slider_val]
review = str(st.session_state[movie_rev])
insert_review(user, movies, rate, review)
st.write("Your review is saved")
I was trying to save the data in db and whenever I click submit it shows error.
KeyError: 'st.session_state has no key "yy". Did you forget to initialize it? More info: https://docs.streamlit.io/library/advanced-features/session-state#initialization' Traceback: File "c:\users\yaagik\pycharmprojects\pythonproject\venv\lib\site-packages\streamlit\runtime\scriptrunner\script_runner.py", line 564, in _run_script exec(code, module.__dict__) File "C:\Users\YAAGIK\PycharmProjects\pythonProject\new_test.py", line 77, in <module> user = str(st.session_state[user_name_rev]) File "c:\users\yaagik\pycharmprojects\pythonproject\venv\lib\site-packages\streamlit\runtime\state\session_state_proxy.py", line 89, in __getitem__ return get_session_state()[key] File "c:\users\yaagik\pycharmprojects\pythonproject\venv\lib\site-packages\streamlit\runtime\state\safe_session_state.py", line 110, in __getitem__ return self._state[key] File "c:\users\yaagik\pycharmprojects\pythonproject\venv\lib\site-packages\streamlit\runtime\state\session_state.py", line 439, in __getitem__ raise KeyError(_missing_key_error_message(key))
I tried to fix it with various methods available online but none of them worked for me.`

The problem is that you call 'st.session_state[user_name_rev]' on line 77 without initializing it.
To initialize a streamlit session_state you can do:
st.session_state['your_session_state_name'] = value_to_store
Or
if 'you_session_state_name' not in st.session_state:
st.session_state.you_session_state_name = value_to_store
In your specific case you can do:
if submitted or st.session_state.load_state:
if 'user' not in st.session_state:
st.session_state['user'] = user_name_rev
user = str(st.session_state['user'])
Do the same to movies, rate, review, this might work.
References:
https://docs.streamlit.io/library/advanced-features/session-state

Related

API using MechanicalSoup is failing to submit form - NoneType

I'm using a python API that uses MechanicalSoup to do most of its functions and all of a sudden, it won't work anymore. I feel like the website it's utilizing may have changed or something.
Here is the API's code:
def trade(self, symbol, orderType, quantity, priceType="Market", price=False, duration=Duration.good_cancel):
"""
Executes trades on the platform. See the readme.md file
for examples on use and inputs. Returns True if the
trade was successful. Else an exception will be
raised.
client.trade("GOOG", Action.buy, 10)
client.trade("GOOG", Action.buy, 10, "Limit", 500)
"""
br = self.br
trade_page = self.fetch('/simulator/trade/tradestock.aspx')
trade_form = trade_page.soup.select("form#orderForm")[0]
# input symbol, quantity, etc.
trade_form.select("input#symbolTextbox")[0]["value"] = symbol
trade_form.select("input#quantityTextbox")[0]["value"] = str(quantity)
# input transaction type
[option.attrs.pop("selected", "") for option in trade_form.select("select#transactionTypeDropDown")[0]("option")]
trade_form.select("select#transactionTypeDropDown")[0].find("option", {"value": str(orderType.value)})["selected"] = True
# input price type
[radio.attrs.pop("checked", "") for radio in trade_form("input", {"name": "Price"})]
trade_form.find("input", {"name": "Price", "value": priceType})["checked"] = True
# input duration type
[option.attrs.pop("selected", "") for option in trade_form.select("select#durationTypeDropDown")[0]("option")]
trade_form.select("select#durationTypeDropDown")[0].find("option", {"value": str(duration.value)})["selected"] = True
# if a limit or stop order is made, we have to specify the price
if price and priceType == "Limit":
trade_form.select("input#limitPriceTextBox")[0]["value"] = str(price)
elif price and priceType == "Stop":
trade_form.select("input#stopPriceTextBox")[0]["value"] = str(price)
prev_page = br.submit(trade_form, trade_page.url)
prev_form = prev_page.soup.select("form", {"name": "simTradePreview"})
br.submit(prev_form, prev_page.url)
return True
And here is my code that I implement it with:
def buy(shares, ticker, client):
client.trade(ticker,ita.Action.buy, shares)
...
if apred[0] - arl[-1] > 0 and apred[1] - apred[0] > 0 and tickers[0] not in z:
buy(ashr ,tickers[0], client)
Here is the error message:
Traceback (most recent call last):
File "/Users/carson/mlTechnicalAnalysis/investopedia.py", line 146, in <module>
schedule.run_pending()
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/schedule/__init__.py", line 493, in run_pending
default_scheduler.run_pending()
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/schedule/__init__.py", line 78, in run_pending
self._run_job(job)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/schedule/__init__.py", line 131, in _run_job
ret = job.run()
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/schedule/__init__.py", line 411, in run
ret = self.job_func()
File "/Users/carson/mlTechnicalAnalysis/investopedia.py", line 56, in main
buy(ashr ,tickers[0], client)
File "/Users/carson/mlTechnicalAnalysis/investopedia.py", line 16, in buy
client.trade(ticker,ita.Action.buy, shares)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/InvestopediaApi/ita.py", line 240, in trade
prev_form = prev_page.soup.select("form", {"name": "simTradePreview"})
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/bs4/element.py", line 1532, in select
for candidate in _use_candidate_generator(tag):
TypeError: 'dict' object is not callable
I've been beating my head against the wall for a few hours now and I feel like it'll take one of y'all two seconds to figure out. FYI it's an API to made trades on Investopedia's stock trading simulator.
Thanks!
In short: you're passing one too many arguments to .select(); you must pass a single CSS selector as a string.
Looking at the stack trace:
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/InvestopediaApi/ita.py", line 240, in trade
prev_form = prev_page.soup.select("form", {"name": "simTradePreview"})
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/bs4/element.py", line 1532, in select
for candidate in _use_candidate_generator(tag):
TypeError: 'dict' object is not callable
It appears that what you pass as the second argument to .select() is a dict ({"name": "simTradePreview"}). Apparently it's not expected.
From the stacktrace it appears that the soup in question is BeautifulSoup 4 (bs4); its select does not seem to accept a second argument. But the source does have more undocumented arguments with default vlues, in particular, _candidate_generator, which you clobber.

creating a data base with peewee execute_sql self.commit()

I used some very simple code to create a database with peewee, I am new to using python ORMs so I can't really tell why I'm getting a whole bunch of errors.
What this code does is: First I create a database 'diary.db'
the data types used are entries, which is a Text Field, and date, which is a DateTimeField. I created some functions: 'initialize' to run basic commands and initialize the database, 'menu_loop' that will show a menu that works with an infinite loop and may call the function 'add_entry' that adds new entries to the database.
Heres the code:
#!/usr/bin/env python3
from collections import OrderedDict
from peewee import *
import datetime
import sys
db = SqliteDatabase('diary.db')
class Diary(Model):
entries = TextField()
date = DateTimeField(default = datetime.datetime.now)
class Meta:
database = db
def initialize():
"""initializes the database"""
db.connect()
db.create_tables([Diary], safe = True)
#end of initialize
def menu_loop():
"""show menu"""
choice = 0
while choice != 2:
print("Enter '2' to quit")
print('1) to add an entry')
choice = input()
if choice == 1:
add_entry()
#end of menu_loop
def add_entry():
"""add an entry"""
print("Enter your entry, press ctrl+d when done")
data = sys.stdin.read().strip()
if data:
while(True):
option = input('\nSave entry?[1 = yes 0 = no] ')
if option == 1:
Diary.create(content=data)
print ("Saved sucessfully!")
if option == 0:
print ("Program exited")
break;
#end of add_entry
if __name__ == '__main__':
initialize()
menu_loop()
and the error log
Enter '2' to quit
1) to add an entry
1
Enter your entry, press ctrl+d when done
this is my new entry
hello world^D
Save entry?[1 = yes 0 = no] 1
Traceback (most recent call last):
File "ispythonsmart.py", line 50, in <module>
menu_loop()
File "ispythonsmart.py", line 30, in menu_loop
add_entry()
File "ispythonsmart.py", line 41, in add_entry
Diary.create(content=data)
File "/Library/Python/2.7/site-packages/peewee.py", line 4494, in create
inst.save(force_insert=True)
File "/Library/Python/2.7/site-packages/peewee.py", line 4680, in save
pk_from_cursor = self.insert(**field_dict).execute()
File "/Library/Python/2.7/site-packages/peewee.py", line 3213, in execute
cursor = self._execute()
File "/Library/Python/2.7/site-packages/peewee.py", line 2628, in _execute
return self.database.execute_sql(sql, params, self.require_commit)
File "/Library/Python/2.7/site-packages/peewee.py", line 3461, in execute_sql
self.commit()
File "/Library/Python/2.7/site-packages/peewee.py", line 3285, in __exit__
reraise(new_type, new_type(*exc_args), traceback)
File "/Library/Python/2.7/site-packages/peewee.py", line 3454, in execute_sql
cursor.execute(sql, params or ())
peewee.IntegrityError: NOT NULL constraint failed: diary.entries
You need to set entries to null=True or use a default value for entries:
class Diary(Model):
entries = TextField(null=True)
Output:
Enter '2' to quit
1) to add an entry
1
Enter your entry, press ctrl+d when done
foobar
Save entry?[1 = yes 0 = no] 1
Saved successfully!
You want to see "entries" TEXT in the db not "entries" TEXT NOT NULL. If a column is set to NOT NULL you must insert a value or you will get an integrity error, an alternative is to give a default value for the column i.e TextField(default="foo"). On a sidenote you have #!/usr/bin/env python3 as your shebang but your code is written for python 2 so you may want to correct that.

Adding Item data to a DynamoDB table using boto does not work

I have been trying to add items to a DynamoDB table using boto, but somehow it doesn't seem to work. I tried using users.Item() and users.put_item but nothing worked. Below is the script that I have in use.
import boto.dynamodb2
import boto.dynamodb2.items
import json
from boto.dynamodb2.fields import HashKey, RangeKey, GlobalAllIndex
from boto.dynamodb2.layer1 import DynamoDBConnection
from boto.dynamodb2.table import Table
from boto.dynamodb2.items import Item
from boto.dynamodb2.types import NUMBER
region = "us-east-1"
con = boto.dynamodb2.connect_to_region(region)
gettables = con.list_tables()
mytable = "my_table"
if mytable not in gettables['TableNames']:
print "The table *%s* is not in the list of tables created. A new table will be created." % req_table
Table.create(req_table,
schema = [HashKey('username'),
RangeKey('ID', data_type = NUMBER)],
throughput = {'read': 1, 'write': 1})
else:
print "The table *%s* exists." % req_table
con2table = Table(req_table,connection=con)
con2table.put_item(data={'username': 'abcd',
'ID': '001',
'logins':'10',
'timeouts':'20'
'daysabsent': '30'
})
I tried this, the table gets created and it is fine. But when I try to put in the items, I get the following error message.
Traceback (most recent call last):
File "/home/ec2-user/DynamoDB_script.py", line 29, in <module>
'daysabsent':'30'
File "/usr/lib/python2.7/dist-packages/boto/dynamodb2/table.py", line 821, in put_item
return item.save(overwrite=overwrite)
File "/usr/lib/python2.7/dist-packages/boto/dynamodb2/items.py", line 455, in save
returned = self.table._put_item(final_data, expects=expects)
File "/usr/lib/python2.7/dist-packages/boto/dynamodb2/table.py", line 835, in _put_item
self.connection.put_item(self.table_name, item_data, **kwargs)
File "/usr/lib/python2.7/dist-packages/boto/dynamodb2/layer1.py", line 1510, in put_item
body=json.dumps(params))
File "/usr/lib/python2.7/dist-packages/boto/dynamodb2/layer1.py", line 2842, in make_request
retry_handler=self._retry_handler)
File "/usr/lib/python2.7/dist-packages/boto/connection.py", line 954, in _mexe
status = retry_handler(response, i, next_sleep)
File "/usr/lib/python2.7/dist-packages/boto/dynamodb2/layer1.py", line 2882, in _retry_handler
response.status, response.reason, data)
boto.dynamodb2.exceptions.ValidationException: ValidationException: 400 Bad Request
{u'message': u'One or more parameter values were invalid: Type mismatch for key version expected: N actual: S', u'__type': u'com.amazon.coral.validate#ValidationException'}
Thank you.
From the error message you are getting, it sounds like you are trying to send string values for an attribute that is defined as numeric in DynamoDB.
The specific issue looks to be related to your Range Key ID which is defined as a numeric value N but you are sending it a string value '001'.
Looks like of of the values you are trying to load has empty value.
I got the same error when I was trying to load this. I got exception when partner_name property was a empty string.
try:
item_old = self.table.get_item(hash_key=term)
except BotoClientError as ex:
# if partner alias does not exist then create a new entry!
if ex.message == "Key does not exist.":
item_old = self.table.new_item(term)
else:
raise ex
item_old['partner_code'] = partner_code
item_old['partner_name'] = partner_name
item_old.put()

Pysphere having a issue with inserting an annotation after setting vm_mor

The goal of my program is to parse some information returned from an oracle database. Then as it parses this information build a pickle dictionary to insert data into a vcenter vm.object using the pysphere module. However, currently I'm running into an issue when trying to save the annotation to a user set vm_object which is set by using the vm_mor identifier.Before when I was loopping through VM properties it was working correctly, but now that im trying to search via VM-mor im having issues I'll post the way it worked and the way I want to do it but it isn't working.
This is the way it doesn't work and the error code I get:
import cx_Oracle
import datetime
from decimal import *
from pysphere import VIServer, MORTypes, VIProperty, VIMor
from pysphere.resources import VimService_services as VI
from pysphere.vi_virtual_machine import VIVirtualMachine
import pickle
import sys
import time
vc = VIServer()
vc.connect(hostname,username,password, trace_file="debug.txt")
properties = ['config.name', 'config.annotation']
licenses_list = []
license_built_list = []
def change_annotation(vm_mor, new_annotation):
request = VI.ReconfigVM_TaskRequestMsg()
_this = request.new__this(vm_mor)
_this.set_attribute_type(vm_mor.get_attribute_type())
request.set_element__this(_this)
spec = request.new_spec()
spec.set_element_annotation(new_annotation)
request.set_element_spec(spec)
vc._proxy.ReconfigVM_Task(request)
oracle = cx_Oracle.connect()
cursor = oracle.cursor()
cursor_guestos = oracle.cursor()
select_customer = ( ''' ''')
cursor.execute(select_customer)
for value in cursor:
licenses_list.append(value)
for index, value in enumerate(licenses_list):
customer_id = value[0]
vm_mor = value[1]
vm_id = value[2]
license_id = value[3]
product = value[4]
guest_os_id = 0
sql_guest_os = (''' ''')%int(vm_id)
cursor_guestos.execute(sql_guest_os)
for guest_os_id in cursor_guestos:
guest_os_id = guest_os_id[0]
if licenses_list[index][2] == licenses_list[index+1][2]:
license_built_list.append((licenses_list[index][4], licenses_list[index][3]))
continue
else:
license_built_list.append((licenses_list[index][4], licenses_list[index][3]))
pickle_dict = {"license":license_built_list, "customer_id":customer_id, "guest_os":guest_os_id}
pickle.dump( pickle_dict, open( vm_mor, "wb" ) )
annotation = vm_mor
vm_mor_query = VIMor(str(vm_mor), MORTypes.VirtualMachine)
try:
vm = VIVirtualMachine(vc, vm_mor_query)
except:
continue
change_annotation(vm, annotation) #this is where it breaks.
pickle_dict = {}
annotation = {}
vm_mor = {}
license_built_list=[]
Traceback (most recent call last):
File "/home/grant/.eclipse/org.eclipse.platform_3.8_155965261/plugins/org.python.pydev_3.4.1.201403181715/pysrc/pydevd.py", line 1844, in <module>
debugger.run(setup['file'], None, None)
File "/home/grant/.eclipse/org.eclipse.platform_3.8_155965261/plugins/org.python.pydev_3.4.1.201403181715/pysrc/pydevd.py", line 1372, in run
pydev_imports.execfile(file, globals, locals) # execute the script
File "/home/grant/workspace/Metering/metering-home/push-annotation-pickle.py", line 96, in <module>
change_annotation(vm, annotation)
File "/home/grant/workspace/Metering/metering-home/push-annotation-pickle.py", line 25, in change_annotation
_this.set_attribute_type(vm_mor.get_attribute_type())
AttributeError: 'VIVirtualMachine' object has no attribute 'get_attribute_type'
The way it works:
def change_annotation(vm_mor, new_annotation):
request = VI.ReconfigVM_TaskRequestMsg()
_this = request.new__this(vm_mor)
_this.set_attribute_type(vm_mor.get_attribute_type())
request.set_element__this(_this)
spec = request.new_spec()
spec.set_element_annotation(new_annotation)
request.set_element_spec(spec)
vc._proxy.ReconfigVM_Task(request)
vc = VIServer()
vc.connect()
properties = ['config.name', 'config.annotation']
vm_mors = []
for vm_mor_sql in cursor:
vm_mors.append(vm_mor_sql[0])
for vc_vm in vc._retrieve_properties_traversal(property_names=properties, obj_type='VirtualMachine'):
vm_mor = vc_vm.Obj
if vm_mor in vm_mors:
vm = dict()
print vm_mor,
try:
for vm_prop in vc_vm.PropSet:
vm[vm_prop.Name] = vm_prop.Val
except AttributeError:
print 'missing properties'
continue
try:
change_annotation(vm_mor, 'test insert')
except:
continue
Any help would be appriciated.

RuntimeError: maximum recursion depth exceeded (without an explicit recursive call in my Python code)

I am trying to read key-value pairs from an already existing shelf to create a new class object with a updated field and write that class object to a new shelf.
My class object : SongDetails
This is the procedure which fails:
def updateShelfWithTabBody(shelfFileName, newShelfFileName):
"""this function updates songDetails with
html body i.e. just the part that contains lyrics and
chords in the tab """
#read all songDetails
shelf = shelve.open(shelfFileName)
listOfKeys = shelf.keys()
#create new songDetails object
temporaryShelfObject = SongDetails.SongDetails()
#iterate over list of keys
for key in listOfKeys:
#print "name:"+shelf[key].name
#fill details from temporaryShelfObject
temporaryShelfObject.name = shelf[key].name
temporaryShelfObject.tabHtmlPageContent = shelf[key].tabHtmlPageContent
#add new detail information
htmlPageContent = shelf[key].tabHtmlPageContent
temporaryShelfObject.htmlBodyContent = extractDataFromDocument.fetchTabBody(htmlPageContent)
#write SongDetails back to shelf
writeSongDetails.writeSongDetails(temporaryShelfObject, newShelfFileName)
Definitions for functions used in above code:
def fetchTabBody(page_contents):
soup = BeautifulSoup(page_contents)
HtmlBody = ""
try:
#The lyrics and chords of song are contained in div with id = "cont"
#Note: This assumtption is specific to ultimate-guitar.com
HtmlBody = soup.html.body.find("div",{"id":"cont"})
except:
print "Error: ",sys.exc_info()[0]
return HtmlBody
def writeSongDetails(songDetails, shelfFileName):
shelf = shelve.open(shelfFileName)
songDetails.name = str(songDetails.name).strip(' ')
shelf[songDetails.name] = songDetails
shelf.close()
SongDetails class:
class SongDetails:
name = ""
tabHtmlPageContent = ""
genre = ""
year = ""
artist = ""
chordsAndLyrics = ""
htmlBodyContent = ""
scale = ""
chordsUsed = []
This is the error that I get:
Traceback (most recent call last):
File "/l/nx/user/ndhande/Independent_Study_Project_Git/Crawler/updateSongDetailsShelfWithNewAttributes.py", line 69, in <module>
updateShelfWithTabBody(shelfFileName, newShelfFileName)
File "/l/nx/user/ndhande/Independent_Study_Project_Git/Crawler/updateSongDetailsShelfWithNewAttributes.py", line 38, in updateShelfWithTabBody
writeSongDetails.writeSongDetails(temporaryShelfObject, newShelfFileName)
File "/home/nx/user/ndhande/Independent_Study_Project_Git/Crawler/writeSongDetails.py", line 7, in writeSongDetails
shelf[songDetails.name] = songDetails
File "/usr/lib64/python2.6/shelve.py", line 132, in __setitem__
p.dump(value)
File "/usr/lib64/python2.6/copy_reg.py", line 71, in _reduce_ex
state = base(self)
File "/u/ndhande/.local/lib/python2.6/site-packages/BeautifulSoup.py", line 476, in __unicode__
return str(self).decode(DEFAULT_OUTPUT_ENCODING)
**RuntimeError: maximum recursion depth exceeded**
I couldn't find any reason why I'm getting this error even though there is no explicit recursive call in my code. I have seen this error in other stackoverflow posts, but they did have recursive calls in their case.
str(self) calls __str__ or calls __unicode__ calls str(self).

Categories