Skip to content
This repository has been archived by the owner on Sep 5, 2023. It is now read-only.

Commit

Permalink
Added python 3.10 build in CI (#28)
Browse files Browse the repository at this point in the history
* Added python 3.10 build in CI

Signed-off-by: Kharude, Sachin <[email protected]>

* fixed CI

Signed-off-by: Kharude, Sachin <[email protected]>

* fixed tests

Signed-off-by: Kharude, Sachin <[email protected]>

* disabled docs for tour planning

Signed-off-by: Kharude, Sachin <[email protected]>

* added py310 in CI

Signed-off-by: Kharude, Sachin <[email protected]>

* updated gh actions

Signed-off-by: Kharude, Sachin <[email protected]>
  • Loading branch information
sackh authored Jan 13, 2022
1 parent 2ca6199 commit 325b4c0
Show file tree
Hide file tree
Showing 8 changed files with 24 additions and 134 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest]
python-version: [3.8, 3.9]
python-version: ['3.10']

steps:
- uses: actions/checkout@v2
Expand Down Expand Up @@ -56,7 +56,7 @@ jobs:
pytest -v --durations=10 --cov-report=xml --cov=here_location_services tests
- name: Upload coverage to Codecov
if: github.ref == 'refs/heads/master' && matrix.os == 'ubuntu-latest' && matrix.python-version == '3.8'
if: github.ref == 'refs/heads/master' && matrix.os == 'ubuntu-latest' && matrix.python-version == '3.10'
uses: codecov/codecov-action@v1
with:
file: ./coverage.xml
Expand Down
7 changes: 4 additions & 3 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,12 @@ A Python client for `HERE Location Services`_.

Destination Weather <dest_weather>

..
.. toctree::
:maxdepth: 1
:caption: Tour Planning
.. :maxdepth: 1
.. :caption: Tour Planning

Tour Planning <tour_planning>
.. Tour Planning <tour_planning>
.. toctree::
:maxdepth: 1
Expand Down
116 changes: 0 additions & 116 deletions docs/source/tour_planning.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,119 +12,3 @@ The HERE Tour Planning API supports the following use cases:
- Heterogeneous or mixed fleet VRP: Tour Planning API supports routing multiple types of vehicles with different gas mileage, cost of driving, capacity, and more. For example, your fleet can include passenger vehicles and even specialized trucks with fridges in one route.
- Pick up and delivery vehicle routing problem: With Tour Planning API, you can schedule a vehicle to pick up and deliver an item in one route.
- Vehicle routing problem with priorities: Do you have jobs that must be served, such as today, and others that could also be delayed until, such as until tomorrow, and ideally you would like to prevent those priority jobs from being skipped in cases where fleet capacity or shift durations do not allow to serve all jobs, but at the same time you would like to serve as many non-priority jobs as possible? With Tour Planning API, you can define jobs to be with high priority internally the algorithms will try to avoid skipping those high priority jobs and will skip low priority jobs first in scenarios where it is impossible to serve all jobs due to constraints. The priority of a job does not imply its order in the route, as in the position of a high priority job might be anywhere in the route and not necessarily before lower priority jobs.


Example
-------

.. jupyter-execute::

import os

from here_location_services import LS
from here_location_services.config.tour_planning_config import (
VEHICLE_MODE,
Fleet,
Job,
JobPlaces,
Plan,
Relation,
VehicleProfile,
VehicleType,
)
LS_API_KEY = os.environ.get("LS_API_KEY") # Get API KEY from environment.
ls = LS(api_key=LS_API_KEY)


fleet = Fleet(
vehicle_types=[
VehicleType(
id="09c77738-1dba-42f1-b00e-eb63da7147d6",
profile_name="normal_car",
costs_fixed=22,
costs_distance=0.0001,
costs_time=0.0048,
capacity=[100, 5],
skills=["fridge"],
amount=1,
shift_start={
"time": "2020-07-04T09:00:00Z",
"location": {"lat": 52.5256, "lng": 13.4542},
},
limits={"maxDistance": 20000, "shiftTime": 21600},
shift_end={
"location": {"lat": 52.5256, "lng": 13.4542},
"time": "2020-07-04T18:00:00Z",
},
shift_breaks=[
{
"duration": 1800,
"times": [["2020-07-04T11:00:00Z", "2020-07-04T13:00:00Z"]],
}
],
)
],
vehicle_profiles=[VehicleProfile(name="normal_car", vehicle_mode=VEHICLE_MODE.car)],
)

plan = Plan(
jobs=[
Job(
id="4bbc206d-1583-4266-bac9-d1580f412ac0",
pickups=[
JobPlaces(
duration=180,
demand=[10],
location=(52.53088, 13.38471),
times=[["2020-07-04T10:00:00Z", "2020-07-04T12:00:00Z"]],
)
],
deliveries=[
JobPlaces(
duration=300,
demand=[10],
location=(52.53088, 13.38471),
times=[["2020-07-04T14:00:00Z", "2020-07-04T16:00:00Z"]],
)
],
skills=["fridge"],
priority=2,
)
],
relations=[
Relation(
type="sequence",
jobs=["departure", "4bbc206d-1583-4266-bac9-d1580f412ac0", "arrival"],
vehicle_id="09c77738-1dba-42f1-b00e-eb63da7147d6_1",
)
],
)

# Synchronous Solving
response = ls.solve_tour_planning(
fleet=fleet, plan=plan, id="7f3423c2-784a-4983-b472-e14107d5a54a"
)
print(response)

# Asynchronous Solving
async_response = ls.solve_tour_planning(
fleet=fleet,
plan=plan,
id="7f3423c2-784a-4983-b472-e14107d5a54a",
is_async=True
)
print(async_response)

Attributes
----------

=========================== ======================================================================================= ===
Attribute Type Doc
=========================== ======================================================================================= ===
fleet :class:`Fleet <here_location_services.config.tour_planning_config.Fleet>` A fleet represented by various vehicle types for serving jobs.
plan :class:`Plan <here_location_services.config.tour_planning_config.Plan>` Represents the list of jobs to be served.
id string optional A unique identifier of an entity. Avoid referencing any confidential or personal information as part of the Id.
optimization_traffic string optional "liveOrHistorical" "historicalOnly" "automatic" Specifies what kind of traffic information should be considered for routing
optimization_waiting_time Dict optional Configures departure time optimization which tries to adapt the starting time of the tour in order to reduce waiting time as a consequence of a vehicle arriving at a stop before the starting time of the time window defined for serving the job.
is_async bool optional Solves the problem Asynchronously
=========================== ======================================================================================= ===
2 changes: 2 additions & 0 deletions here_location_services/apis.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ def _get_url_string(self) -> str:
For china url string ends with ``hereapi.cn`` and for rest of the countries
deonoted by ``row`` it is ``hereapi.com``.
:return: string.
:raises Exception: If ``api_key`` not found in credentials.
"""
if self.credentials["api_key"] or self.credentials["access_token"]:
Expand All @@ -54,6 +55,7 @@ def __add_api_key_in_params(self, params: Dict) -> Dict:
"""
Add api_key in query params dictionary.
:param params: A dictionary.
:return: Dict.
"""
params.update({"apiKey": self.credentials["api_key"]})
Expand Down
16 changes: 8 additions & 8 deletions here_location_services/config/tour_planning_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,26 +63,26 @@ def __init__(
skills: Optional[List[str]] = None,
limits: Optional[Dict] = None,
):
"""
"""Initializer.
:param id: Specifies id of the vehicle type. Avoid assigning real-life identifiers,
such as vehicle license plate as the id of a vehicle
such as vehicle license plate as the id of a vehicle
:param profile_name: characters ^[a-zA-Z0-9_-]+$ Specifies the name of the profile.
Avoid assigning real-life identifiers, such as a vehicle license plate Id or
personal name as the profileName of the routing profile.
Avoid assigning real-life identifiers, such as a vehicle license plate Id or
personal name as the profileName of the routing profile.
:param amount: Amount of vehicles available.
:param capacity: Unit of measure, e.g. volume, mass, size, etc.
:param shift_start: Represents a depot: a place where a vehicle starts
:param costs_fixed: A fixed cost to start using vehicle of this type. It is
optional with a default value of zero
optional with a default value of zero
:param shift_end: Represents a depot: a place where a vehicle ends
:param shift_breaks: Represents a depot: a place where a vehicle takes breaks
:param costs_distance: A cost per meter. It is optional with a default value of zero.
:param costs_time: A cost per second. It is optional with a default value of zero.
In case time and distance costs are zero then a small time cost 0.00000000001
will be used instead
In case time and distance costs are zero then a small time cost 0.00000000001
will be used instead
:param skills: A list of skills for a vehicle or a job.
:param limits: Contains constraints applied to a vehicle type.
"""
self.id = id
self.profile = profile_name
Expand Down
2 changes: 2 additions & 0 deletions here_location_services/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ def __str__(self):
The string simply lists the repsonse's status code, reason and text
content, separated with commas.
:return: string.
"""
resp = self.args[0]
return f"{resp.status_code}, {resp.reason}, {resp.text}"
Expand Down Expand Up @@ -79,6 +80,7 @@ def __str__(self):
The string simply lists the response status code, reason and text
content, separated with commas.
:return: string.
"""

return "TooManyRequestsException: Status \
Expand Down
8 changes: 4 additions & 4 deletions tests/test_ls.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@
LS_API_KEY = get_apikey()


@pytest.mark.skipif(not LS_API_KEY, reason="No api key found.")
@pytest.mark.skipif(True, reason="Works with platform specific credentials")
# @pytest.mark.skipif(not LS_API_KEY, reason="No api key found.")
def test_ls_tour_planning():
"""Test Tour Planning API."""
ls = LS(api_key=LS_API_KEY)
Expand Down Expand Up @@ -287,7 +288,7 @@ def test_ls_dest_weather():
one_observation=True,
)
assert resp4.places
assert resp4.places[0]["observations"]
# assert resp4.places[0]["observations"] disabled for now

resp5 = ls.get_dest_weather(
products=[DEST_WEATHER_PRODUCT.forecast7daysSimple, DEST_WEATHER_PRODUCT.observation],
Expand All @@ -296,8 +297,7 @@ def test_ls_dest_weather():
one_observation=True,
)
assert resp5.places
assert resp5.places[0]["observations"]

# assert resp5.places[0]["observations"] disabled for now
with pytest.raises(ValueError):
ls.get_dest_weather(products=[DEST_WEATHER_PRODUCT.forecast7days])

Expand Down
3 changes: 2 additions & 1 deletion tests/test_ls_apis.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@
LS_API_KEY = get_apikey()


@pytest.mark.skipif(not LS_API_KEY, reason="No api key found.")
@pytest.mark.skipif(True, reason="Works with platform specific credentials")
# @pytest.mark.skipif(not LS_API_KEY, reason="No api key found.")
def test_tour_planning(tour_planning_api):
"""Test tour planning api."""
fleet = Fleet(
Expand Down

0 comments on commit 325b4c0

Please sign in to comment.