Python for the Energy Industry
Vessels endpoint documentation.
By now, you should be well used to the process of filtering Cargo Movements, and searching the relevant endpoints to get IDs of interest for filtering. This works in exactly the same way for filtering Cargo Movements that are being carried on a known Vessel:
# Some initial imports / settings
from datetime import datetime
from dateutil.relativedelta import relativedelta
import vortexasdk as v
now = datetime.utcnow()
one_month_ago = now - relativedelta(months=1)
required_columns = ["vessels.0.name","vessels.0.vessel_class","product.group.label","product.grade.label","quantity",
"status","events.cargo_port_load_event.0.location.port.label","events.cargo_port_load_event.0.end_timestamp",
"events.cargo_port_unload_event.0.location.port.label","events.cargo_port_unload_event.0.end_timestamp"]
new_labels = ["vessel_name","vessel_class","product_group","product_grade","quantity","status","loading_port","loading_finish","unloading_port","unloading_finish"]
relabel = dict(zip(required_columns,new_labels))
# get ID for all vessels with 'CRIMSON' in the name
crimson_id = [ves['id'] for ves in v.Vessels().search(term='CRIMSON')]
# filter for cargo movements on CRIMSON
crimson_cm = v.CargoMovements().search(
filter_activity="loading_state",
filter_time_min=one_month_ago,
filter_time_max=now,
filter_vessels=crimson_id)
crimson_cm.to_df(columns=required_columns).rename(relabel,axis=1)
vessel_name | vessel_class | product_group | product_grade | quantity | status | loading_port | loading_finish | unloading_port | unloading_finish | |
---|---|---|---|---|---|---|---|---|---|---|
0 | CRIMSON PEARL | handymax | Clean Petroleum Products | NaN | 292375 | unloaded_state | Brofjorden [SE] | 2021-01-12 01:33:36+00:00 | Amsterdam [NL] | 2021-01-16 05:50:14+00:00 |
1 | OCEANIC CRIMSON | general_purpose | Clean Petroleum Products | NaN | 57142 | unloaded_state | Hamburg [DE] | 2021-01-10 18:03:14+00:00 | Bejaia [DZ] | 2021-01-23 15:22:33+00:00 |
2 | CRIMSON RAY | general_purpose | Clean Petroleum Products | NaN | 17730 | unloaded_state | Aqaba [JO] | 2021-01-23 19:17:56+00:00 | Barcelona [ES] | 2021-02-03 08:30:38+00:00 |
3 | CRIMSON PEARL | handymax | Clean Petroleum Products | Motor Spirit | 181794 | transiting_state | Antwerp [BE] | 2021-01-22 23:40:00+00:00 | Conakry [GN] | NaT |
4 | LADY ROISE | sgc | Clean Petroleum Products | NaN | 13284 | unloaded_state | Daesan [KR] | 2021-01-30 10:56:38+00:00 | Kaohsiung [TW] | 2021-02-03 10:05:07+00:00 |
5 | SAEHAN SELINA | sgc | Clean Petroleum Products | NaN | 18982 | unloaded_state | Daesan [KR] | 2021-01-24 21:08:52+00:00 | Dongying [CN] | 2021-02-03 05:35:44+00:00 |
6 | SAEHAN VIRTUS | sgc | Clean Petroleum Products | NaN | 20580 | unloaded_state | Daesan [KR] | 2021-01-23 21:01:02+00:00 | Mizushima [JP] | 2021-02-04 08:39:12+00:00 |
7 | SAEHAN SELINA | sgc | Clean Petroleum Products | NaN | 20580 | loading_state | Daesan [KR] | 2021-02-09 08:04:59+00:00 | Cao Jing [CN] | NaT |
8 | SAEHAN VIRTUS | sgc | Clean Petroleum Products | NaN | 20240 | unloaded_state | Jiangyin [CN] | 2021-01-17 23:15:33+00:00 | Ulsan, Onsan [KR] | 2021-01-20 14:47:25+00:00 |
9 | SAEHAN VIRTUS | sgc | Clean Petroleum Products | NaN | 20240 | transiting_state | Daesan [KR] | 2021-02-07 15:31:59+00:00 | NaN | NaT |
10 | SAEHAN SELINA | sgc | Clean Petroleum Products | NaN | 20580 | unloaded_state | Daesan [KR] | 2021-01-17 23:49:51+00:00 | Lianyungang [CN] | 2021-01-20 04:36:55+00:00 |
11 | CRIMSON PEARL | handymax | Clean Petroleum Products | Motor Spirit | 123940 | unloaded_state | Antwerp [BE] | 2021-01-22 23:40:00+00:00 | Freetown [SL] | 2021-02-06 11:26:30+00:00 |
12 | LADY ROISE | sgc | Clean Petroleum Products | NaN | 14768 | unloaded_state | Ulsan, Onsan [KR] | 2021-01-19 18:24:41+00:00 | Kaohsiung [TW] | 2021-01-24 03:45:55+00:00 |
13 | LADY ROISE | sgc | Clean Petroleum Products | NaN | 14768 | unloaded_state | Daesan [KR] | 2021-01-11 21:58:38+00:00 | Taixing [CN] | 2021-01-17 02:52:13+00:00 |
14 | OCEANIC CRIMSON | general_purpose | Clean Petroleum Products | NaN | 90673 | transiting_state | Nikolayev (Mykolaiv) [UA] | 2021-02-07 22:22:30+00:00 | Cartagena [ES] | NaT |
Another way of using the Vessels endpoint is to limit searches based on vessel class. Say we are interested only in VLCC movements from Saudi Arabia:
# get all vessels of vlcc class
vlcc = v.Vessels().search(vessel_classes='vlcc')
# get the ids of these vessels
vlcc_ids = [ves['id'] for ves in vlcc]
# saudi arabia id
sa_search = v.Geographies().search("Saudi Arabia",exact_term_match=True)
assert len(sa_search) == 1
sa_ID = sa_search[0]['id']
# filter for vlcc movements out of saudi arabia
vlcc_query = v.CargoMovements().search(
filter_activity="loading_state",
filter_time_min=one_month_ago,
filter_time_max=now,
filter_vessels=vlcc_ids,
filter_origins=sa_ID)
# convert to dataframe
vlcc_query.to_df(columns=required_columns).rename(relabel,axis=1)
vessel_name | vessel_class | product_group | product_grade | quantity | status | loading_port | loading_finish | unloading_port | unloading_finish | |
---|---|---|---|---|---|---|---|---|---|---|
0 | KASAGISAN | vlcc_plus | Crude/Condensates | Arab Medium | 2110718 | unloaded_state | Juaymah Terminal [SA] | 2020-11-14 07:16:42+00:00 | Quanzhou [CN] | 2020-12-07 08:53:54+00:00 |
1 | NEW PROSPECT | vlcc_plus | Crude/Condensates | Arab Light | 1969827 | transiting_state | Juaymah Terminal [SA] | 2020-11-26 23:17:14+00:00 | Kaohsiung [TW] | NaT |
2 | C.MIGHTY | vlcc_plus | Crude/Condensates | Arab Medium | 2035637 | transiting_state | Juaymah Terminal [SA] | 2020-11-21 08:56:21+00:00 | Zhoushan [CN] | NaT |
3 | GASSAN | vlcc_plus | Crude/Condensates | Arab Light | 301149 | transiting_state | Ras Tanura [SA] | 2020-11-12 05:32:48+00:00 | Sendai, Miyagi [JP] | NaT |
4 | TENRYU | vlcc_plus | Crude/Condensates | Arab Light | 565346 | transiting_state | Ras Tanura [SA] | 2020-11-17 16:49:22+00:00 | Singapore [SG] | NaT |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
102 | ABQAIQ | vlcc_plus | Crude/Condensates | Arab Light | 2102642 | transiting_state | Yanbu Industrial Port [SA] | 2020-12-10 00:34:23+00:00 | Ain Sukhna [EG] | NaT |
103 | M.T. TENJUN | vlcc_plus | Crude/Condensates | Arab Heavy | 591455 | loading_state | Ras Tanura [SA] | 2020-12-11 10:32:47+00:00 | NaN | NaT |
104 | ATHINA II | vlcc_plus | Crude/Condensates | Arab Heavy | 1383057 | transiting_state | Juaymah Terminal [SA] | 2020-12-04 02:22:16+00:00 | New Mangalore [IN] | NaT |
105 | ABQAIQ | vlcc_plus | Crude/Condensates | Arab Light | 2102705 | unloaded_state | Yanbu Industrial Port [SA] | 2020-11-27 23:27:01+00:00 | Ain Sukhna [EG] | 2020-12-04 20:17:20+00:00 |
106 | ENEOS TOKYO | vlcc_plus | Crude/Condensates | Arab Light | 760348 | transiting_state | Ras Tanura [SA] | 2020-12-09 01:49:46+00:00 | Fujairah [AE] | NaT |
107 rows × 10 columns
If there is a group of vessels of interest, it may be useful to store their IDs in a dictionary for easy access (of course, this applies to IDs for all other types of filter, as well).
# search for all vlcc vessels with the term 'glory'
vlcc_glory = v.Vessels().search(vessel_classes='vlcc',term='glory')
vlcc_glory_df = vlcc_glory.to_df()
# limit to those with 'glory' in the name
vlcc_glory_df = vlcc_glory_df[vlcc_glory_df['name'].str.contains('GLORY')]
vlcc_glory_df
id | name | imo | vessel_class | |
---|---|---|---|---|
0 | a8daaa7b46f01a01b0b003f51116882c6df4b18210c2b8... | DELTA GLORY | 9602617 | vlcc_plus |
1 | 51d8eeb4fbb6691756594f6143e1b3ce8b74437f50c800... | ENEOS GLORY | 9851608 | vlcc_plus |
2 | 05263ff056489d1cf2c264e708e6e8bb1da502a216ece6... | V. GLORY | 9849851 | vlcc_plus |
3 | 6a9b0048c3356d9975bef63da82e3a1ec04c9668066353... | ATHENIAN GLORY | 9429302 | vlcc_plus |
4 | 5f9d7b1329f44ef585bfa506d1d0c52a16eb3d5ef01c1b... | CARIBBEAN GLORY | 9788875 | vlcc_plus |
7 | c7cd0caacfc8d5b1ffafe6a623cd0c437843fb76100a58... | BALTIC GLORY | 9307645 | vlcc_plus |
9 | e6ff63f16630fdb1e82d856f3e3c2466ed8359d41a43d7... | LANDBRIDGE GLORY | 9828778 | vlcc_plus |
14 | 8faaab9fad4706d8bd19d908d55ab4368fa28ef422893e... | PLATA GLORY | 9172674 | vlcc_plus |
vlcc_glory_dict = dict(zip(vlcc_glory_df['name'],vlcc_glory_df['id']))
vlcc_glory_dict
{'DELTA GLORY': 'a8daaa7b46f01a01b0b003f51116882c6df4b18210c2b8c26e96dccac3eba696', 'ENEOS GLORY': '51d8eeb4fbb6691756594f6143e1b3ce8b74437f50c80062785c1101f46aa652', 'V. GLORY': '05263ff056489d1cf2c264e708e6e8bb1da502a216ece68cfeee1105307dbd0a', 'ATHENIAN GLORY': '6a9b0048c3356d9975bef63da82e3a1ec04c966806635377ae6aa9b42d97c66e', 'CARIBBEAN GLORY': '5f9d7b1329f44ef585bfa506d1d0c52a16eb3d5ef01c1bf031da37849c3bfdf0', 'BALTIC GLORY': 'c7cd0caacfc8d5b1ffafe6a623cd0c437843fb76100a5828793d38cf92da6344', 'LANDBRIDGE GLORY': 'e6ff63f16630fdb1e82d856f3e3c2466ed8359d41a43d74d220e8e770769b240', 'PLATA GLORY': '8faaab9fad4706d8bd19d908d55ab4368fa28ef422893e25745216558088366c'}
vlcc_EG_query = v.CargoMovements().search(
filter_activity="loading_state",
filter_time_min=one_month_ago,
filter_time_max=now,
filter_vessels=vlcc_glory_dict['DELTA GLORY'])
Loading from API: 0it [00:00, ?it/s]
vlcc_EG_query.to_df(columns=required_columns).rename(relabel,axis=1)
vessel_name | vessel_class | product_group | product_grade | quantity | status | loading_port | loading_finish | unloading_port | unloading_finish |
---|
Make a DataFrame with all vessels. Aggregate this by vessel class, and plot a pie chart of the number of vessels in each class.