def get_price_from_oracle(self, addy: str, exchange_info: ExchangeInfo) -> Result[TokenPrices, str]: """ Ask the pricegetter to get the price of a token and returns its under the form of a nice message. """ token_info: TokenMetadata = self.web3_helper.get_token_info_from_address(address=addy, w3=exchange_info.web3) now = ValueWithName('now', int(time.time())) one_hour_ago = ValueWithName('1H ', now.value - 3600) one_day_ago = ValueWithName('24H', now.value - 3600 * 24) one_week_ago = ValueWithName('7D ', now.value - 3600 * 24 * 7) one_month_ago = ValueWithName('30D', now.value - 3600 * 24 * 30) res: Result[List[PricePoint], Exception] = self.get_historical_price_from_contract(addy, exchange_info.exchange.chain, [now, one_hour_ago, one_day_ago, one_week_ago, one_month_ago]) if isinstance(Failure, res.__class__): message = "Error getting price info for ticker " + token_info.ticker logging.error( "Failure when getting historical price from contract for ticker %s, addy %s, chain %s, exchange %s", token_info.ticker, addy, exchange_info.exchange.chain, exchange_info.exchange.name, res.failure()) return Failure(message) prices: List[PricePoint] = res.unwrap() p_now = now.associate_price_point(prices) p_1_h_ago = one_hour_ago.associate_price_point(prices) p_1_d_ago = one_day_ago.associate_price_point(prices) p_1_w_ago = one_week_ago.associate_price_point(prices) p_1_m_ago = one_month_ago.associate_price_point(prices) if p_now is None: message = "Error getting price info for ticker " + token_info.ticker logging.error("Impossible to get price now for ticker %s, addy %s, chain %s, exchange %s", token_info.ticker, addy, exchange_info.exchange.chain, exchange_info.exchange.name) return Failure(message) return Success(TokenPrices(metadata=token_info, exchange_info=exchange_info.exchange, price_now=p_now, prices_historical=list(filter(None, [p_1_h_ago, p_1_d_ago, p_1_w_ago, p_1_m_ago]))))
def from_failure( cls, inner_value: _FirstType, ) -> 'RequiresContextResult[NoDeps, Any, _FirstType]': """ Creates new container with ``Failure(inner_value)`` as a unit value. .. code:: python >>> from returns.context import RequiresContextResult >>> from returns.result import Failure >>> assert RequiresContextResult.from_failure(1)(...) == Failure(1) """ return RequiresContextResult(lambda _: Failure(inner_value))
def _get_non_detections(self, object_id): try: non_detections = self.db.query().find_all( model=mongo_models.NonDetection, filter_by={ "aid": object_id, "tid": { "$regex": "ATLAS*" } }, paginate=False, ) return Success(list(non_detections)) except Exception as e: return Failure(ServerErrorException(e))
def test_bind(): """Ensures that bind works.""" def factory(inner_value: int) -> RCR[int, float, str]: if inner_value > 0: return RCR(lambda deps: Success(inner_value / deps)) return RCR.from_failure(str(inner_value)) input_value = 5 bound: RCR[int, int, str] = RCR.from_success(input_value) assert bound.bind(factory)(2) == factory(input_value)(2) assert bound.bind(factory)(2) == Success(2.5) assert RCR.from_success(0).bind( factory, )(2) == factory(0)(2) == Failure('0')
def from_failed_context( cls, inner_value: 'RequiresContext[_NewValueType, _NewEnvType]', ) -> RequiresContextResult[Any, _NewValueType, _NewEnvType]: """ Creates new container from ``RequiresContext`` as a failure unit. .. code:: python >>> from returns.context import RequiresContext >>> from returns.result import Failure >>> assert RequiresContextResult.from_failed_context( ... RequiresContext.from_value(1), ... )(...) == Failure(1) """ return RequiresContextResult(lambda deps: Failure(inner_value(deps)))
def get(self, object_id, survey_id): astro_object = self._get_object(object_id, survey_id) if is_successful(astro_object): aid = astro_object.unwrap()["aid"] detections = self._get_detections(aid) if is_successful(detections) and len(detections.unwrap()) > 0: return detections else: raise Failure( ClientErrorException( ObjectNotFound(object_id=object_id, survey_id=self.survey_id))) else: return astro_object
def __verify_response( self, response: JsonResponse ) -> Result[KSQLStreamDetailed, DataProviderFailureDetails]: _response = response[0] if _response.get("@type") == "statement_error": return Failure( DataProviderFailureDetails( reason="STATEMENT_ERROR", dataprovider_type="REST", attributes={ "message": _response["message"], "statementText": _response["statementText"], }, )) stream = KSQLStreamDetailed(**_response["sourceDescription"]) return Success(stream)
def __verify_response( self, response: JsonResponse ) -> Result[List[KSQLStream], DataProviderFailureDetails]: _response = response[0] if _response.get("@type") == "statement_error": return Failure( DataProviderFailureDetails( reason="STATEMENT_ERROR", dataprovider_type="REST", attributes={ "message": _response["message"], "statementText": _response["statementText"], }, )) return Success( [KSQLStream(**stream) for stream in _response["streams"]])
def get(self, object_id, survey_id): astro_object = self._get_object(object_id, survey_id) if is_successful(astro_object): aid = astro_object.unwrap()["aid"] non_detections = self._get_non_detections(aid) if is_successful(non_detections): return non_detections else: return Failure( ClientErrorException( ObjectNotFound(object_id=object_id, survey_id=survey_id))) else: return astro_object
def __validate_response( self, response: Response ) -> Result[JsonResponse, DataProviderFailureDetails]: http_status = HttpStatus(response.status_code) if http_status in [HttpStatus.OK, HttpStatus.CREATED]: return Success(response.json()) return Failure( DataProviderFailureDetails( dataprovider_type="REST", reason=http_status.name, attributes={ "origin": "HTTP_STATUS", "http_status_code": http_status.value, "response": response.json(), }, ) )
def iterable_data_handler(raw_data, paths) -> ResultE[list]: """Iterate and create all combinations from list of paths.""" if not paths: return Failure(ValueError('No paths')) path, rest = paths[0], paths[1:] if not rest: return create_iterable(raw_data, path) my_list: list = [] for iterable in create_iterable(raw_data, path).unwrap(): iterable_data_handler(iterable, rest).map(my_list.extend, ) return Success(my_list)
def maybe_to_result( maybe_container: Maybe[_ValueType], ) -> Result[_ValueType, None]: """ Converts ``Maybe`` container to ``Result`` container. .. code:: python >>> from returns.maybe import Some, Nothing >>> from returns.result import Failure, Success >>> assert maybe_to_result(Some(1)) == Success(1) >>> assert maybe_to_result(Nothing) == Failure(None) >>> assert maybe_to_result(Some(None)) == Failure(None) """ if is_successful(maybe_container): return Success(maybe_container.unwrap()) return Failure(None)
def maybe_to_result( maybe_container: Maybe[_ValueType], ) -> Result[_ValueType, None]: """ Converts ``Maybe`` container to ``Result`` container. .. code:: python >>> from returns.maybe import Some, Nothing >>> from returns.result import Failure, Success >>> assert maybe_to_result(Nothing) == Failure(None) >>> assert maybe_to_result(Some(1)) == Success(1) >>> assert maybe_to_result(Some(None)) == Failure(None) """ inner_value = maybe_container.value_or(None) if inner_value is not None: return Success(inner_value) return Failure(inner_value)
def iterable_data_handler( raw_data: dict, iterators: List[Iterator], ) -> ResultE[list]: """Iterate and create all combinations from list of iterators.""" if not iterators: return Failure(ValueError('No iterators')) iterable, rest = iterators[0], iterators[1:] if not rest: return create_iterable(raw_data, iterable) my_list: list = [] for iterable_list in create_iterable(raw_data, iterable).unwrap(): iterable_data_handler(iterable_list, rest).map(my_list.extend, ) return Success(my_list)
def decorator(*args: Any, **kwargs: Any) -> Result[_SuccessType, _FailureType]: try: json_body = orjson.loads(request.data) request_body = Success(clazz(**json_body)) except (ValidationError, TypeError) as error: raw_errors = getattr(error, "raw_errors", []) errors = {e._loc: e.exc.msg_template for e in raw_errors} failure = NewFailureDetails( reason="BODY_PARSE_ERROR", failure_message= "Body request has to match exactly as the body schema", # noqa: E501 attributes={ "expected_body_schema": clazz.__pydantic_model__.schema(), "field_errors": errors, }, ) request_body = Failure(_create_response(failure, 400)) return function(*args, **kwargs, request_body=request_body)
def test_should_return_failure_when_get_stream_by_name_fails( get_stream_details_use_case: GetStreamDetailsUseCase, find_stream_by_stream_id: Mock, find_projects_by_stream: Mock, get_stream_by_name: Mock, ) -> None: stream_id = uuid4() stream = Stream( stream_id=stream_id, name="TEST_STREAM", source_type=SourceType.STREAM, source_name="OTHER_STREAM_TEST", ) project_list = [ Project( project_id=uuid4(), title="Project One", created_at=datetime.now(), status=ProjectStatus.ACTIVE, ), Project( project_id=uuid4(), title="Project Two", created_at=datetime.now(), status=ProjectStatus.INACTIVE, ), ] failure = FailureDetails(reason="TEST_FIND_STREAM_BY_NAME_FAILS") find_stream_by_stream_id.return_value = Success(Maybe.from_value(stream)) find_projects_by_stream.return_value = Success(project_list) get_stream_by_name.return_value = Failure(failure) actual = get_stream_details_use_case(stream_id) get_stream_by_name.assert_called_once() get_stream_by_name.assert_called_with(stream.name) assert isinstance(actual, Result.failure_type) assert isinstance(actual.failure(), FailureDetails) assert failure == actual.failure()
async def test_inner_value(subtests): """Ensure that coroutine correct value is preserved for all units.""" containers = [ # We have to define these values inside the test, because # otherwise `anyio` will `await` reused coroutines. # And they have to be fresh. That's why we use subtests for it. FutureResult.from_value(1), FutureResult.from_failure(1), FutureResult.from_io(IO(1)), FutureResult.from_failed_io(IO(1)), FutureResult.from_ioresult(IOSuccess(1)), FutureResult.from_ioresult(IOFailure(1)), FutureResult.from_result(Success(1)), FutureResult.from_result(Failure(1)), FutureResult.from_future(Future.from_value(1)), FutureResult.from_failed_future(Future.from_value(1)), FutureResult.from_typecast(Future.from_value(Success(1))), ] for container in containers: with subtests.test(container=container): result_inst = await container assert result_inst._inner_value._inner_value == 1 # noqa: WPS437
def from_failure( cls, inner_value: _NewErrorType, ) -> 'FutureResult[Any, _NewErrorType]': """ Creates ``FutureResult`` from failed value. .. code:: python >>> import anyio >>> from returns.io import IOFailure >>> from returns.future import FutureResult >>> async def main(): ... assert await FutureResult.from_failure( ... 1, ... ) == IOFailure(1) >>> anyio.run(main) """ return FutureResult(async_identity(Failure(inner_value)))
def test_assert_failure(): assert_failure(Failure(123), 123) assert_failure(Failure(ValueError("test")), ValueError("test")) with raises(AssertionError): assert_failure(Failure(123), 567) with raises(AssertionError): assert_failure(Failure(123), "ABC") with raises(AssertionError): assert_failure(Failure(123), "ABC") with raises(AssertionError): assert_failure(Success(123), 123) with raises(AssertionError): assert_failure(Failure(ValueError("ABC")), ValueError("DEF")) with raises(AssertionError): assert_failure(Failure(ValueError("ABC")), IOError("ABC"))
def _cast_with_millennia( self, value_to_cast: str, original_format: str, ) -> ResultE[str]: # mm[.]dd[.]yyyy any separator if self._mmddyyyy_pattern.match(original_format): return self._apply_regex_sub( r'(\d{2})[^\w]?(\d{2})[^\w]?(\d{4})', r'\3-\1-\2', value_to_cast, ) # dd[.]mm[.]yyyy any separator if self._ddmmyyyy_pattern.match(original_format): return self._apply_regex_sub( r'(\d{2})[^\w]?(\d{2})[^\w]?(\d{4})', r'\3-\2-\1', value_to_cast, ) # yyyy[.]mm[.]dd any separator if self._yyyymmdd_pattern.match(original_format): return self._apply_regex_sub( r'(\d{4})[^\w]?(\d{2})[^\w]?(\d{2})', r'\1-\2-\3', value_to_cast, ) return Failure( ValueError( 'Unable to case to milennia format: {value}'.format( value=value_to_cast, ), ), )
def test_should_return_failure_when_find_projects_by_stream_fails( get_stream_details_use_case: GetStreamDetailsUseCase, find_stream_by_stream_id: Mock, find_projects_by_stream: Mock, ) -> None: stream_id = uuid4() stream = Stream( stream_id=stream_id, name="TEST_STREAM", source_type=SourceType.STREAM, source_name="OTHER_STREAM_TEST", ) failure = FailureDetails(reason="TEST_FIND_PROJECTS_FAILS") find_stream_by_stream_id.return_value = Success(Maybe.from_value(stream)) find_projects_by_stream.return_value = Failure(failure) actual = get_stream_details_use_case(stream_id) find_projects_by_stream.assert_called_once() find_projects_by_stream.assert_called_with(stream) assert isinstance(actual, Result.failure_type) assert isinstance(actual.failure(), FailureDetails) assert failure == actual.failure()
def repartition(self, df: DataFrame, cluster_spec: ClusterSpec) -> Result[DataFrame, InvalidJob]: size = df.size.compute() num_partitions = self.partitions if cluster_spec.valid(): cluster_spec_num_workers = cluster_spec.num_workers() else: cluster_spec_num_workers = None num_workers = num_partitions or cluster_spec_num_workers if num_workers: max_partition_size = cluster_spec.max_partition_size() even_partition_size = size / num_workers if max_partition_size: if even_partition_size > max_partition_size: return Failure(InvalidJob(f"Partitions too large for workers: (size, max) = ({even_partition_size}, {max_partition_size}). Add more workers or increase worker memory.")) else: return Success(df.repartition(partition_size=even_partition_size).repartition(npartitions=num_workers)) else: return Success(df.repartition(partition_size=even_partition_size).repartition(npartitions=num_workers)) else: return Success(df)
def apply_casting( value_to_cast: Optional[MapValue], casting: Dict[str, Any], ) -> ResultE[MapValue]: """Cast one type of code to another. :param casting: :term:`casting` object :type casting: dict :param value_to_cast: The value to cast to casting['to'] :type value_to_cast: MapValue :return: Success/Failure containers :rtype: MapValue Example >>> apply_casting('123', {'to': 'integer'}).unwrap() 123 >>> apply_casting('123.12', {'to': 'decimal'}).unwrap() Decimal('123.12') """ if value_to_cast is None: return Failure(ValueError('value_to_cast is empty')) if TO not in casting or casting[TO] is None: return Success(value_to_cast) return flow( casting[TO], get_casting_function, bind( # type: ignore lambda function: function( # type: ignore value_to_cast, casting.get(ORIGINAL_FORMAT), ), ), )
def test_nothing_to_failure(): """Ensure that `Nothing` is always converted to `Failure`.""" assert maybe_to_result(Nothing) == Failure(None)
def also_returns_container(self, arg: str) -> Result[str, ValueError]: if arg != "0": return Success(str(arg)) else: return Failure(ValueError('Wrong arg 2'))
def returns_container(self, test: float, arg: float) -> Result[str, ValueError]: if arg == test: return Success(str(arg)) else: return Failure(ValueError('Wrong arg'))
from returns.maybe import Nothing, Some from returns.result import Failure, Success @pytest.mark.parametrize( ('container', 'merged'), [ # Flattens: (IO(IO(1)), IO(1)), (Success(Success({})), Success({})), (IOSuccess(IOSuccess(1)), IOSuccess(1)), (Some(Some(None)), Nothing), (Some(Some([])), Some([])), # Nope: (Failure(Failure('a')), Failure(Failure('a'))), (IOFailure(IOFailure('a')), IOFailure(IOFailure('a'))), ]) def test_flatten(container, merged): """Ensures that `flatten` is always returning the correct type.""" assert flatten(container) == merged @pytest.mark.parametrize(('container', 'merged'), [ ( RequiresContextResult.from_success( RequiresContextResult.from_success(1), ), RequiresContextResult.from_success(1), ), ( RequiresContextIOResult.from_success(
def factory(inner_value: int) -> Failure[float]: return Failure(float(inner_value + 1))
def factory(inner_value: int) -> Failure[TypeError]: return Failure(TypeError())
def test_pipeline_failure(): """Ensures that pipeline works well for Failure.""" assert _example1(0) == Failure('E') assert _example1(0).failure() == 'E' assert _example2(0) == Failure(0) assert _example2(1).rescue(_transformation).unwrap() == -1