-
Notifications
You must be signed in to change notification settings - Fork 42
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Is there a way to add timeout, when Google browser popup is closed? #54
Comments
Hmm. It is not natively supported in gcsa. Couldn't find this possibility with You can do it with import signal
def signal_handler(signum, frame):
raise Exception("Timed out!")
signal.signal(signal.SIGALRM, signal_handler)
signal.alarm(60) # 60 seconds
try:
gc = GoogleCalendar(...)
except Exception:
print("Timed out!")
else:
signal.alarm(0) I will think if I want to add it natively to the library. Thank you for the idea and issue submission. |
Thank you! Will try this solution. Closed for now. |
I'll leave it open for now. It is a good feature to think about. And probably a common use case. |
Oh, once you opened the issue, I tried your solution, but there is no |
Ok, so I found an option that "kind of" works on Windows. (Not recommended due to threading issues) Create a import threading
class TimeoutError(Exception):
pass
class InterruptableThread(threading.Thread):
def __init__(self, func, *args, **kwargs):
threading.Thread.__init__(self)
self._func = func
self._args = args
self._kwargs = kwargs
self._result = None
def run(self):
self._result = self._func(*self._args, **self._kwargs)
@property
def result(self):
return self._result
class timeout(object):
def __init__(self, sec):
self._sec = sec
def __call__(self, f):
def wrapped_f(*args, **kwargs):
it = InterruptableThread(f, *args, **kwargs)
it.start()
it.join(self._sec)
if not it.is_alive():
it.join()
return it.result
raise TimeoutError('execution expired')
return wrapped_f In from timeout import timeout, TimeoutError
...
@timeout(60) # 60 seconds, but we can also pass a custom int via the GoogleCalendar class.
def _get_credentials(self):
... And when creating a calendar, wrap it in a try/except: try:
calendar = GoogleCalendar('primary', ...)
except TimeoutError:
pass Hope this helps, when implementing this feature! |
Or, even a better option. The previous one has issues with catching other exceptions, and the timeout thread is not closed when finished, leading to future errors. This code is the only one that worked for me on Windows, without any hidden bugs with closing threads.
from oauthlib.oauth2.rfc6749.errors import AccessDeniedError, MismatchingStateError
from gcsa.google_calendar import GoogleCalendar
from concurrent.futures import TimeoutError
from pebble import concurrent
@concurrent.process(timeout=60) # Raise TimeoutError, if the function exceeds the given deadline (in seconds).
def create_process():
return GoogleCalendar('primary', credentials_path='credentials.json')
def do_something():
try:
process = create_process() # Return concurrent process.
calendar = process.result() # Wait for process result. Return calendar instance, or exceptions, if any were raised.
# Catch exceptions, received from process result.
except TimeoutError: # If user did not log into Google Calendar on time.
pass
except AccessDeniedError: # If user denied access to Google Calendar.
pass
except MismatchingStateError: # If user attempted to login using an outdated browser window.
pass |
That looks perfect. Thank you! I'll try to incorporate it into the library |
Decided to not implement it into the library. Instead provided an example in the documentation if anybody needs this. Thank you @Teraskull for your suggestion! |
Yes, this is a good idea. This feature is to vague to be useful for everyone. Thanks! |
You have some typos in the docs, you can see them here: https://github.com/Teraskull/google-calendar-simple-api/commit/8ab725826c0eaab2b8352ea9baebdfd3d4507569 I don't want to open a whole PR for a few fixes. Just edit them yourself. Thanks. |
Thanks, updated |
Right now, if you close the browser window, the script will hang, waiting for user permission.
Is there a way to add a timeout?
For example, the local server:
If there are no credentials returned for 1 minute, close local server, and return error.
The text was updated successfully, but these errors were encountered: