I'm getting an error the first time I try to get an element. Notice that second time I try that it actually works. This is a debug session:
>>> self.selenium.find_element_by_xpath('//*[#id="add-button"]')
Traceback (most recent call last):
File "/home/vagrant/.pycharm_helpers/pydev/pydevd_exec2.py", line 3, in Exec
exec(exp, global_vars, local_vars)
File "<input>", line 1, in <module>
File "/vagrant/venv/lib/python3.4/site-packages/selenium/webdriver/remote/webdriver.py", line 232, in find_element_by_xpath
return self.find_element(by=By.XPATH, value=xpath)
File "/vagrant/venv/lib/python3.4/site-packages/selenium/webdriver/remote/webdriver.py", line 664, in find_element
{'using': by, 'value': value})['value']
File "/vagrant/venv/lib/python3.4/site-packages/selenium/webdriver/remote/webdriver.py", line 173, in execute
response = self.command_executor.execute(driver_command, params)
File "/vagrant/venv/lib/python3.4/site-packages/selenium/webdriver/remote/remote_connection.py", line 349, in execute
return self._request(command_info[0], url, body=data)
File "/vagrant/venv/lib/python3.4/site-packages/selenium/webdriver/remote/remote_connection.py", line 380, in _request
resp = self._conn.getresponse()
File "/usr/lib/python3.4/http/client.py", line 1147, in getresponse
response.begin()
File "/usr/lib/python3.4/http/client.py", line 351, in begin
version, status, reason = self._read_status()
File "/usr/lib/python3.4/http/client.py", line 321, in _read_status
raise BadStatusLine(line)
http.client.BadStatusLine: ''
>>> self.selenium.find_element_by_xpath('//*[#id="add-button"]')
<selenium.webdriver.remote.webelement.WebElement object at 0x7f90ab074400>
And this is the code:
from selenium.webdriver.firefox.webdriver import WebDriver
from django.contrib.staticfiles.testing import StaticLiveServerTestCase
from xvfbwrapper import Xvfb
class UIPropertyTestCase(StaticLiveServerTestCase):
fixtures = ['properties']
#classmethod
def setUpClass(cls):
cls.vdisplay = Xvfb()
cls.vdisplay.start()
cls.selenium = WebDriver()
cls.selenium.implicitly_wait(10)
super(UIPropertyTestCase, cls).setUpClass()
#classmethod
def tearDownClass(cls):
cls.selenium.quit()
cls.vdisplay.stop()
super(UIPropertyTestCase, cls).tearDownClass()
def test_add_property(self):
self.selenium.get('{0}{1}'.format(self.live_server_url, '/#/app/properties'))
self.selenium.find_element_by_xpath('//*[#id="add-button"]').click()
self.selenium.get('{0}{1}'.format(self.live_server_url, '/#/app/properties'))
count = len(self.selenium.find_elements_by_xpath('//*[#id="data"]/tbody/tr'))
self.assertEqual(count, 3)
Found this comment on /usr/lib/python3.4/http/client.py:319:
Presumably, the server closed the connection before sending a valid
response.
Additional info:
OS: Ubuntu 14.04.2 LTS
Python: 3.4.0
Django: 1.7.6
selenium: 2.45.0
Firefox: 36.0.4
Any idea what could I be missing?
As said when something goes strange with Selenium it is usually good idea to update it and also update firefox.
In your case are you sure that element was actually loaded? I can see implicitly wait method but loading time may vary so it might be not enough.
You can start by increasing implicitly_wait time and try once again.
Related
I have the following script that grabs a repository from Github using PYGitHub
import logging
import getpass
import os
from github import Github, Repository as Repository, UnknownObjectException
GITHUB_URL = 'https://github.firstrepublic.com/api/v3'
if __name__ == '__main__':
logging.getLogger().setLevel(logging.DEBUG)
logging.debug('validating GH token')
simpleuser = getpass.getuser().replace('adm_','')
os.path.exists(os.path.join(os.path.expanduser('~' + getpass.getuser()) + '/.ssh/github-' + simpleuser + '.token'))
with open(os.path.join(os.path.expanduser('~' + getpass.getuser()) + '/.ssh/github-' + simpleuser + '.token'), 'r') as token_file:
github_token = token_file.read()
logging.debug(f'Token after file processing: {github_token}')
logging.debug('initializing github')
g = Github(base_url=GITHUB_URL, login_or_token=github_token)
logging.debug("attempting to get repository")
source_repo = g.get_repo('CLOUD/iam')
Works just fine in Python 3.9.1 on my Mac.
In production, we have RHEL7, Python 3.6.8 (can't upgrade it, don't suggest it). This is where it blows up:
(virt) user#lmachine: directory$ python3 test3.py -r ORG/repo_name -d
DEBUG:root:validating GH token
DEBUG:root:Token after file processing: <properly_formed_token>
DEBUG:root:initializing github
DEBUG:root:attempting to get repository
DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): <domain>:443
Traceback (most recent call last):
File "test3.py", line 68, in <module>
source_repo = g.get_repo(args.repo)
File "/home/adm_gciesla/virt/lib/python3.6/site-packages/github/MainClass.py", line 348, in get_repo
"GET", "%s%s" % (url_base, full_name_or_id)
File "/home/user/virt/lib/python3.6/site-packages/github/Requester.py", line 319, in requestJsonAndCheck
verb, url, parameters, headers, input, self.__customConnection(url)
File "/home/user/virt/lib/python3.6/site-packages/github/Requester.py", line 410, in requestJson
return self.__requestEncode(cnx, verb, url, parameters, headers, input, encode)
File "/home/user/virt/lib/python3.6/site-packages/github/Requester.py", line 487, in __requestEncode
cnx, verb, url, requestHeaders, encoded_input
File "/home/user/virt/lib/python3.6/site-packages/github/Requester.py", line 513, in __requestRaw
response = cnx.getresponse()
File "/home/user/virt/lib/python3.6/site-packages/github/Requester.py", line 116, in getresponse
allow_redirects=False,
File "/home/user/virt/lib/python3.6/site-packages/requests/sessions.py", line 543, in get
return self.request('GET', url, **kwargs)
File "/home/user/virt/lib/python3.6/site-packages/requests/sessions.py", line 530, in request
resp = self.send(prep, **send_kwargs)
File "/home/user/virt/lib/python3.6/site-packages/requests/sessions.py", line 643, in send
r = adapter.send(request, **kwargs)
File "/home/user/virt/lib/python3.6/site-packages/requests/adapters.py", line 449, in send
timeout=timeout
File "/home/user/virt/lib/python3.6/site-packages/urllib3/connectionpool.py", line 677, in urlopen
chunked=chunked,
File "/home/user/virt/lib/python3.6/site-packages/urllib3/connectionpool.py", line 392, in _make_request
conn.request(method, url, **httplib_request_kw)
File "/usr/lib64/python3.6/http/client.py", line 1254, in request
self._send_request(method, url, body, headers, encode_chunked)
File "/usr/lib64/python3.6/http/client.py", line 1295, in _send_request
self.putheader(hdr, value)
File "/usr/lib64/python3.6/http/client.py", line 1232, in putheader
raise ValueError('Invalid header value %r' % (values[i],))
ValueError: Invalid header value b'token <properly_formed_token>\n'
The script is a stripped down version of a larger application. I've tried rolling back to earlier versions of PyGitHub, that's really all I have control over in prod. Same error regardless. PyGithub's latest release claims Python >=3.6 should work.
I've really run the gamut of debugging. Seems like reading from environment variables can work sometimes, but the script needs to be able to use whatever credentials are available. Passing in the token as an argument is only for running locally.
Hopefully someone out there has seen something similar.
We just figured it out. Apparently, even though there's no newline in the .token file, there is one after calling file.read()
Changing github_token = token_file.read() to github_token = token_file.read().strip() fixes the problem.
I'm trying to use Authlib library to access new eBay REST API (as Authorization code grant)
Here is my code;
import json
import os
import webbrowser
from time import time
from authlib.integrations.requests_client import OAuth2Session
from rpi_order_data_sync import settings
def auth(seller):
def token_updater(token, seller=seller):
if not os.path.exists(seller):
open(seller, "w").close()
with open(seller, "w") as token_file:
json.dump(token, token_file)
scope = ["https://api.ebay.com/oauth/api_scope/sell.fulfillment.readonly"]
if not os.path.exists(seller):
ebay = OAuth2Session(
settings.E_APP_ID,
settings.E_CERT_ID,
redirect_uri=settings.E_RU_NAME,
scope=scope,
)
uri, state = ebay.create_authorization_url(
"https://auth.sandbox.ebay.com/oauth2/authorize",
)
print("Please go to {} and authorize access.".format(uri))
try:
webbrowser.open_new_tab(uri)
except webbrowser.Error:
pass
authorization_response = input("Please enter callback URL: ") # nosec
token = ebay.fetch_token(
"https://api.sandbox.ebay.com/identity/v1/oauth2/token",
authorization_response=authorization_response,
)
print(token)
token_updater(token)
return ebay
The problem is eBay's token response has an unconventional token type named "User Access Token" instead of "Bearer". Therefore I get this error;
Traceback (most recent call last):
File "/home/thiras/.local/share/virtualenvs/rpi-order-data-sync-tA0i1rrc/lib/python3.8/site-packages/authlib/integrations/requests_client/oauth2_session.py", line 37, in __call__
req.url, req.headers, req.body = self.prepare(
File "/home/thiras/.local/share/virtualenvs/rpi-order-data-sync-tA0i1rrc/lib/python3.8/site-packages/authlib/oauth2/auth.py", line 91, in prepare
sign = self.SIGN_METHODS[token_type.lower()]
KeyError: 'user access token'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/thiras/.local/share/virtualenvs/rpi-order-data-sync-tA0i1rrc/bin/rods", line 11, in <module>
load_entry_point('rpi-order-data-sync', 'console_scripts', 'rods')()
File "/home/thiras/.local/share/virtualenvs/rpi-order-data-sync-tA0i1rrc/lib/python3.8/site-packages/click/core.py", line 829, in __call__
return self.main(*args, **kwargs)
File "/home/thiras/.local/share/virtualenvs/rpi-order-data-sync-tA0i1rrc/lib/python3.8/site-packages/click/core.py", line 782, in main
rv = self.invoke(ctx)
File "/home/thiras/.local/share/virtualenvs/rpi-order-data-sync-tA0i1rrc/lib/python3.8/site-packages/click/core.py", line 1259, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/home/thiras/.local/share/virtualenvs/rpi-order-data-sync-tA0i1rrc/lib/python3.8/site-packages/click/core.py", line 1066, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/home/thiras/.local/share/virtualenvs/rpi-order-data-sync-tA0i1rrc/lib/python3.8/site-packages/click/core.py", line 610, in invoke
return callback(*args, **kwargs)
File "/home/thiras/HDD/freelancer/contentassasin/rpi-order-data-sync/rpi_order_data_sync/main.py", line 132, in sync_ebay_orders
orders = ebay.get(
File "/home/thiras/.local/share/virtualenvs/rpi-order-data-sync-tA0i1rrc/lib/python3.8/site-packages/requests/sessions.py", line 543, in get
return self.request('GET', url, **kwargs)
File "/home/thiras/.local/share/virtualenvs/rpi-order-data-sync-tA0i1rrc/lib/python3.8/site-packages/authlib/integrations/requests_client/oauth2_session.py", line 113, in request
return super(OAuth2Session, self).request(
File "/home/thiras/.local/share/virtualenvs/rpi-order-data-sync-tA0i1rrc/lib/python3.8/site-packages/requests/sessions.py", line 516, in request
prep = self.prepare_request(req)
File "/home/thiras/.local/share/virtualenvs/rpi-order-data-sync-tA0i1rrc/lib/python3.8/site-packages/requests/sessions.py", line 449, in prepare_request
p.prepare(
File "/home/thiras/.local/share/virtualenvs/rpi-order-data-sync-tA0i1rrc/lib/python3.8/site-packages/requests/models.py", line 318, in prepare
self.prepare_auth(auth, url)
File "/home/thiras/.local/share/virtualenvs/rpi-order-data-sync-tA0i1rrc/lib/python3.8/site-packages/requests/models.py", line 549, in prepare_auth
r = auth(self)
File "/home/thiras/.local/share/virtualenvs/rpi-order-data-sync-tA0i1rrc/lib/python3.8/site-packages/authlib/integrations/requests_client/oauth2_session.py", line 41, in __call__
raise UnsupportedTokenTypeError(description=description)
authlib.integrations.base_client.errors.UnsupportedTokenTypeError: unsupported_token_type: Unsupported token_type: 'user access token'
I've noticed Compliance fix for non-standard section at Authlib documentation but couldn't figure out how to do this fix or even possible in this way.
I've found a solution and it also works with requests-oauthlib package. It seems working flawlessly so far. The main struggle was to create a fake request.Response model since request.Response has no setter for .text or .content attributes so modifying them was impossible.
So I've created a FakeResponse class that only mimics .json() method since it was the only method used by Authlib.
class FakeResponse:
""" Fake Class for Request Response class. """
def __init__(self, data):
self.data = data
def json(self):
""" Mocks requests.Response.json(). """
return self.data
After that I've created an access_token_response hook;
def non_compliant_token_type(resp):
data = resp.json()
data["token_type"] = "Bearer"
fake_resp = FakeResponse(data=data)
return fake_resp
Please let me know if you have a better answer or any recommendations to improve it.
Explicit waits in my codes are not working in SafariDriver 2.48.0. it's working in chrome in windows and MAC. when wait is reached it's driver throwing exception
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/selenium/webdriver/support/wait.py", line 71, in until
value = method(self._driver)
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/selenium/webdriver/support/expected_conditions.py", line 78, in call
return _element_if_visible(_find_element(driver, self.locator))
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/selenium/webdriver/support/expected_conditions.py", line 98, in _element_if_visible
return element if element.is_displayed() == visibility else False
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/selenium/webdriver/remote/webelement.py", line 358, in is_displayed
return self._execute(Command.IS_ELEMENT_DISPLAYED)['value']
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/selenium/webdriver/remote/webelement.py", line 494, in _execute
return self._parent.execute(command, params)
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/selenium/webdriver/remote/webdriver.py", line 236, in execute
self.error_handler.check_response(response)
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/selenium/webdriver/remote/errorhandler.py", line 163, in check_response
raise exception_class(value)
My code is:
self.driver = webdriver.Safari()
self.driver.wait = WebDriverWait(self.driver, 60)
self.driver.get("http://example.com")
# Click Sign in button and wait for sign in page
self.driver.find_element_by_xpath(XMLDict['SignIn'].Xpath).click()
self.driver.wait.until(EC.visibility_of_element_located((By.ID, XMLDict['User'].ID)))
self.driver.maximize_window()
Configuration:
OS - macOS Sierra
Selenium 3.0.1
Safari - 10.0.1
SafariDriver - 2.48.0
Python 3.5
Xpath doesn't work well with Safari, try to solve your problem with CSS_SELECTOR, ID, or CLASS_NAME
This is the error log:
[I 160308 11:09:59 web:1908] 200 GET /admin/realtime (117.93.180.216) 107.13ms
[E 160308 11:09:59 http1connection:54] Uncaught exception
Traceback (most recent call last):
File "/usr/local/lib/python3.4/dist-packages/tornado/http1connection.py", line 238, in _read_message
delegate.finish()
File "/usr/local/lib/python3.4/dist-packages/tornado/httpserver.py", line 290, in finish
self.delegate.finish()
File "/usr/local/lib/python3.4/dist-packages/tornado/web.py", line 1984, in finish
self.execute()
File "/usr/local/lib/python3.4/dist-packages/blueware-1.0.10/blueware/hooks/framework_tornado/web.py", line 480, in _bw_wrapper__RequestDispatcher_execute
future = wrapped(*args, **kwargs)
File "/usr/local/lib/python3.4/dist-packages/tornado/web.py", line 2004, in execute
**self.handler_kwargs)
File "/usr/local/lib/python3.4/dist-packages/blueware-1.0.10/blueware/hooks/framework_tornado/web.py", line 448, in _bw_wrapper_RequestHandler___init___
return wrapped(*args, **kwargs)
File "/usr/local/lib/python3.4/dist-packages/tornado/web.py", line 185, in init
self.initialize(**kwargs)
File "/usr/local/lib/python3.4/dist-packages/tornado/web.py", line 2714, in wrapper
self.redirect(url)
File "/usr/local/lib/python3.4/dist-packages/tornado/web.py", line 671, in redirect
self.finish()
File "/usr/local/lib/python3.4/dist-packages/blueware-1.0.10/blueware/hooks/framework_tornado/web.py", line 309, in _bw_wrapper_RequestHandler_finish_
return wrapped(*args, **kwargs)
File "/usr/local/lib/python3.4/dist-packages/tornado/web.py", line 934, in finish
self.flush(include_footers=True)
File "/usr/local/lib/python3.4/dist-packages/tornado/web.py", line 870, in flush
for transform in self._transforms:
TypeError: 'NoneType' object is not iterable
[I 160308 11:10:00 web:1908] 200 GET /admin/order?order_type=1&order_status=1&page=0&action=allreal (49.89.27.173) 134.53ms
Can anyone tell me how to solve this problem? Thank you very much
I assume that OneAPM (blueware agent) is compatible with your python and Tornado version, however it's can be tricky.
Solution
Move self.redirect(url) from your handler initialize method to get method, like this
class MyHandler(tornado.web.RequestHandler):
def get(self):
self.redirect('/some_url')
or use RedirectHandler.
Every action that could finish request needs to be called in context of http-verb method (get, post, put and so on). The common mistake is making authetication/authorization in __init__ or initialize.
More detail
In Tornado's source there is a note about _transforms that is initialized in the constructor with None and set in_execute (oversimplifying - after headers_received).
A transform modifies the result of an HTTP request (e.g., GZip encoding).
Applications are not expected to create their own OutputTransforms
or interact with them directly; the framework chooses which transforms
(if any) to apply.
Reproduce
Sample that triggers this error. I'm including this only as a cross-check that blueware is not the cause:
import tornado.ioloop
import tornado.web
class SomeHandler(tornado.web.RequestHandler):
def initialize(self, *args, **kwargs):
url = '/some'
self.redirect(url)
# ^ this is wrong
def get(self):
# redirect should be here
self.write("Hello")
def make_app():
return tornado.web.Application([
(r"/", SomeHandler),
])
if __name__ == "__main__":
app = make_app()
app.listen(8888)
tornado.ioloop.IOLoop.current().start()
And stacktrace:
ERROR:tornado.application:Uncaught exception
Traceback (most recent call last):
File "/tmp/py3/lib/python3.4/site-packages/tornado/http1connection.py", line 238, in _read_message
delegate.finish()
File "/tmp/py3/lib/python3.4/site-packages/tornado/httpserver.py", line 289, in finish
self.delegate.finish()
File "/tmp/py3/lib/python3.4/site-packages/tornado/web.py", line 2022, in finish
self.execute()
File "/tmp/py3/lib/python3.4/site-packages/tornado/web.py", line 2042, in execute
**self.handler_kwargs)
File "/tmp/py3/lib/python3.4/site-packages/tornado/web.py", line 183, in __init__
self.initialize(**kwargs)
File "test.py", line 8, in initialize
self.redirect(url)
File "/tmp/py3/lib/python3.4/site-packages/tornado/web.py", line 666, in redirect
self.finish()
File "/tmp/py3/lib/python3.4/site-packages/tornado/web.py", line 932, in finish
self.flush(include_footers=True)
File "/tmp/py3/lib/python3.4/site-packages/tornado/web.py", line 868, in flush
for transform in self._transforms:
TypeError: 'NoneType' object is not iterable
I have a small script that repeatedly (hourly) fetches tweets from the API, using sixohsix's
Twitter Wrapper for Python. I am successful with handling most, if not all of the errors coming from the Twitter API, i.e. all the 5xx and 4xx stuff.
Nonetheless I randomly observe the below error traceback (only once in 2-3 days). I mean the program exits and the traceback is displayed in the shell. I have no clue what this could mean, but think it is not directly related to what my script does since it has proved itself to correctly run most of the time.
This is where I call a function of the wrapper in my script:
KW = {
'count': 200, # number of tweets to fetch (fetch maximum)
'user_id' : tweeter['user_id'],
'include_rts': 'false', # do not include native RT's
'trim_user' : 'true',
}
timeline = tw.twitter_request(tw_endpoint,\
tw_endpoint.statuses.user_timeline, KW)
The function tw.twitter_request(tw_endpoint, tw_endpoint.statuses.user_timeline, KW) basically does return tw_endpoint.statuses_user_timeline(**args), where args translate to KW, and tw_endpoint is an OAuthorized endpoint gained from using the sixohsix's library's
return twitter.Twitter(domain='api.twitter.com', api_version='1.1',
auth=twitter.oauth.OAuth(access_token, access_token_secret,
consumer_key, consumer_secret))
This is the traceback:
Traceback (most recent call last):
File "search_twitter_entities.py", line 166, in <module>
tw_endpoint.statuses.user_timeline, KW)
File "/home/tg/mild/twitter_utils.py", line 171, in twitter_request
return twitter_function(**args)
File "build/bdist.linux-x86_64/egg/twitter/api.py", line 173, in __call__
File "build/bdist.linux-x86_64/egg/twitter/api.py", line 177, in _handle_response
File "/usr/lib/python2.7/urllib2.py", line 126, in urlopen
return _opener.open(url, data, timeout)
File "/usr/lib/python2.7/urllib2.py", line 400, in open
response = self._open(req, data)
File "/usr/lib/python2.7/urllib2.py", line 418, in _open
'_open', req)
File "/usr/lib/python2.7/urllib2.py", line 378, in _call_chain
result = func(*args)
File "/usr/lib/python2.7/urllib2.py", line 1215, in https_open
return self.do_open(httplib.HTTPSConnection, req)
File "/usr/lib/python2.7/urllib2.py", line 1180, in do_open
r = h.getresponse(buffering=True)
File "/usr/lib/python2.7/httplib.py", line 1030, in getresponse
response.begin()
File "/usr/lib/python2.7/httplib.py", line 407, in begin
version, status, reason = self._read_status()
File "/usr/lib/python2.7/httplib.py", line 371, in _read_status
raise BadStatusLine(line)
httplib.BadStatusLine: ''
The only thing I can gain from that traceback is that the error happens somewhere deep inside another Python library and has something to do with an invalid HTTP stat coming from the Twitter API or the wrapper... But as I said, maybe some of you could give me a hint on how to debug/solve this since it is pretty annoying having to regularly check my script and restart it to continue fetching tweets.
EDIT: To clarify this a little, the first two functions in the traceback are already in a try-except block. For example, the try-except-Block in File "twitter_utils.py" filters out 40x and 50x exceptions, but also looks for general exceptions with only except:. So what I don't understand is why the error is not getting caught at this position and instead, the program is force-closed and a traceback printed? Shortly speaking I am in the situation where I cannot catch an error, just like a parse error in a PHP script. So how would I do this?
Perhaps this will point you in the right direction. This is what's being called when BadStatusLine is called upon:
class BadStatusLine(HTTPException):
def __init__(self, line):
if not line:
line = repr(line)
self.args = line,
self.line = line
I'm not too familiar with httplib, but if I had to guess, you're geting an empty response/error line and, well, it can't be parsed. There are comments before the line you're program is stopping at:
# Presumably, the server closed the connection before
# sending a valid response.
raise BadStatusLine(line)
If twitter is closing the connection before sending a response, you could try again, meaning do a try/except at "search_twitter_entities.py", line 166 a couple times (ugly).
try:
timeline = tw.twitter_request(tw_endpoint,\
tw_endpoint.statuses.user_timeline, KW)
except:
try:
timeline = tw.twitter_request(tw_endpoint,\
tw_endpoint.statuses.user_timeline, KW) # try again
except:
pass
Or, assuming you can reassign timeline as none each time, do a while loop:
timeline = None
while timeline == None:
try:
timeline = tw.twitter_request(tw_endpoint,\
tw_endpoint.statuses.user_timeline, KW)
except:
pass
I didn't test of of that. Check for bad code.