class RequestManager: logger = logging.getLogger("web3.RequestManager") def __init__(self, web3, provider=None, middlewares=None): self.web3 = web3 self.pending_requests = {} if middlewares is None: middlewares = self.default_middlewares(web3) self.middleware_onion = NamedElementOnion(middlewares) if provider is None: self.provider = AutoProvider() else: self.provider = provider web3 = None _provider = None @property def provider(self): return self._provider @provider.setter def provider(self, provider): self._provider = provider @staticmethod def default_middlewares(web3): """ List the default middlewares for the request manager. Leaving ens unspecified will prevent the middleware from resolving names. """ return [ (request_parameter_normalizer, 'request_param_normalizer'), (gas_price_strategy_middleware, 'gas_price_strategy'), (name_to_address_middleware(web3), 'name_to_address'), (attrdict_middleware, 'attrdict'), (pythonic_middleware, 'pythonic'), (normalize_errors_middleware, 'normalize_errors'), (validation_middleware, 'validation'), (abi_middleware, 'abi'), ] # # Provider requests and response # def _make_request(self, method, params): request_func = self.provider.request_func( self.web3, tuple(self.middleware_onion)) self.logger.debug("Making request. Method: %s", method) return request_func(method, params) async def _coro_make_request(self, method, params): request_func = self.provider.request_func( self.web3, tuple(self.middleware_onion)) self.logger.debug("Making request. Method: %s", method) return await request_func(method, params) def request_blocking(self, method, params): """ Make a synchronous request using the provider """ response = self._make_request(method, params) if "error" in response: raise ValueError(response["error"]) if response['result'] is None: raise ValueError(f"The call to {method} did not return a value.") return response['result'] async def coro_request(self, method, params): """ Couroutine for making a request using the provider """ response = await self._coro_make_request(method, params) if "error" in response: raise ValueError(response["error"]) if response['result'] is None: raise ValueError(f"The call to {method} did not return a value.") return response['result'] @deprecated_for("coro_request") def request_async(self, raw_method, raw_params): request_id = uuid.uuid4() self.pending_requests[request_id] = spawn( self.request_blocking, raw_method=raw_method, raw_params=raw_params, ) return request_id def receive_blocking(self, request_id, timeout=None): try: request = self.pending_requests.pop(request_id) except KeyError: raise KeyError("Request for id:{0} not found".format(request_id)) else: response = request.get(timeout=timeout) if "error" in response: raise ValueError(response["error"]) return response['result'] def receive_async(self, request_id, *args, **kwargs): raise NotImplementedError("Callback pattern not implemented")
class RequestManager: logger = logging.getLogger("web3.RequestManager") def __init__( self, web3: 'Web3', provider: Optional[BaseProvider] = None, middlewares: Optional[Sequence[Tuple[Middleware, str]]] = None ) -> None: self.web3 = web3 self.pending_requests: Dict[UUID, ThreadWithReturn[RPCResponse]] = {} if middlewares is None: middlewares = self.default_middlewares(web3) self.middleware_onion: MiddlewareOnion = NamedElementOnion(middlewares) if provider is None: self.provider = AutoProvider() else: self.provider = provider web3: 'Web3' = None _provider = None @property def provider(self) -> BaseProvider: return self._provider @provider.setter def provider(self, provider: BaseProvider) -> None: self._provider = provider @staticmethod def default_middlewares( web3: 'Web3' )-> List[Tuple[Middleware, str]]: """ List the default middlewares for the request manager. Leaving ens unspecified will prevent the middleware from resolving names. """ return [ (request_parameter_normalizer, 'request_param_normalizer'), # Delete (gas_price_strategy_middleware, 'gas_price_strategy'), # Add Async (name_to_address_middleware(web3), 'name_to_address'), # Add Async (attrdict_middleware, 'attrdict'), # Delete (pythonic_middleware, 'pythonic'), # Delete (normalize_errors_middleware, 'normalize_errors'), # Add async (validation_middleware, 'validation'), # Add async (abi_middleware, 'abi'), # Delete ] # # Provider requests and response # def _make_request( self, method: Union[RPCEndpoint, Callable[..., RPCEndpoint]], params: Any ) -> RPCResponse: request_func = self.provider.request_func( self.web3, self.middleware_onion) self.logger.debug("Making request. Method: %s", method) return request_func(method, params) async def _coro_make_request( self, method: Union[RPCEndpoint, Callable[..., RPCEndpoint]], params: Any ) -> RPCResponse: request_func = self.provider.request_func( self.web3, self.middleware_onion) self.logger.debug("Making request. Method: %s", method) # type ignored b/c request_func is an awaitable in async model return await request_func(method, params) # type: ignore def request_blocking( self, method: Union[RPCEndpoint, Callable[..., RPCEndpoint]], params: Any, error_formatters: Optional[Callable[..., Any]] = None, ) -> Any: """ Make a synchronous request using the provider """ response = self._make_request(method, params) if "error" in response: apply_error_formatters(error_formatters, response) raise ValueError(response["error"]) elif response['result'] is None: apply_error_formatters(error_formatters, response, params) return response['result'] async def coro_request( self, method: Union[RPCEndpoint, Callable[..., RPCEndpoint]], params: Any, error_formatters: Optional[Callable[..., Any]] = None, ) -> Any: """ Couroutine for making a request using the provider """ response = await self._coro_make_request(method, params) if "error" in response: apply_error_formatters(error_formatters, response) raise ValueError(response["error"]) if response['result'] is None: raise ValueError(f"The call to {method} did not return a value.") return response['result'] @deprecated_for("coro_request") def request_async(self, raw_method: str, raw_params: Any) -> UUID: request_id = uuid.uuid4() self.pending_requests[request_id] = spawn( self.request_blocking, raw_method=raw_method, raw_params=raw_params, ) return request_id def receive_blocking(self, request_id: UUID, timeout: Optional[float] = None) -> Any: try: request = self.pending_requests.pop(request_id) except KeyError: raise KeyError("Request for id:{0} not found".format(request_id)) else: response = request.get(timeout=timeout) if "error" in response: raise ValueError(response["error"]) return response['result'] def receive_async(self, request_id: UUID, *args: Any, **kwargs: Any) -> NoReturn: raise NotImplementedError("Callback pattern not implemented")
class RequestManager: logger = logging.getLogger("web3.RequestManager") def __init__( self, web3: 'Web3', provider: Optional[BaseProvider] = None, middlewares: Optional[Sequence[Tuple[Middleware, str]]] = None) -> None: self.web3 = web3 self.pending_requests: Dict[UUID, ThreadWithReturn[RPCResponse]] = {} if middlewares is None: middlewares = self.default_middlewares(web3) self.middleware_onion: MiddlewareOnion = NamedElementOnion(middlewares) if provider is None: self.provider = AutoProvider() else: self.provider = provider web3: 'Web3' = None _provider = None @property def provider(self) -> BaseProvider: return self._provider @provider.setter def provider(self, provider: BaseProvider) -> None: self._provider = provider @staticmethod def default_middlewares(web3: 'Web3') -> List[Tuple[Middleware, str]]: """ List the default middlewares for the request manager. Leaving ens unspecified will prevent the middleware from resolving names. """ return [ (request_parameter_normalizer, 'request_param_normalizer'), # Delete (gas_price_strategy_middleware, 'gas_price_strategy'), (name_to_address_middleware(web3), 'name_to_address'), # Add Async (attrdict_middleware, 'attrdict'), # Delete (pythonic_middleware, 'pythonic'), # Delete (validation_middleware, 'validation'), (abi_middleware, 'abi'), # Delete (buffered_gas_estimate_middleware, 'gas_estimate'), ] # # Provider requests and response # def _make_request(self, method: Union[RPCEndpoint, Callable[..., RPCEndpoint]], params: Any) -> RPCResponse: request_func = self.provider.request_func(self.web3, self.middleware_onion) self.logger.debug("Making request. Method: %s", method) return request_func(method, params) async def _coro_make_request(self, method: Union[RPCEndpoint, Callable[..., RPCEndpoint]], params: Any) -> RPCResponse: # type ignored b/c request_func is an awaitable in async model request_func = await self.provider.request_func( # type: ignore self.web3, self.middleware_onion) self.logger.debug("Making request. Method: %s", method) return await request_func(method, params) @staticmethod def formatted_response( response: RPCResponse, params: Any, error_formatters: Optional[Callable[..., Any]] = None, null_result_formatters: Optional[Callable[..., Any]] = None, ) -> Any: if "error" in response: apply_error_formatters(error_formatters, response) raise ValueError(response["error"]) # NULL_RESPONSES includes None, so return False here as the default # so we don't apply the null_result_formatters if there is no 'result' key elif response.get('result', False) in NULL_RESPONSES: # null_result_formatters raise either a BlockNotFound # or a TransactionNotFound error, depending on the method called apply_null_result_formatters(null_result_formatters, response, params) return response['result'] elif response.get('result') is not None: return response['result'] else: raise BadResponseFormat( "The response was in an unexpected format and unable to be parsed. " f"The raw response is: {response}") def request_blocking( self, method: Union[RPCEndpoint, Callable[..., RPCEndpoint]], params: Any, error_formatters: Optional[Callable[..., Any]] = None, null_result_formatters: Optional[Callable[..., Any]] = None, ) -> Any: """ Make a synchronous request using the provider """ response = self._make_request(method, params) return self.formatted_response(response, params, error_formatters, null_result_formatters) async def coro_request( self, method: Union[RPCEndpoint, Callable[..., RPCEndpoint]], params: Any, error_formatters: Optional[Callable[..., Any]] = None, null_result_formatters: Optional[Callable[..., Any]] = None, ) -> Any: """ Couroutine for making a request using the provider """ response = await self._coro_make_request(method, params) return self.formatted_response(response, params, error_formatters, null_result_formatters) @deprecated_for("coro_request") def request_async(self, raw_method: str, raw_params: Any) -> UUID: request_id = uuid.uuid4() self.pending_requests[request_id] = spawn( self.request_blocking, raw_method=raw_method, raw_params=raw_params, ) return request_id def receive_blocking(self, request_id: UUID, timeout: Optional[float] = None) -> Any: try: request = self.pending_requests.pop(request_id) except KeyError: raise KeyError("Request for id:{0} not found".format(request_id)) else: response = request.get(timeout=timeout) if "error" in response: raise ValueError(response["error"]) return response['result'] def receive_async(self, request_id: UUID, *args: Any, **kwargs: Any) -> NoReturn: raise NotImplementedError("Callback pattern not implemented")