# Path: weblablib/utils.py
# def create_token(size=None):
#     if size is None:
#         size = 32
#     tok = os.urandom(size)
#     safe_token = base64.urlsafe_b64encode(tok).strip().replace(b'=', b'').replace(b'-', b'_')
#     safe_token = safe_token.decode('utf8')
#     return safe_token
# 
# def _current_backend():
#     return _current_weblab()._backend
# 
# def _current_timestamp():
#     return float(_to_timestamp(datetime.datetime.now()))
# 
# def _current_weblab():
#     if 'weblab' not in current_app.extensions:
#         raise WebLabNotInitializedError("App not initialized with weblab.init_app()")
#     return current_app.extensions['weblab']
# 
# def _current_session_id():
#     return _current_weblab()._session_id()
# 
# Path: weblablib/tasks.py
# class _TaskWrapper(object):
# class WebLabTask(object):
# class _TaskRunner(threading.Thread):
#     def __init__(self, weblab, func, unique):
#     def func(self):
#     def unique(self):
#     def __call__(self, *args, **kwargs):
#     def delay(self, *args, **kwargs):
#     def run_sync(self, *args, **kwargs):
#     def __init__(self, weblab, task_id):
#     def join(self, timeout=None, error_on_timeout=True):
#     def task_id(self):
#     def session_id(self):
#     def name(self):
#     def _is_current_task(self):
#     def data(self):
#     def data(self, new_data):
#     def update_data(self, new_data):
#     def store(self):
#     def retrieve(self):
#     def stop(self):
#     def status(self):
#     def done(self):
#     def running(self):
#     def submitted(self):
#     def failed(self):
#     def finished(self):
#     def stopping(self):
#     def result(self):
#     def error(self):
#     def __repr__(self):
#     def __lt__(self, other):
#     def __cmp__(self, other):
#     def __eq__(self, other):
#     def __hash__(self):
#     def __init__(self, number, weblab, app):
#     def stop(self):
#     def run(self):
# def _current_task():
# def _current_task_stopping():
#     _STEPS_WAITING = 20


import abc
import json
import zlib
import warnings
import six
from werkzeug.datastructures import ImmutableDict
from werkzeug.local import LocalProxy
from flask import g, current_app
from weblablib.utils import create_token, _current_backend, _current_timestamp, \
     _current_weblab, _current_session_id
from weblablib.tasks import current_task
        """
        Did the user call :func:`logout`?
        """
        return self._exited

    @property
    def request_client_data(self):
        """
        Information provided in the beginning of the interaction (on_start): client_data
        """
        return ImmutableDict(self._request_client_data or {})

    @property
    def request_server_data(self):
        """
        Information provided in the beginning of the interaction (on_start): server_data
        """
        return ImmutableDict(self._request_server_data or {})

    @property
    def start_date(self):
        """
        Information provided in the beginning of the interaction (on_start): client_data
        """
        return self._start_date

    def add_action(self, session_id, action):
        """
        Adds a new raw action to a session_id, returning the action_id
        """

# Path: weblablib/utils.py
# def create_token(size=None):
#     if size is None:
#         size = 32
#     tok = os.urandom(size)
#     safe_token = base64.urlsafe_b64encode(tok).strip().replace(b'=', b'').replace(b'-', b'_')
#     safe_token = safe_token.decode('utf8')
#     return safe_token
# 
# def _current_backend():
#     return _current_weblab()._backend
# 
# def _current_timestamp():
#     return float(_to_timestamp(datetime.datetime.now()))
# 
# def _current_weblab():
#     if 'weblab' not in current_app.extensions:
#         raise WebLabNotInitializedError("App not initialized with weblab.init_app()")
#     return current_app.extensions['weblab']
# 
# def _current_session_id():
#     return _current_weblab()._session_id()
# 
# Path: weblablib/tasks.py
# class _TaskWrapper(object):
# class WebLabTask(object):
# class _TaskRunner(threading.Thread):
#     def __init__(self, weblab, func, unique):
#     def func(self):
#     def unique(self):
#     def __call__(self, *args, **kwargs):
#     def delay(self, *args, **kwargs):
#     def run_sync(self, *args, **kwargs):
#     def __init__(self, weblab, task_id):
#     def join(self, timeout=None, error_on_timeout=True):
#     def task_id(self):
#     def session_id(self):
#     def name(self):
#     def _is_current_task(self):
#     def data(self):
#     def data(self, new_data):
#     def update_data(self, new_data):
#     def store(self):
#     def retrieve(self):
#     def stop(self):
#     def status(self):
#     def done(self):
#     def running(self):
#     def submitted(self):
#     def failed(self):
#     def finished(self):
#     def stopping(self):
#     def result(self):
#     def error(self):
#     def __repr__(self):
#     def __lt__(self, other):
#     def __cmp__(self, other):
#     def __eq__(self, other):
#     def __hash__(self):
#     def __init__(self, number, weblab, app):
#     def stop(self):
#     def run(self):
# def _current_task():
# def _current_task_stopping():
#     _STEPS_WAITING = 20


# Path: weblablib/users.py
import abc
import json
import zlib
import warnings
import six
from werkzeug.datastructures import ImmutableDict
from werkzeug.local import LocalProxy
from flask import g, current_app
from weblablib.utils import create_token, _current_backend, _current_timestamp, \
     _current_weblab, _current_session_id
from weblablib.tasks import current_task

        """
        Did the user call :func:`logout`?
        """
        return self._exited

    @property
    def request_client_data(self):
        """
        Information provided in the beginning of the interaction (on_start): client_data
        """
        return ImmutableDict(self._request_client_data or {})

    @property
    def request_server_data(self):
        """
        Information provided in the beginning of the interaction (on_start): server_data
        """
        return ImmutableDict(self._request_server_data or {})

    @property
    def start_date(self):
        """
        Information provided in the beginning of the interaction (on_start): client_data
        """
        return self._start_date

    def add_action(self, session_id, action):
        """
        Adds a new raw action to a session_id, returning the action_id
        """

        action_id = create_token()