def test_parse_model_missing_attribute_raises_type_error():
    @dataclass(frozen=True)
    class TestModel:
        model_id: int
        model_lists: Any

    data = {'ModelID': 1}

    with pytest.raises(TypeError):
        parsing_helpers.parse_model(data, TestModel)
def test_parse_model():
    @dataclass(frozen=True)
    class TestModel:
        model_id: int
        model_name: str
        model_score: float
        touched_by: str
        created_date: datetime
        version: int = None

    data = {
        'ModelID': 1,
        'ModelName': 'model1',
        'ModelScore': .97,
        'TouchedBy': 'signal',
        'CreatedDate': '2010-01-01T01:00:00'
    }

    parsed = parsing_helpers.parse_model(data, TestModel)
    assert isinstance(parsed, TestModel)
    assert parsed == TestModel(model_id=1,
                               model_name='model1',
                               model_score=.97,
                               touched_by='signal',
                               created_date=datetime(2010,
                                                     1,
                                                     1,
                                                     1,
                                                     0,
                                                     0,
                                                     tzinfo=timezone.utc))
Ejemplo n.º 3
0
def get_multiple(connection: Connection, relative_url: str, cls: Type[TModel],
                 query_string: Optional[QueryString] = None,
                 rename_keys: Optional[Dict[str, str]] = None) \
        -> Tuple[TModel, ...]:
    """Get a multiple objects from the API.

    Make a get request to the specified URL to retrieve a sequence of results
    and return a list of objects of the provided class instantiated with the
    retrieved data. If the API responds with an empty sequence an empty list
    is returned.

    Args:
        connection: The connection object to use to make the appropriate get
            request to the API.
        relative_url: The relative URL to make the request to.
        cls: The class to instantiate the object for the retrieved data.
        query_string: Query parameters for the request.
        rename_keys: Key names to rename to match model attribute names,
            used when an automated translation of the name from CapsWords
            to snake_case is to sufficient. Renaming must provide the name
            in CapsWords.
    """
    response = connection._make_get_request(relative_url,
                                            query_string=query_string)
    response.raise_for_status()
    data = response.json()
    return tuple(parse_model(d, cls, rename_keys=rename_keys) for d in data)
Ejemplo n.º 4
0
def get_single(connection: Connection, relative_url: str, cls: Type[TModel],
               query_string: Optional[QueryString] = None,
               rename_keys: Optional[Dict[str, str]] = None) \
        -> Optional[TModel]:
    """Get a single object from the API.

    Make a get request to the specified URL and return an object of the
    provided class instantiated with the retrieved data. If the API responds
    with a "Not Found" status code, return None.

    Args:
        connection: The connection object to use to make the appropriate get
            request to the API.
        relative_url: The relative URL to make the request to.
        cls: The class to instantiate the object for the retrieved data.
        query_string: Query parameters for the request.
        rename_keys: Key names to rename to match model attribute names,
            used when an automated translation of the name from CapsWords
            to snake_case is to sufficient. Renaming must provide the name
            in CapsWords.

    Returns:
        An object of the provided class instantiated with the data retrieved
        from the specified URL, or None if the API responds with a "Not Found"
        status code.
    """
    response = connection._make_get_request(relative_url,
                                            query_string=query_string)

    if response.status_code == requests.codes.not_found:
        return None

    response.raise_for_status()
    data = response.json()
    return parse_model(data, cls, rename_keys=rename_keys)
def test_parse_model_field(value: Union[str, int, float, bool, None],
                     field_type: Type,
                     expected: Union[str, int, float, bool, None, datetime,
                                     List[int], List[str], Tuple[int, ...],
                                     Tuple[str, ...]]) \
        -> None:
    transformed = parsing_helpers.parse_model(value, field_type)
    assert type(transformed) == type(expected)
    assert transformed == expected
def test_parse_model_rename_key_extra_attribute_ignored():
    @dataclass(frozen=True)
    class TestModel:
        model_id: int

    data = {'ModelID': 1}
    rename_keys = {'NAME': 'model_name'}
    parsed = parsing_helpers.parse_model(data, TestModel, rename_keys)
    assert isinstance(parsed, TestModel)
    assert parsed == TestModel(model_id=1)
def test_parse_model_default_factory():
    @dataclass(frozen=True)
    class TestModel:
        model_id: int
        model_lists: List = field(default_factory=list)

    data = {'ModelID': 1}

    parsed = parsing_helpers.parse_model(data, TestModel)
    assert isinstance(parsed, TestModel)
    assert parsed == TestModel(model_id=1, model_lists=[])
def test_parse_model_default():
    @dataclass(frozen=True)
    class TestModel:
        model_id: int
        model_name: str = 'a'

    data = {'ModelID': 1}

    parsed = parsing_helpers.parse_model(data, TestModel)
    assert isinstance(parsed, TestModel)
    assert parsed == TestModel(model_id=1, model_name='a')
def test_parse_model_rename_key():
    @dataclass(frozen=True)
    class TestModel:
        model_id: int
        model_name: str

    data = {'ModelID': 1, 'NAME': 'model1'}
    rename_keys = {'NAME': 'model_name'}
    parsed = parsing_helpers.parse_model(data, TestModel, rename_keys)
    assert isinstance(parsed, TestModel)
    assert parsed == TestModel(model_id=1, model_name='model1')
def test_parse_nested_model():
    @dataclass(frozen=True)
    class TestNestedModel:
        model_id: int

    @dataclass(frozen=True)
    class TestModel:
        model_id: int
        nested_model: TestNestedModel

    data = {'ModelID': 1, 'nested_model': {'ModelID': 3}}

    parsed = parsing_helpers.parse_model(data, TestModel)
    assert isinstance(parsed, TestModel)
    assert parsed == TestModel(model_id=1, nested_model=TestNestedModel(3))
def test_parse_model_extra_attributes_are_ignored():
    @dataclass(frozen=True)
    class TestModel:
        model_id: int
        model_name: str

    data = {
        'ModelID': 1,
        'ModelName': 'model1',
        'ModelScore': .97,
        'TouchedBy': 'signal',
        'CreatedDate': '2010-01-01'
    }

    parsed = parsing_helpers.parse_model(data, TestModel)
    assert isinstance(parsed, TestModel)
    assert parsed == TestModel(model_id=1, model_name='model1')
Ejemplo n.º 12
0
    def get_imos(
            self,
            vessel_filter: Optional[VesselFilter] = None
    ) -> Tuple[Vessel, ...]:
        """Retrieves available vessel types.

        Args:
            vessel_filter: A filter used to find specific vessel . If not
                specified, returns all available vessels .

        Returns:
            A tuple of available vessels that match the filter.
        """
        response = self.__connection._make_get_request(
            "voyages-api/v2/filters/availableVessels")
        response.raise_for_status()

        vessels = (parse_model(c, Vessel) for c in response.json())
        vessel_filter = vessel_filter or VesselFilter()

        return tuple(vessel_filter._apply(vessels))
Ejemplo n.º 13
0
    def get_vessel_classes(
        self,
        class_filter: Optional[VesselClassFilter] = None
    ) -> Tuple[VesselClass, ...]:
        """Retrieves available vessel classes.

        Args:
            class_filter: A filter used to find specific vessel classes. If not
                specified, returns all available vessel classes.

        Returns:
            A tuple of available vessel classes that match the filter.
        """
        response = self.__connection._make_get_request(
            "voyages-api/v2/filters/availableVesselClasses")
        response.raise_for_status()

        classes = (parse_model(c, VesselClass) for c in response.json())
        class_filter = class_filter or VesselClassFilter()

        return tuple(class_filter._apply(classes))
def test_parse_model_field_raises_error(
        value: Union[str, int, float, bool, None], field_type: Type,
        expected_error: Type[BaseException]) -> None:
    with pytest.raises(expected_error):
        parsing_helpers.parse_model(value, field_type)