1############################################################################### 2# 3# The MIT License (MIT) 4# 5# Copyright (c) Crossbar.io Technologies GmbH 6# 7# Permission is hereby granted, free of charge, to any person obtaining a copy 8# of this software and associated documentation files (the "Software"), to deal 9# in the Software without restriction, including without limitation the rights 10# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11# copies of the Software, and to permit persons to whom the Software is 12# furnished to do so, subject to the following conditions: 13# 14# The above copyright notice and this permission notice shall be included in 15# all copies or substantial portions of the Software. 16# 17# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23# THE SOFTWARE. 24# 25############################################################################### 26 27from __future__ import absolute_import 28 29from txaio._version import __version__ 30from txaio.interfaces import IFailedFuture, ILogger 31 32version = __version__ 33 34# This is the API 35# see tx.py for Twisted implementation 36# see aio.py for asyncio/trollius implementation 37 38 39class _Config(object): 40 """ 41 This holds all valid configuration options, accessed as 42 class-level variables. For example, if you were using asyncio: 43 44 .. sourcecode:: python 45 46 txaio.config.loop = asyncio.get_event_loop() 47 48 ``loop`` is populated automatically (while importing one of the 49 framework-specific libraries) but can be changed before any call 50 into this library. Currently, it's only used by :meth:`call_later` 51 If using asyncio, you must set this to an event-loop (by default, 52 we use asyncio.get_event_loop). If using Twisted, set this to a 53 reactor instance (by default we "from twisted.internet import 54 reactor" on the first call to call_later) 55 """ 56 #: the event-loop object to use 57 loop = None 58 59 60__all__ = ( 61 'with_config', # allow mutliple custom configurations at once 62 'using_twisted', # True if we're using Twisted 63 'using_asyncio', # True if we're using asyncio 64 'use_twisted', # sets the library to use Twisted, or exception 65 'use_asyncio', # sets the library to use asyncio, or exception 66 67 'config', # the config instance, access via attributes 68 69 'create_future', # create a Future (can be already resolved/errored) 70 'create_future_success', 71 'create_future_error', 72 'create_failure', # return an object implementing IFailedFuture 73 'as_future', # call a method, and always return a Future 74 'is_future', # True for Deferreds in tx and Futures, @coroutines in asyncio 75 'reject', # errback a Future 76 'resolve', # callback a Future 77 'cancel', # cancel a Future 78 'add_callbacks', # add callback and/or errback 79 'gather', # return a Future waiting for several other Futures 80 'is_called', # True if the Future has a result 81 82 'call_later', # call the callback after the given delay seconds 83 84 'failure_message', # a printable error-message from a IFailedFuture 85 'failure_traceback', # returns a traceback instance from an IFailedFuture 86 'failure_format_traceback', # a string, the formatted traceback 87 88 'make_batched_timer', # create BatchedTimer/IBatchedTimer instances 89 90 'make_logger', # creates an object implementing ILogger 91 'start_logging', # initializes logging (may grab stdin at this point) 92 'set_global_log_level', # Set the global log level 93 'get_global_log_level', # Get the global log level 94 'add_log_categories', 95 96 'IFailedFuture', # describes API for arg to errback()s 97 'ILogger', # API for logging 98 99 'sleep', # little helper for inline sleeping 100) 101 102 103_explicit_framework = None 104 105 106def use_twisted(): 107 global _explicit_framework 108 if _explicit_framework is not None and _explicit_framework != 'twisted': 109 raise RuntimeError("Explicitly using '{}' already".format(_explicit_framework)) 110 _explicit_framework = 'twisted' 111 from txaio import tx 112 _use_framework(tx) 113 import txaio 114 txaio.using_twisted = True 115 txaio.using_asyncio = False 116 117 118def use_asyncio(): 119 global _explicit_framework 120 if _explicit_framework is not None and _explicit_framework != 'asyncio': 121 raise RuntimeError("Explicitly using '{}' already".format(_explicit_framework)) 122 _explicit_framework = 'asyncio' 123 from txaio import aio 124 _use_framework(aio) 125 import txaio 126 txaio.using_twisted = False 127 txaio.using_asyncio = True 128 129 130def _use_framework(module): 131 """ 132 Internal helper, to set this modules methods to a specified 133 framework helper-methods. 134 """ 135 import txaio 136 for method_name in __all__: 137 if method_name in ['use_twisted', 'use_asyncio']: 138 continue 139 setattr(txaio, method_name, 140 getattr(module, method_name)) 141 142 143# use the "un-framework", which is neither asyncio nor twisted and 144# just throws an exception -- this forces you to call .use_twisted() 145# or .use_asyncio() to use the library. 146from txaio import _unframework # noqa 147_use_framework(_unframework) 148