Skip to content

Commit

Permalink
Merge pull request #55 from V0RT3X4/clearer-docs
Browse files Browse the repository at this point in the history
docs: Add about-endpoints explanation
  • Loading branch information
KitBurgess committed Nov 20, 2019
2 parents faf2495 + 8a7a8cd commit 2d0aaeb
Show file tree
Hide file tree
Showing 9 changed files with 634 additions and 78 deletions.
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,16 @@ Set your `VORTEXA_API_KEY` environment variable, that's all.

```python
>>> from vortexasdk import CargoMovements
>>> df = CargoMovements() \
.search(filter_time_min="2019-08-01T00:00:00.000Z", filter_time_max="2019-08-01T00:15:00.000Z")\
>>> df = CargoMovements()\
.search(filter_activity='loading_state',
filter_time_min='2019-08-01T00:00:00.000Z',
filter_time_max='2019-08-01T00:15:00.000Z')\
.to_df()
```

## Next Steps

Learn how to call [Endpoints](https://v0rt3x4.github.io/python-sdk/endpoints/about-endpoints/)

## Documentation

Expand Down
32 changes: 32 additions & 0 deletions docs/endpoints/about-endpoints.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# About VortexaSDK Endpoints

The endpoints module allows you to query Vortexa's data.

The VortexaSDK currently contains 4 different endpoints:

1. Cargo Movements
2. Charterers
3. Geographies
4. Products
5. Vessels


Each endpoint offers either one, or both, of two different functionalities:


1. **Lookup by ID**. Retreive an object matching a certain id. In sql speak this is the equivalent of `SELECT * FROM vessels WHERE id = 12345;`
2. **Search**. Retrieve a number of objects matching given search parameters. In sql speak this is the equivalent of `SELECT * FROM vessels WHERE name ~* 'ocean' AND vessel_class = 'vlcc';`


Let's explain with some examples:

Find all aframax vessels
```python
from vortexasdk import Vessels
df = Vessels().search(vessel_classes='aframax').to_df()
```

Find the vessel that has with id 1245
```python
vessel = Vessels().reference(id='12345')
```
1 change: 1 addition & 0 deletions docs/entities/about-entities.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
## Vortexa SDK Entities
23 changes: 13 additions & 10 deletions pydocmd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ generate:

- endpoints/cargo_movements.md:
- vortexasdk.endpoints.cargo_movements++
- vortexasdk.endpoints.cargo_movements_result++
- endpoints/charterers.md:
- vortexasdk.endpoints.charterers++
- endpoints/vessels.md:
Expand All @@ -28,19 +29,21 @@ generate:
- vortexasdk.api.cargo_movement++
pages:
- Home: index.md << README.md
- Entities:
Vessel: entities/vessel.md
Product: entities/product.md
Geography: entities/geography.md
Corporation: entities/corporation.md
Cargo Movement: entities/cargo_movement.md
- Operations: operations.md
- Endpoints:
Vessels: endpoints/vessels.md
Products: endpoints/products.md
Geographies: endpoints/geographies.md
About Endpoints: endpoints/about-endpoints.md << docs/endpoints/about-endpoints.md
Cargo Movements: endpoints/cargo_movements.md
Charterers: endpoints/charterers.md
Geographies: endpoints/geographies.md
Products: endpoints/products.md
Vessels: endpoints/vessels.md
- Entities:
About Entities: entities/about-entities.md << docs/entities/about-entities.md
Cargo Movement: entities/cargo_movement.md
Corporation: entities/corporation.md
Geography: entities/geography.md
Product: entities/product.md
Vessel: entities/vessel.md
- Operations: operations.md
- Examples:
1 China VLCC Discharges: examples/1_china.md

Expand Down
8 changes: 7 additions & 1 deletion tests/endpoints/test_cargo_movements_real.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@ def setUp(self) -> None:
set_client(create_client())

def test_default_search(self):
results = CargoMovements().search()
results = CargoMovements().search(filter_activity='loading_state')
print(len(results))

def test_search_returns_unique_results(self):
result = CargoMovements().search(
filter_activity='loading_state',
filter_origins=['68faf65af1345067f11dc6723b8da32f00e304a6f33c000118fccd81947deb4e'],
filter_time_min="2019-08-29T00:00:00.000Z",
filter_time_max="2019-10-30T00:00:00.000Z",
Expand All @@ -37,6 +38,7 @@ def test_search_returns_unique_results(self):

def test_search_single_filter_id(self):
df = CargoMovements().search(
filter_activity='loading_state',
filter_products='6f11b0724c9a4e85ffa7f1445bc768f054af755a090118dcf99f14745c261653',
filter_time_min="2019-08-29T00:00:00.000Z",
filter_time_max="2019-08-29T00:10:00.000Z",
Expand All @@ -46,6 +48,7 @@ def test_search_single_filter_id(self):

def test_search_single_filter_origin_name(self):
df = CargoMovements().search(
filter_activity='loading_state',
filter_origins='Rotterdam',
filter_time_min="2019-08-29T00:00:00.000Z",
filter_time_max="2019-08-29T00:10:00.000Z",
Expand All @@ -55,6 +58,7 @@ def test_search_single_filter_origin_name(self):

def test_search_single_filter_charterer_name(self):
df = CargoMovements().search(
filter_activity='loading_state',
filter_owners="DHT"
).to_df().head(2)

Expand All @@ -75,6 +79,7 @@ def test_search_list_filter_id(self):
filter_products=['6f11b0724c9a4e85ffa7f1445bc768f054af755a090118dcf99f14745c261653'],
filter_time_min="2019-08-29T00:00:00.000Z",
filter_time_max="2019-08-29T00:10:00.000Z",
filter_activity='loading_state'
).to_df().head(2)

assert len(df) == 2
Expand All @@ -83,6 +88,7 @@ def test_search_list_filter_id(self):
def test_speed(self):
with Timer("Search") as t_search:
cms = CargoMovements().search(
filter_activity='loading_state',
filter_time_min="2019-08-29T00:00:00.000Z",
filter_time_max="2019-08-30T00:00:00.000Z",
)
Expand Down
6 changes: 6 additions & 0 deletions tests/endpoints/test_vessels_real.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ def test_search_filters_vessel_class(self):

assert actual == set(vessel_classes)

def test_search_terms_are_combined_with_AND(self):
aframax = set(v.id for v in Vessels().search(vessel_classes='aframax').to_list())
aframax_called_zhen = set(v.id for v in Vessels().search(vessel_classes='aframax', term='zhen').to_list())

assert aframax_called_zhen.issubset(aframax)

def test_search_ids_dataframe(self):
ids = [
"6d8a8f0863ca087204dd68e5fc3b6469a879829e6262856e34856aea3ca20509",
Expand Down
74 changes: 10 additions & 64 deletions vortexasdk/endpoints/cargo_movements.py
Original file line number Diff line number Diff line change
@@ -1,80 +1,24 @@
"""Cargo Movements Endpoint."""
import functools
import os
from multiprocessing.pool import Pool
from typing import Dict, List, Union
from typing import List, Union

import jsons
import pandas as pd

from vortexasdk.api.cargo_movement import CargoMovement
from vortexasdk.api.entity_serializing import convert_cme_to_flat_dict
from vortexasdk.api.search_result import Result
from vortexasdk.conversions import convert_to_charterer_ids, convert_to_geography_ids, convert_to_product_ids
from vortexasdk.conversions.vessels import convert_to_vessel_ids
from vortexasdk.endpoints.cargo_movements_result import CargoMovementsResult
from vortexasdk.endpoints.endpoints import CARGO_MOVEMENTS_RESOURCE
from vortexasdk.operations import Search
from vortexasdk.utils import to_list

DEFAULT_COLUMNS = [
'events.cargo_port_load_event.0.label',
'events.cargo_port_unload_event.0.label',
'product.group.label',
'product.grade.label',
'quantity',
'vessels.0.name',
'events.cargo_port_load_event.0.start_timestamp',
'events.cargo_port_unload_event.0.start_timestamp',
]


def _serialize_cm(dictionary: Dict) -> CargoMovement:
return jsons.loads(jsons.dumps(dictionary), CargoMovement)


class CargoMovementsResult(Result):
"""Container class holdings search results returns from the cargo movements endpoint."""

def to_list(self) -> List[CargoMovement]:
"""Represent cargo movements as a list of `CargoMovementEntity`s."""
list_of_dicts = super().to_list()

with Pool(os.cpu_count()) as pool:
return list(pool.map(_serialize_cm, list_of_dicts))

def to_df(self, columns=None) -> pd.DataFrame:
"""
Represent cargo movements as a `pd.DataFrame`.
# Arguments
columns: Output columns present in the `pd.DataFrame`.
Enter `columns='all'` to return all available columns.
Enter `columns=None` to use `cargo_movements.DEFAULT_COLUMNS`.
# Returns
`pd.DataFrame`, one row per cargo movement.
"""
if columns is None:
columns = DEFAULT_COLUMNS

with Pool(os.cpu_count()) as pool:
records = pool.map(functools.partial(convert_cme_to_flat_dict, cols=columns), super().to_list())

return pd.DataFrame(records)


class CargoMovements(Search):
"""Cargo Movements Endpoint."""
"""Cargo Movements Endpoint, use this to search through Vortexa's cargo movements."""

_MAX_PAGE_RESULT_SIZE = 500

def __init__(self):
Search.__init__(self, CARGO_MOVEMENTS_RESOURCE)

def search(self,
filter_activity: str = "loading_state",
filter_activity: str,
filter_time_min: str = "2019-10-01T00:00:00.000Z",
filter_time_max: str = "2019-10-01T01:00:00.000Z",
cm_unit: str = 'b',
Expand All @@ -95,8 +39,10 @@ def search(self,
Find CargoMovements matching the given search parameters.
# Arguments
filter_activity: Movement activity on which to base the time filter. It can be a filter for a
specific timestamp, which looks for it within the specified time-frame.
filter_activity: Movement activity on which to base the time filter. Must be one of ['loading_state',
'loading_start', 'loading_end', 'identified_for_loading_state', 'unloading_state', 'unloading_start',
'unloading_end', 'unloaded_state', 'storing_state', 'storing_start', 'storing_end', 'transiting_state',
'any_state'].
filter_time_min: The start date of the time filter.
Expand Down Expand Up @@ -126,14 +72,14 @@ def search(self,
the filter behaviour for cargo leaving then entering the same geographic area.
# Returns
List of cargo movements matching all the search parameters.
`CargoMovementsResult`, containing all the cargo movements matching the given search terms.
# Example
Let's search for all vessels that loaded from `Rotterdam [NL]` on the morning of 1st December 2018.
```python
>>> from vortexasdk import CargoMovements
>>> df = CargoMovements().search(
filter_origins="Rotterdam",
filter_activity='loading_state',
Expand Down
Loading

0 comments on commit 2d0aaeb

Please sign in to comment.