Skip to content

Freight Rates

Freight Rates API Package.

Classes:

Name Description
FreightRatesAPI

Represents Signal's Freight Rates API.

FreightPricing

The freight pricing given a load and discharge port.

VesselClass

A vessel class.

Port

A maritime facility where vessels can dock.

PortFilter

A filter used to find specific ports.

Cost dataclass

The freight costs breakdown.

Attributes:

Name Type Description
canal float

Canal costs.

freight_cost float

Freight cost.

other_port_expenses float

Other port expenses.

Source code in signal_ocean/freight_rates/models.py
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
@dataclass(frozen=True)
class Cost:
    """The freight costs breakdown.

    Attributes:
        canal: Canal costs.
        freight_cost: Freight cost.
        other_port_expenses: Other port expenses.
    """

    canal: float
    freight_cost: float
    other_port_expenses: float

FreightPricing dataclass

The freight pricing given a load and discharge port.

Attributes:

Name Type Description
vessel_class str

The vessel class.

rate float

Value of the rate.

rate_type str

Type of the rate.

estimated_flat_rate float

Estimated flat rate.

costs Cost

Costs breakdown.

total_freight_cost float

Total freight cost.

total_freight_rate float

Total freight rate.

route_type str

Route type.

load_ports List[Port]

Load ports.

discharge_ports List[Port]

Discharge ports.

quantity float

Quantity.

min_flat_augusta_used bool

True if minimum flat Augusta was used.

routing_choices Optional[List[str]]

Routing choices (e.g. Suez, Panama etc).

Source code in signal_ocean/freight_rates/models.py
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
@dataclass(frozen=True)
class FreightPricing:
    """The freight pricing given a load and discharge port.

    Attributes:
        vessel_class: The vessel class.
        rate: Value of the rate.
        rate_type: Type of the rate.
        estimated_flat_rate: Estimated flat rate.
        costs: Costs breakdown.
        total_freight_cost: Total freight cost.
        total_freight_rate: Total freight rate.
        route_type: Route type.
        load_ports: Load ports.
        discharge_ports: Discharge ports.
        quantity: Quantity.
        min_flat_augusta_used: True if minimum flat Augusta was used.
        routing_choices: Routing choices (e.g. Suez, Panama etc).
    """

    vessel_class: str
    rate: float
    rate_type: str
    estimated_flat_rate: float
    costs: Cost
    total_freight_cost: float
    total_freight_rate: float
    route_type: str
    load_ports: List[Port]
    discharge_ports: List[Port]
    quantity: float
    min_flat_augusta_used: bool
    routing_choices: Optional[List[str]]

FreightRatesAPI

Represents Signal's Freight Rates API.

Source code in signal_ocean/freight_rates/freight_rates_api.py
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
class FreightRatesAPI:
    """Represents Signal's Freight Rates API."""

    def __init__(self, connection: Optional[Connection] = None):
        """Initializes the Freight Rates API.

        Args:
            connection: API connection configuration. If not provided, the
                default connection method is used.
        """
        self.__connection = connection or Connection()

    def get_freight_pricing(
            self, load_ports: List[int], discharge_ports: List[int],
            vessel_classes: List[str], is_clean: bool,
            date: date = date.today()
    ) -> Tuple[FreightPricing, ...]:
        """Provides freight pricing for given load/discharge ports.

        Args:
            load_ports: Load ports.
            discharge_ports: Discharge ports.
            vessel_classes: Vessel classes for which to return the freight e.g.
            VLCC, Aframax etc.
            is_clean: True if it is clean cargo.
            date: Date of pricing.


        Returns:
            The freight pricing or None if there are is no freight matching the
            given criteria.
        """
        query_dict = {
            "LoadPorts": '&LoadPorts='.join([str(lp) for lp in load_ports]),
            "DischargePorts": '&DischargePorts='.join([str(dp) for dp in
                                                       discharge_ports]),
            "IsClean": '{}'.format(is_clean),
            "Date": date.isoformat()
        }

        vessel_classes_param = '&VesselClasses='.join(vessel_classes)
        query_dict['VesselClasses'] = vessel_classes_param

        query_string: QueryString = query_dict
        response = self.__connection._make_get_request(
            "freight/api/Freight/v3/pricing", query_string
        )
        response.raise_for_status()
        response_json = response.json()
        return_object = parse_freight_pricing(response_json)

        return return_object

    @staticmethod
    def get_vessel_classes() -> Tuple[str, ...]:
        """Retrieves all available vessel classes.

        Returns:
            A tuple of all available vessel classes.
        """
        vessel_classes = tuple(vessel_class.name
                               for vessel_class in VesselClass)
        return vessel_classes

    def get_ports(
        self, port_filter: Optional[PortFilter] = None
    ) -> Tuple[Port, ...]:
        """Retrieves available ports.

        Args:
            port_filter: A filter used to find specific ports. If not
                specified, returns all available ports.

        Returns:
            A tuple of available ports that match the filter.
        """
        query_dict = {
            "date": date.today().isoformat()
        }

        query_string: QueryString = query_dict

        available_ports: List[Port] = []
        for vessel_class in VesselClass:
            response = self.__connection._make_get_request(
                f"freight/api/Freight/v2/pricing/"
                f"availablePorts/{vessel_class.name}",
                query_string
            )
            response.raise_for_status()
            response_json = response.json()
            available_ports += parse_ports(response_json)

        port_filter = port_filter or PortFilter()

        return tuple(port_filter._apply(available_ports))

__init__(connection=None)

Initializes the Freight Rates API.

Parameters:

Name Type Description Default
connection Optional[Connection]

API connection configuration. If not provided, the default connection method is used.

None
Source code in signal_ocean/freight_rates/freight_rates_api.py
17
18
19
20
21
22
23
24
def __init__(self, connection: Optional[Connection] = None):
    """Initializes the Freight Rates API.

    Args:
        connection: API connection configuration. If not provided, the
            default connection method is used.
    """
    self.__connection = connection or Connection()

get_freight_pricing(load_ports, discharge_ports, vessel_classes, is_clean, date=date.today())

Provides freight pricing for given load/discharge ports.

Parameters:

Name Type Description Default
load_ports List[int]

Load ports.

required
discharge_ports List[int]

Discharge ports.

required
vessel_classes List[str]

Vessel classes for which to return the freight e.g.

required
is_clean bool

True if it is clean cargo.

required
date date

Date of pricing.

today()

Returns:

Type Description
FreightPricing

The freight pricing or None if there are is no freight matching the

...

given criteria.

Source code in signal_ocean/freight_rates/freight_rates_api.py
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
def get_freight_pricing(
        self, load_ports: List[int], discharge_ports: List[int],
        vessel_classes: List[str], is_clean: bool,
        date: date = date.today()
) -> Tuple[FreightPricing, ...]:
    """Provides freight pricing for given load/discharge ports.

    Args:
        load_ports: Load ports.
        discharge_ports: Discharge ports.
        vessel_classes: Vessel classes for which to return the freight e.g.
        VLCC, Aframax etc.
        is_clean: True if it is clean cargo.
        date: Date of pricing.


    Returns:
        The freight pricing or None if there are is no freight matching the
        given criteria.
    """
    query_dict = {
        "LoadPorts": '&LoadPorts='.join([str(lp) for lp in load_ports]),
        "DischargePorts": '&DischargePorts='.join([str(dp) for dp in
                                                   discharge_ports]),
        "IsClean": '{}'.format(is_clean),
        "Date": date.isoformat()
    }

    vessel_classes_param = '&VesselClasses='.join(vessel_classes)
    query_dict['VesselClasses'] = vessel_classes_param

    query_string: QueryString = query_dict
    response = self.__connection._make_get_request(
        "freight/api/Freight/v3/pricing", query_string
    )
    response.raise_for_status()
    response_json = response.json()
    return_object = parse_freight_pricing(response_json)

    return return_object

get_ports(port_filter=None)

Retrieves available ports.

Parameters:

Name Type Description Default
port_filter Optional[PortFilter]

A filter used to find specific ports. If not specified, returns all available ports.

None

Returns:

Type Description
Tuple[Port, ...]

A tuple of available ports that match the filter.

Source code in signal_ocean/freight_rates/freight_rates_api.py
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
def get_ports(
    self, port_filter: Optional[PortFilter] = None
) -> Tuple[Port, ...]:
    """Retrieves available ports.

    Args:
        port_filter: A filter used to find specific ports. If not
            specified, returns all available ports.

    Returns:
        A tuple of available ports that match the filter.
    """
    query_dict = {
        "date": date.today().isoformat()
    }

    query_string: QueryString = query_dict

    available_ports: List[Port] = []
    for vessel_class in VesselClass:
        response = self.__connection._make_get_request(
            f"freight/api/Freight/v2/pricing/"
            f"availablePorts/{vessel_class.name}",
            query_string
        )
        response.raise_for_status()
        response_json = response.json()
        available_ports += parse_ports(response_json)

    port_filter = port_filter or PortFilter()

    return tuple(port_filter._apply(available_ports))

get_vessel_classes() staticmethod

Retrieves all available vessel classes.

Returns:

Type Description
Tuple[str, ...]

A tuple of all available vessel classes.

Source code in signal_ocean/freight_rates/freight_rates_api.py
67
68
69
70
71
72
73
74
75
76
@staticmethod
def get_vessel_classes() -> Tuple[str, ...]:
    """Retrieves all available vessel classes.

    Returns:
        A tuple of all available vessel classes.
    """
    vessel_classes = tuple(vessel_class.name
                           for vessel_class in VesselClass)
    return vessel_classes

Port dataclass

A maritime facility where vessels can dock.

Attributes:

Name Type Description
id Optional[int]

ID of the port.

name str

Name of the port.

country Optional[str]

Country of the port.

area Optional[str]

Area of the port.

Source code in signal_ocean/freight_rates/models.py
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
@dataclass(frozen=True)
class Port:
    """A maritime facility where vessels can dock.

    Attributes:
        id: ID of the port.
        name: Name of the port.
        country: Country of the port.
        area: Area of the port.
    """

    name: str
    id: Optional[int] = None
    country: Optional[str] = None
    area: Optional[str] = None

PortFilter dataclass

A filter used to find specific ports.

Attributes:

Name Type Description
name_like Optional[str]

Used to find ports by name. When specified, ports whose names partially match (contain) the attribute's value will be returned. Matching is case-insensitive.

Source code in signal_ocean/freight_rates/port_filter.py
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
@dataclass(eq=False)
class PortFilter:
    """A filter used to find specific ports.

    Attributes:
        name_like: Used to find ports by name. When specified, ports whose
            names partially match (contain) the attribute's value will be
            returned. Matching is case-insensitive.
    """

    name_like: Optional[str] = None

    def _apply(self, ports: Iterable[Port]) -> \
            Iterable[Port]:
        return filter(self.__does_port_match, ports)

    def __does_port_match(self, port: Port) -> bool:
        return not self.name_like or contains_caseless(
            self.name_like, port.name
        )