Skip to content

Commit

Permalink
Merge pull request #104 from traveltime-dev/update-pydantic
Browse files Browse the repository at this point in the history
Bumped pydantic to V2
  • Loading branch information
arnasbr authored Nov 30, 2023
2 parents f5a42bd + 47d71fe commit 0f36477
Show file tree
Hide file tree
Showing 15 changed files with 46 additions and 91 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ jobs:
max-parallel: 1
matrix:
python-version:
- "3.7"
- "3.8"
- "3.9"
- "3.10"
- "3.11"
- "3.12"
steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Travel Time Python SDK

[![PyPI version](https://badge.fury.io/py/traveltimepy.svg)](https://badge.fury.io/py/traveltimepy) [![Unit Tests](https://github.com/traveltime-dev/traveltime-python-sdk/actions/workflows/ci.yml/badge.svg)](https://github.com/traveltime-dev/traveltime-python-sdk/actions/workflows/ci.yml) [![Python support](https://img.shields.io/badge/python-3.7+-blue.svg)](https://img.shields.io/badge/python-3.7+-blue)
[![PyPI version](https://badge.fury.io/py/traveltimepy.svg)](https://badge.fury.io/py/traveltimepy) [![Unit Tests](https://github.com/traveltime-dev/traveltime-python-sdk/actions/workflows/ci.yml/badge.svg)](https://github.com/traveltime-dev/traveltime-python-sdk/actions/workflows/ci.yml) [![Python support](https://img.shields.io/badge/python-3.8+-blue.svg)](https://img.shields.io/badge/python-3.8+-blue)

[Travel Time](https://docs.traveltime.com/api/overview/introduction) Python SDK helps users find locations by journey
time rather than using ‘as the crow flies’ distance.
Expand Down
4 changes: 2 additions & 2 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ include_package_data = True
python_requires = >=3.7
packages = find_namespace:
install_requires =
pydantic>=1.7.4,<2.0
pydantic
typing-extensions
geojson-pydantic
geojson-pydantic >= 1.0.1
shapely
dacite
certifi >= 2021.5.30
Expand Down
16 changes: 9 additions & 7 deletions traveltimepy/dto/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from enum import Enum
from typing import List, Union, Optional

from pydantic import validator
from pydantic import field_validator
from typing_extensions import Literal
from pydantic.main import BaseModel

Expand All @@ -11,13 +11,15 @@ class Coordinates(BaseModel):
lat: float
lng: float

@validator("lat")
@field_validator("lat")
@classmethod
def validate_latitude(cls, v):
if not -90 <= v <= 90:
raise ValueError("Latitude must be between -90 and 90.")
return v

@validator("lng")
@field_validator("lng")
@classmethod
def validate_longitude(cls, v):
if not -180 <= v <= 180:
raise ValueError("Longitude must be between -180 and 180.")
Expand Down Expand Up @@ -50,8 +52,8 @@ class RoadPart(BaseModel):
travel_time: int
coords: List[Coordinates]
type: Literal["road"]
road: Optional[str]
turn: Optional[str]
road: Optional[str] = None
turn: Optional[str] = None


class StartEndPart(BaseModel):
Expand Down Expand Up @@ -138,5 +140,5 @@ class Range(BaseModel):

class LevelOfDetail(BaseModel):
scale_type: Literal["simple", "simple_numeric", "coarse_grid"] = "simple"
level: Optional[Union[int, str]]
square_size: Optional[int]
level: Optional[Union[int, str]] = None
square_size: Optional[int] = None
61 changes: 6 additions & 55 deletions traveltimepy/dto/requests/time_map_geojson.py
Original file line number Diff line number Diff line change
@@ -1,64 +1,15 @@
import typing
from datetime import datetime

from typing import List, Optional
from typing import List

from geojson_pydantic import FeatureCollection
from pydantic.main import BaseModel

from traveltimepy import (
Coordinates,
Range,
PublicTransport,
Driving,
Ferry,
Walking,
Cycling,
DrivingTrain,
CyclingPublicTransport,
LevelOfDetail,
)
from traveltimepy.dto.requests.request import TravelTimeRequest
from traveltimepy.dto.requests.time_map import TimeMapRequest
from traveltimepy.dto.requests.time_map import (
TimeMapRequest,
DepartureSearch,
ArrivalSearch,
)
from traveltimepy.itertools import split, flatten


class DepartureSearch(BaseModel):
id: str
coords: Coordinates
departure_time: datetime
travel_time: int
transportation: typing.Union[
PublicTransport,
Driving,
Ferry,
Walking,
Cycling,
DrivingTrain,
CyclingPublicTransport,
]
range: Optional[Range] = None
level_of_detail: Optional[LevelOfDetail] = None


class ArrivalSearch(BaseModel):
id: str
coords: Coordinates
arrival_time: datetime
travel_time: int
transportation: typing.Union[
PublicTransport,
Driving,
Ferry,
Walking,
Cycling,
DrivingTrain,
CyclingPublicTransport,
]
range: Optional[Range] = None
level_of_detail: Optional[LevelOfDetail] = None


class TimeMapRequestGeojson(TravelTimeRequest[FeatureCollection]):
departure_searches: List[DepartureSearch]
arrival_searches: List[ArrivalSearch]
Expand Down
2 changes: 1 addition & 1 deletion traveltimepy/dto/responses/map_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class PublicTransport(BaseModel):
class Features(BaseModel):
fares: bool
postcodes: bool
public_transport: Optional[PublicTransport]
public_transport: Optional[PublicTransport] = None


class Map(BaseModel):
Expand Down
4 changes: 2 additions & 2 deletions traveltimepy/dto/responses/postcodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@


class Property(BaseModel):
travel_time: Optional[int]
distance: Optional[int]
travel_time: Optional[int] = None
distance: Optional[int] = None


class Postcode(BaseModel):
Expand Down
8 changes: 4 additions & 4 deletions traveltimepy/dto/responses/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@


class Property(BaseModel):
travel_time: Optional[int]
fares: Optional[Fares]
distance: Optional[int]
route: Optional[Route]
travel_time: Optional[int] = None
fares: Optional[Fares] = None
distance: Optional[int] = None
route: Optional[Route] = None


class Location(BaseModel):
Expand Down
8 changes: 4 additions & 4 deletions traveltimepy/dto/responses/time_filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ class DistanceBreakdown(BaseModel):

class Property(BaseModel):
travel_time: int
distance: Optional[int]
distance_breakdown: Optional[List[DistanceBreakdown]]
fares: Optional[Fares]
route: Optional[Route]
distance: Optional[int] = None
distance_breakdown: Optional[List[DistanceBreakdown]] = None
fares: Optional[Fares] = None
route: Optional[Route] = None


class Location(BaseModel):
Expand Down
2 changes: 1 addition & 1 deletion traveltimepy/dto/responses/time_filter_fast.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class Fares(BaseModel):

class Properties(BaseModel):
travel_time: int
fares: Optional[Fares]
fares: Optional[Fares] = None


class Location(BaseModel):
Expand Down
8 changes: 4 additions & 4 deletions traveltimepy/dto/responses/time_map_wkt.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
from typing import List, Union, Dict, Any, TypeVar, Optional
from pydantic import BaseModel, Field, validator
from pydantic.generics import GenericModel
from pydantic import field_validator, BaseModel, Field

from traveltimepy.wkt import WKTObject, parse_wkt
from traveltimepy.wkt.helper import print_indented

Props = TypeVar("Props", bound=Union[Dict[str, Any], BaseModel])


class TimeMapWKTResult(GenericModel):
class TimeMapWKTResult(BaseModel):
search_id: str
shape: WKTObject
properties: Optional[Props] = Field(None)

@validator("shape", pre=True)
@field_validator("shape", mode="before")
@classmethod
def transform_shape(cls, shape: str) -> WKTObject:
return parse_wkt(shape)

Expand Down
6 changes: 3 additions & 3 deletions traveltimepy/dto/responses/zones.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ class TravelTime(BaseModel):


class Properties(BaseModel):
travel_time_reachable: Optional[TravelTime]
travel_time_all: Optional[TravelTime]
coverage: Optional[float]
travel_time_reachable: Optional[TravelTime] = None
travel_time_all: Optional[TravelTime] = None
coverage: Optional[float] = None


class Zone(BaseModel):
Expand Down
7 changes: 4 additions & 3 deletions traveltimepy/http.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import asyncio
import json
from dataclasses import dataclass
from typing import TypeVar, Type, Dict

from aiohttp import ClientSession, ClientResponse, TCPConnector
from pydantic.tools import parse_raw_as
from traveltimepy.dto.requests.request import TravelTimeRequest

from traveltimepy.dto.responses.error import ResponseError
Expand Down Expand Up @@ -100,8 +100,9 @@ async def send_get_async(

async def _process_response(response_class: Type[T], response: ClientResponse) -> T:
text = await response.text()
json_data = json.loads(text)
if response.status != 200:
parsed = parse_raw_as(ResponseError, text)
parsed = ResponseError.model_validate_json(json_data)
msg = (
f"Travel Time API request failed: {parsed.description}\n"
f"Error code: {parsed.error_code}\n"
Expand All @@ -110,4 +111,4 @@ async def _process_response(response_class: Type[T], response: ClientResponse) -
)
raise ApiError(msg)
else:
return parse_raw_as(response_class, text)
return response_class.parse_obj(json_data)
2 changes: 1 addition & 1 deletion traveltimepy/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "3.8.1"
__version__ = "3.9.0"
5 changes: 3 additions & 2 deletions traveltimepy/wkt/geometries.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from enum import Enum
from typing import List

from pydantic import BaseModel, validator
from pydantic import field_validator, BaseModel

from traveltimepy import Coordinates
from traveltimepy.wkt.helper import print_indented
Expand Down Expand Up @@ -43,7 +43,8 @@ class LineStringModel(WKTObject):
def __init__(self, **data):
super().__init__(type=GeometryType.LINESTRING, **data)

@validator("coordinates")
@field_validator("coordinates")
@classmethod
def check_minimum_coordinates(cls, coords):
if len(coords) < 2:
raise ValueError("LineString must have at least 2 coordinates.")
Expand Down

0 comments on commit 0f36477

Please sign in to comment.