def test_plain_output(caplog, capsys): logger_name = log.current_logger_name() assert logger_name == "tests.test_logx" FIRST_MESSAGE = "first message" log.info(FIRST_MESSAGE) assert m(caplog) == FIRST_MESSAGE out, err = capsys.readouterr() assert out == FIRST_MESSAGE + "\n" assert not err
def load_env_yaml(path=None): path = path or ENV_YAML try: with io.open(path) as r: log.info(f"loading env vars from yaml: {path}") env_vars = yaml.load(r, Loader=yaml.FullLoader) os.environ.update(env_vars) except FileNotFoundError: log.info(f"local env file not found at {path}, not loading")
def sync_db_structure_to_target_db(db_url, target_db_url, confirm=True, create_extensions_only=False, **kwargs): log.info(f"syncing: {db_url} to {target_db_url}") with S(db_url, poolclass=NullPool) as s_current, S(target_db_url, poolclass=NullPool) as s_target: m = Migration(s_current, s_target, **kwargs) m.set_safety(False) if create_extensions_only: log.info("Syncing extension creation only...") m.add_extension_changes(creates=True, drops=False) else: m.add_all_changes() if m.statements: if confirm: # pragma: no cover print("THE FOLLOWING CHANGES ARE PENDING:", end="\n\n") print(m.sql) print() if not confirm or prompt("Apply these changes?"): log.info("Applying...") m.apply() log.info("Applied.") else: if confirm: # pragma: no cover print("Not applying.") else: if confirm: # pragma: no cover print("Already synced.") current_schema_hash = schema_hash(db_url) if confirm: # pragma: no cover print(f"Schema hash: {current_schema_hash}")
def await_pg_notifications( dburi_or_sqlaengine_or_dbapiconnection, channels=None, timeout=5, yield_on_timeout=False, handle_signals=None, notifications_as_list=False, ): """Subscribe to PostgreSQL notifications, and handle them in infinite-loop style. On an actual message, returns the notification (with .pid, .channel, and .payload attributes). If you've enabled 'yield_on_timeout', yields None on timeout. If you've enabled 'handle_keyboardinterrupt', yields False on interrupt. """ timeout_is_callable = callable(timeout) cc = get_dbapi_connection(dburi_or_sqlaengine_or_dbapiconnection) if channels: if isinstance(channels, string_types): channels = [channels] start_listening(cc, channels) signals_to_handle = handle_signals or [] original_handlers = {} try: wakeup = None if signals_to_handle: for s in signals_to_handle: original_handlers[s] = signal.signal(s, empty_signal_handler) listen_on = [cc] if sys.platform != 'win32': wakeup = get_wakeup_fd() listen_on.append(wakeup) else: warnings.warn("on windows not all signals available", Warning) else: listen_on = [cc] while True: try: if timeout_is_callable: _timeout = timeout() log.debug("dynamic timeout of {} seconds".format(_timeout)) else: _timeout = timeout _timeout = max(0, _timeout) r, w, x = select.select(listen_on, [], [], _timeout) log.debug("select call awoken, returned: {}".format((r, w, x))) if (r, w, x) == ([], [], []): log.debug("idle timeout on select call, carrying on...") if yield_on_timeout: yield None if wakeup is not None and wakeup in r: signal_byte = os.read(wakeup, 1) signal_int = int.from_bytes(signal_byte, sys.byteorder) sig = signal.Signals(signal_int) signal_name = signal.Signals(sig).name log.info( "woken from slumber by signal: {}".format(signal_name)) yield signal_int if cc in r: cc.poll() nlist = [] while cc.notifies: notify = cc.notifies.pop() nlist.append(notify) if notifications_as_list: for n in nlist: log_notification(n) yield nlist else: for n in nlist: log_notification(n) yield n except select.error as e: if sys.version_info >= (3, 3): e_num = e.errno else: e_num = e[0] if e_num == errno.EINTR: log.debug("EINTR happened during select") else: raise finally: if signals_to_handle: for s in signals_to_handle: if s in original_handlers: signal_name = signal.Signals(s).name log.debug("restoring original handler for: {}".format( signal_name)) signal.signal(s, original_handlers[s])
def await_pg_notifications(conn_string, channels=None, timeout=5.0, yield_on_timeout=False, handle_signals=None): """Subscribe to PostgreSQL notifications, and handle them in infinite-loop style. On an actual message, returns the notification (with .pid, .channel, and .payload attributes). If you've enabled 'yield_on_timeout', yields None on timeout. If you've enabled 'handle_keyboardinterrupt', yields False on interrupt. """ check.str_param(conn_string, 'conn_string') channels = None if channels is None else check.list_param( channels, 'channels', of_type=str) check.float_param(timeout, 'timeout') check.bool_param(yield_on_timeout, 'yield_on_timeout') conn = get_conn(conn_string) if channels: start_listening(conn, channels) signals_to_handle = handle_signals or [] original_handlers = {} try: if signals_to_handle: original_handlers = { s: signal.signal(s, _empty_handler) for s in signals_to_handle } wakeup = get_wakeup_fd() listen_on = [conn, wakeup] else: listen_on = [conn] wakeup = None while True: try: r, w, x = select.select(listen_on, [], [], max(0, timeout)) log.debug('select call awoken, returned: {}'.format((r, w, x))) if (r, w, x) == ([], [], []): log.debug('idle timeout on select call, carrying on...') if yield_on_timeout: yield None if wakeup is not None and wakeup in r: signal_byte = os.read(wakeup, 1) signal_int = int.from_bytes(signal_byte, sys.byteorder) sig = construct_signals(signal_int) signal_name = construct_signals(sig).name log.info( 'woken from slumber by signal: {signal_name}'.format( signal_name=signal_name)) yield signal_int if conn in r: conn.poll() notify_list = [] while conn.notifies: notify_list.append(conn.notifies.pop()) for notif in notify_list: log_notification(notif) yield notif except select.error as e: e_num, _e_message = e # pylint: disable=unpacking-non-sequence if e_num == errno.EINTR: log.debug('EINTR happened during select') else: raise finally: for s in signals_to_handle or []: if s in original_handlers: signal_name = construct_signals(s).name log.debug( 'restoring original handler for: {signal_name}'.format( signal_name=signal_name)) signal.signal(s, original_handlers[s])