vessel-api-python 1.1.0__py3-none-any.whl → 1.3.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -65,11 +65,13 @@ from ._models import (
65
65
  PortEvent,
66
66
  PortEventResponse,
67
67
  PortEventsResponse,
68
+ PortInboundResponse,
68
69
  PortReference,
69
70
  PortResponse,
70
71
  PortsWithinLocationResponse,
71
72
  RadioBeacon,
72
73
  RadioBeaconsWithinLocationResponse,
74
+ ResolutionMeta,
73
75
  TypesInspectionDetailResponse,
74
76
  TypesInspectionsResponse,
75
77
  TypesOwnershipResponse,
@@ -111,6 +113,7 @@ __all__ = [
111
113
  "VesselReference",
112
114
  "VesselFormerName",
113
115
  "BroadcastStation",
116
+ "ResolutionMeta",
114
117
  # Models — Classification sub-models
115
118
  "ClassificationCertificate",
116
119
  "ClassificationCondition",
@@ -159,6 +162,7 @@ __all__ = [
159
162
  "PortEvent",
160
163
  "PortEventResponse",
161
164
  "PortEventsResponse",
165
+ "PortInboundResponse",
162
166
  # Models — Search
163
167
  "FindVesselsResponse",
164
168
  "FindPortsResponse",
@@ -224,6 +224,18 @@ class ClassificationYard(_Base):
224
224
  keel_date: str | None = Field(default=None, alias="keelDate")
225
225
 
226
226
 
227
+ # ---------------------------------------------------------------------------
228
+ # Resolution metadata
229
+ # ---------------------------------------------------------------------------
230
+
231
+
232
+ class ResolutionMeta(_Base):
233
+ """Metadata about ID resolution fallback. Present when the API resolved using a different ID type."""
234
+ requested_id_type: str | None = Field(default=None, alias="requestedIdType")
235
+ resolved_id_type: str | None = Field(default=None, alias="resolvedIdType")
236
+ resolved_id: int | None = Field(default=None, alias="resolvedId")
237
+
238
+
227
239
  # ---------------------------------------------------------------------------
228
240
  # Vessel models
229
241
  # ---------------------------------------------------------------------------
@@ -264,6 +276,7 @@ class VesselResponse(_Base):
264
276
  """Response for a single vessel lookup."""
265
277
 
266
278
  vessel: Vessel | None = None
279
+ meta: ResolutionMeta | None = Field(default=None, alias="_meta")
267
280
 
268
281
 
269
282
  class VesselPosition(_Base):
@@ -290,6 +303,7 @@ class VesselPositionResponse(_Base):
290
303
  vessel_position: VesselPosition | None = Field(
291
304
  default=None, alias="vesselPosition"
292
305
  )
306
+ meta: ResolutionMeta | None = Field(default=None, alias="_meta")
293
307
 
294
308
 
295
309
  class VesselPositionsResponse(_Base):
@@ -299,6 +313,7 @@ class VesselPositionsResponse(_Base):
299
313
  default=None, alias="vesselPositions"
300
314
  )
301
315
  next_token: str | None = Field(default=None, alias="nextToken")
316
+ meta: ResolutionMeta | None = Field(default=None, alias="_meta")
302
317
 
303
318
 
304
319
  # ---------------------------------------------------------------------------
@@ -352,6 +367,7 @@ class MarineCasualtiesResponse(_Base):
352
367
 
353
368
  casualties: list[MarineCasualty] | None = None
354
369
  next_token: str | None = Field(default=None, alias="nextToken")
370
+ meta: ResolutionMeta | None = Field(default=None, alias="_meta")
355
371
 
356
372
 
357
373
  class ClassificationVessel(_Base):
@@ -379,6 +395,7 @@ class ClassificationResponse(_Base):
379
395
  """Response for vessel classification."""
380
396
 
381
397
  classification: ClassificationVessel | None = None
398
+ meta: ResolutionMeta | None = Field(default=None, alias="_meta")
382
399
 
383
400
 
384
401
  class VesselEmission(_Base):
@@ -432,12 +449,14 @@ class VesselEmissionsResponse(_Base):
432
449
 
433
450
  emissions: list[VesselEmission] | None = None
434
451
  next_token: str | None = Field(default=None, alias="nextToken")
452
+ meta: ResolutionMeta | None = Field(default=None, alias="_meta")
435
453
 
436
454
 
437
455
  class VesselETA(_Base):
438
456
  """Vessel Estimated Time of Arrival information."""
439
457
 
440
458
  destination: str | None = None
459
+ destination_port: str | None = None
441
460
  draught: float | None = None
442
461
  eta: str | None = None
443
462
  imo: int | None = None
@@ -450,6 +469,13 @@ class VesselETAResponse(_Base):
450
469
  """Response for vessel ETA."""
451
470
 
452
471
  vessel_eta: VesselETA | None = Field(default=None, alias="vesselEta")
472
+ meta: ResolutionMeta | None = Field(default=None, alias="_meta")
473
+
474
+
475
+ class PortInboundResponse(_Base):
476
+ """Response containing vessels heading to a port."""
477
+ vessel_etas: list[VesselETA] | None = Field(default=None, alias="vesselETAs")
478
+ next_token: str | None = Field(default=None, alias="nextToken")
453
479
 
454
480
 
455
481
  # ---------------------------------------------------------------------------
@@ -652,12 +678,14 @@ class PortEventsResponse(_Base):
652
678
  default=None, alias="portEvents"
653
679
  )
654
680
  next_token: str | None = Field(default=None, alias="nextToken")
681
+ meta: ResolutionMeta | None = Field(default=None, alias="_meta")
655
682
 
656
683
 
657
684
  class PortEventResponse(_Base):
658
685
  """Response for a single port event (e.g. last by vessel)."""
659
686
 
660
687
  port_event: PortEvent | None = Field(default=None, alias="portEvent")
688
+ meta: ResolutionMeta | None = Field(default=None, alias="_meta")
661
689
 
662
690
 
663
691
  # ---------------------------------------------------------------------------
@@ -36,6 +36,7 @@ from ._models import (
36
36
  PortEvent,
37
37
  PortEventResponse,
38
38
  PortEventsResponse,
39
+ PortInboundResponse,
39
40
  PortResponse,
40
41
  PortsWithinLocationResponse,
41
42
  RadioBeacon,
@@ -46,6 +47,7 @@ from ._models import (
46
47
  Vessel,
47
48
  VesselEmission,
48
49
  VesselEmissionsResponse,
50
+ VesselETA,
49
51
  VesselETAResponse,
50
52
  VesselPosition,
51
53
  VesselPositionResponse,
@@ -128,9 +130,9 @@ class VesselsService:
128
130
  error_from_response(r.status_code, r.content)
129
131
  return TypesOwnershipResponse.model_validate(r.json())
130
132
 
131
- def positions(self, *, filter_id_type: str = "imo", filter_ids: str | None = None, pagination_limit: int | None = None, pagination_next_token: str | None = None) -> VesselPositionsResponse:
133
+ def positions(self, *, filter_id_type: str = "imo", filter_ids: str | None = None, time_from: str | None = None, time_to: str | None = None, pagination_limit: int | None = None, pagination_next_token: str | None = None) -> VesselPositionsResponse:
132
134
  """Retrieve positions for multiple vessels."""
133
- r = self._client.get("/vessels/positions", params=_strip_none({"filter.idType": filter_id_type, "filter.ids": filter_ids, "pagination.limit": pagination_limit, "pagination.nextToken": pagination_next_token}))
135
+ r = self._client.get("/vessels/positions", params=_strip_none({"filter.idType": filter_id_type, "filter.ids": filter_ids, "time.from": time_from, "time.to": time_to, "pagination.limit": pagination_limit, "pagination.nextToken": pagination_next_token}))
134
136
  error_from_response(r.status_code, r.content)
135
137
  return VesselPositionsResponse.model_validate(r.json())
136
138
 
@@ -179,6 +181,22 @@ class PortsService:
179
181
  error_from_response(r.status_code, r.content)
180
182
  return PortResponse.model_validate(r.json())
181
183
 
184
+ def inbound(self, unlocode: str, *, eta_from: str, eta_to: str, time_from: str | None = None, time_to: str | None = None, pagination_limit: int | None = None, pagination_next_token: str | None = None) -> PortInboundResponse:
185
+ """Retrieve vessels heading to a port."""
186
+ r = self._client.get(f"/port/{unlocode}/inbound", params=_strip_none({"filter.etaFrom": eta_from, "filter.etaTo": eta_to, "time.from": time_from, "time.to": time_to, "pagination.limit": pagination_limit, "pagination.nextToken": pagination_next_token}))
187
+ error_from_response(r.status_code, r.content)
188
+ return PortInboundResponse.model_validate(r.json())
189
+
190
+ def inbound_all(self, unlocode: str, *, eta_from: str, eta_to: str, time_from: str | None = None, time_to: str | None = None, pagination_limit: int | None = None) -> SyncIterator[VesselETA]:
191
+ """Iterate over all inbound vessels for a port across pages."""
192
+ token: str | None = None
193
+ def fetch() -> tuple[list[VesselETA], str | None]:
194
+ nonlocal token
195
+ resp = self.inbound(unlocode, eta_from=eta_from, eta_to=eta_to, time_from=time_from, time_to=time_to, pagination_limit=pagination_limit, pagination_next_token=token)
196
+ token = resp.next_token
197
+ return resp.vessel_etas or [], token
198
+ return SyncIterator(fetch)
199
+
182
200
 
183
201
  class PortEventsService:
184
202
  """Port event endpoints (sync)."""
@@ -304,15 +322,15 @@ class SearchService:
304
322
  def __init__(self, client: httpx.Client) -> None:
305
323
  self._client = client
306
324
 
307
- def vessels(self, *, filter_name: str | None = None, filter_imo: str | None = None, filter_mmsi: str | None = None, filter_flag: str | None = None, filter_vessel_type: str | None = None, filter_callsign: str | None = None, pagination_limit: int | None = None, pagination_next_token: str | None = None) -> FindVesselsResponse:
325
+ def vessels(self, *, filter_name: str | None = None, filter_imo: str | None = None, filter_mmsi: str | None = None, filter_flag: str | None = None, filter_vessel_type: str | None = None, filter_callsign: str | None = None, filter_year_built_min: int | None = None, filter_year_built_max: int | None = None, filter_class_society: str | None = None, filter_owner: str | None = None, pagination_limit: int | None = None, pagination_next_token: str | None = None) -> FindVesselsResponse:
308
326
  """Search for vessels by name, callsign, flag, type, and other filters."""
309
- r = self._client.get("/search/vessels", params=_strip_none({"filter.name": filter_name, "filter.imo": filter_imo, "filter.mmsi": filter_mmsi, "filter.flag": filter_flag, "filter.vesselType": filter_vessel_type, "filter.callsign": filter_callsign, "pagination.limit": pagination_limit, "pagination.nextToken": pagination_next_token}))
327
+ r = self._client.get("/search/vessels", params=_strip_none({"filter.name": filter_name, "filter.imo": filter_imo, "filter.mmsi": filter_mmsi, "filter.flag": filter_flag, "filter.vesselType": filter_vessel_type, "filter.callsign": filter_callsign, "filter.yearBuiltMin": filter_year_built_min, "filter.yearBuiltMax": filter_year_built_max, "filter.classSociety": filter_class_society, "filter.owner": filter_owner, "pagination.limit": pagination_limit, "pagination.nextToken": pagination_next_token}))
310
328
  error_from_response(r.status_code, r.content)
311
329
  return FindVesselsResponse.model_validate(r.json())
312
330
 
313
- def ports(self, *, filter_name: str | None = None, filter_country: str | None = None, filter_port_type: str | None = None, filter_region: str | None = None, pagination_limit: int | None = None, pagination_next_token: str | None = None) -> FindPortsResponse:
331
+ def ports(self, *, filter_name: str | None = None, filter_country: str | None = None, filter_port_type: str | None = None, filter_size: str | None = None, filter_region: str | None = None, filter_harbor_size: str | None = None, filter_harbor_use: str | None = None, pagination_limit: int | None = None, pagination_next_token: str | None = None) -> FindPortsResponse:
314
332
  """Search for ports by name, country, type, region, and other filters."""
315
- r = self._client.get("/search/ports", params=_strip_none({"filter.name": filter_name, "filter.country": filter_country, "filter.type": filter_port_type, "filter.region": filter_region, "pagination.limit": pagination_limit, "pagination.nextToken": pagination_next_token}))
333
+ r = self._client.get("/search/ports", params=_strip_none({"filter.name": filter_name, "filter.country": filter_country, "filter.type": filter_port_type, "filter.size": filter_size, "filter.region": filter_region, "filter.harborSize": filter_harbor_size, "filter.harborUse": filter_harbor_use, "pagination.limit": pagination_limit, "pagination.nextToken": pagination_next_token}))
316
334
  error_from_response(r.status_code, r.content)
317
335
  return FindPortsResponse.model_validate(r.json())
318
336
 
@@ -409,15 +427,15 @@ class LocationService:
409
427
  def __init__(self, client: httpx.Client) -> None:
410
428
  self._client = client
411
429
 
412
- def vessels_bounding_box(self, *, lat_min: float | None = None, lat_max: float | None = None, lon_min: float | None = None, lon_max: float | None = None, pagination_limit: int | None = None, pagination_next_token: str | None = None) -> VesselsWithinLocationResponse:
430
+ def vessels_bounding_box(self, *, lat_min: float | None = None, lat_max: float | None = None, lon_min: float | None = None, lon_max: float | None = None, time_from: str | None = None, time_to: str | None = None, pagination_limit: int | None = None, pagination_next_token: str | None = None) -> VesselsWithinLocationResponse:
413
431
  """Retrieve vessel positions within a bounding box."""
414
- r = self._client.get("/location/vessels/bounding-box", params=_strip_none({"filter.latBottom": lat_min, "filter.latTop": lat_max, "filter.lonLeft": lon_min, "filter.lonRight": lon_max, "pagination.limit": pagination_limit, "pagination.nextToken": pagination_next_token}))
432
+ r = self._client.get("/location/vessels/bounding-box", params=_strip_none({"filter.latBottom": lat_min, "filter.latTop": lat_max, "filter.lonLeft": lon_min, "filter.lonRight": lon_max, "time.from": time_from, "time.to": time_to, "pagination.limit": pagination_limit, "pagination.nextToken": pagination_next_token}))
415
433
  error_from_response(r.status_code, r.content)
416
434
  return VesselsWithinLocationResponse.model_validate(r.json())
417
435
 
418
- def vessels_radius(self, *, latitude: float | None = None, longitude: float | None = None, radius: float | None = None, pagination_limit: int | None = None, pagination_next_token: str | None = None) -> VesselsWithinLocationResponse:
436
+ def vessels_radius(self, *, latitude: float | None = None, longitude: float | None = None, radius: float | None = None, time_from: str | None = None, time_to: str | None = None, pagination_limit: int | None = None, pagination_next_token: str | None = None) -> VesselsWithinLocationResponse:
419
437
  """Retrieve vessel positions within a radius."""
420
- r = self._client.get("/location/vessels/radius", params=_strip_none({"filter.latitude": latitude, "filter.longitude": longitude, "filter.radius": radius, "pagination.limit": pagination_limit, "pagination.nextToken": pagination_next_token}))
438
+ r = self._client.get("/location/vessels/radius", params=_strip_none({"filter.latitude": latitude, "filter.longitude": longitude, "filter.radius": radius, "time.from": time_from, "time.to": time_to, "pagination.limit": pagination_limit, "pagination.nextToken": pagination_next_token}))
421
439
  error_from_response(r.status_code, r.content)
422
440
  return VesselsWithinLocationResponse.model_validate(r.json())
423
441
 
@@ -692,9 +710,9 @@ class AsyncVesselsService:
692
710
  error_from_response(r.status_code, r.content)
693
711
  return TypesOwnershipResponse.model_validate(r.json())
694
712
 
695
- async def positions(self, *, filter_id_type: str = "imo", filter_ids: str | None = None, pagination_limit: int | None = None, pagination_next_token: str | None = None) -> VesselPositionsResponse:
713
+ async def positions(self, *, filter_id_type: str = "imo", filter_ids: str | None = None, time_from: str | None = None, time_to: str | None = None, pagination_limit: int | None = None, pagination_next_token: str | None = None) -> VesselPositionsResponse:
696
714
  """Retrieve positions for multiple vessels."""
697
- r = await self._client.get("/vessels/positions", params=_strip_none({"filter.idType": filter_id_type, "filter.ids": filter_ids, "pagination.limit": pagination_limit, "pagination.nextToken": pagination_next_token}))
715
+ r = await self._client.get("/vessels/positions", params=_strip_none({"filter.idType": filter_id_type, "filter.ids": filter_ids, "time.from": time_from, "time.to": time_to, "pagination.limit": pagination_limit, "pagination.nextToken": pagination_next_token}))
698
716
  error_from_response(r.status_code, r.content)
699
717
  return VesselPositionsResponse.model_validate(r.json())
700
718
 
@@ -743,6 +761,22 @@ class AsyncPortsService:
743
761
  error_from_response(r.status_code, r.content)
744
762
  return PortResponse.model_validate(r.json())
745
763
 
764
+ async def inbound(self, unlocode: str, *, eta_from: str, eta_to: str, time_from: str | None = None, time_to: str | None = None, pagination_limit: int | None = None, pagination_next_token: str | None = None) -> PortInboundResponse:
765
+ """Retrieve vessels heading to a port."""
766
+ r = await self._client.get(f"/port/{unlocode}/inbound", params=_strip_none({"filter.etaFrom": eta_from, "filter.etaTo": eta_to, "time.from": time_from, "time.to": time_to, "pagination.limit": pagination_limit, "pagination.nextToken": pagination_next_token}))
767
+ error_from_response(r.status_code, r.content)
768
+ return PortInboundResponse.model_validate(r.json())
769
+
770
+ def inbound_all(self, unlocode: str, *, eta_from: str, eta_to: str, time_from: str | None = None, time_to: str | None = None, pagination_limit: int | None = None) -> AsyncIterator[VesselETA]:
771
+ """Iterate over all inbound vessels for a port across pages."""
772
+ token: str | None = None
773
+ async def fetch() -> tuple[list[VesselETA], str | None]:
774
+ nonlocal token
775
+ resp = await self.inbound(unlocode, eta_from=eta_from, eta_to=eta_to, time_from=time_from, time_to=time_to, pagination_limit=pagination_limit, pagination_next_token=token)
776
+ token = resp.next_token
777
+ return resp.vessel_etas or [], token
778
+ return AsyncIterator(fetch)
779
+
746
780
 
747
781
  class AsyncPortEventsService:
748
782
  """Port event endpoints (async)."""
@@ -868,15 +902,15 @@ class AsyncSearchService:
868
902
  def __init__(self, client: httpx.AsyncClient) -> None:
869
903
  self._client = client
870
904
 
871
- async def vessels(self, *, filter_name: str | None = None, filter_imo: str | None = None, filter_mmsi: str | None = None, filter_flag: str | None = None, filter_vessel_type: str | None = None, filter_callsign: str | None = None, pagination_limit: int | None = None, pagination_next_token: str | None = None) -> FindVesselsResponse:
905
+ async def vessels(self, *, filter_name: str | None = None, filter_imo: str | None = None, filter_mmsi: str | None = None, filter_flag: str | None = None, filter_vessel_type: str | None = None, filter_callsign: str | None = None, filter_year_built_min: int | None = None, filter_year_built_max: int | None = None, filter_class_society: str | None = None, filter_owner: str | None = None, pagination_limit: int | None = None, pagination_next_token: str | None = None) -> FindVesselsResponse:
872
906
  """Search for vessels."""
873
- r = await self._client.get("/search/vessels", params=_strip_none({"filter.name": filter_name, "filter.imo": filter_imo, "filter.mmsi": filter_mmsi, "filter.flag": filter_flag, "filter.vesselType": filter_vessel_type, "filter.callsign": filter_callsign, "pagination.limit": pagination_limit, "pagination.nextToken": pagination_next_token}))
907
+ r = await self._client.get("/search/vessels", params=_strip_none({"filter.name": filter_name, "filter.imo": filter_imo, "filter.mmsi": filter_mmsi, "filter.flag": filter_flag, "filter.vesselType": filter_vessel_type, "filter.callsign": filter_callsign, "filter.yearBuiltMin": filter_year_built_min, "filter.yearBuiltMax": filter_year_built_max, "filter.classSociety": filter_class_society, "filter.owner": filter_owner, "pagination.limit": pagination_limit, "pagination.nextToken": pagination_next_token}))
874
908
  error_from_response(r.status_code, r.content)
875
909
  return FindVesselsResponse.model_validate(r.json())
876
910
 
877
- async def ports(self, *, filter_name: str | None = None, filter_country: str | None = None, filter_port_type: str | None = None, filter_region: str | None = None, pagination_limit: int | None = None, pagination_next_token: str | None = None) -> FindPortsResponse:
911
+ async def ports(self, *, filter_name: str | None = None, filter_country: str | None = None, filter_port_type: str | None = None, filter_size: str | None = None, filter_region: str | None = None, filter_harbor_size: str | None = None, filter_harbor_use: str | None = None, pagination_limit: int | None = None, pagination_next_token: str | None = None) -> FindPortsResponse:
878
912
  """Search for ports."""
879
- r = await self._client.get("/search/ports", params=_strip_none({"filter.name": filter_name, "filter.country": filter_country, "filter.type": filter_port_type, "filter.region": filter_region, "pagination.limit": pagination_limit, "pagination.nextToken": pagination_next_token}))
913
+ r = await self._client.get("/search/ports", params=_strip_none({"filter.name": filter_name, "filter.country": filter_country, "filter.type": filter_port_type, "filter.size": filter_size, "filter.region": filter_region, "filter.harborSize": filter_harbor_size, "filter.harborUse": filter_harbor_use, "pagination.limit": pagination_limit, "pagination.nextToken": pagination_next_token}))
880
914
  error_from_response(r.status_code, r.content)
881
915
  return FindPortsResponse.model_validate(r.json())
882
916
 
@@ -973,15 +1007,15 @@ class AsyncLocationService:
973
1007
  def __init__(self, client: httpx.AsyncClient) -> None:
974
1008
  self._client = client
975
1009
 
976
- async def vessels_bounding_box(self, *, lat_min: float | None = None, lat_max: float | None = None, lon_min: float | None = None, lon_max: float | None = None, pagination_limit: int | None = None, pagination_next_token: str | None = None) -> VesselsWithinLocationResponse:
1010
+ async def vessels_bounding_box(self, *, lat_min: float | None = None, lat_max: float | None = None, lon_min: float | None = None, lon_max: float | None = None, time_from: str | None = None, time_to: str | None = None, pagination_limit: int | None = None, pagination_next_token: str | None = None) -> VesselsWithinLocationResponse:
977
1011
  """Retrieve vessel positions within a bounding box."""
978
- r = await self._client.get("/location/vessels/bounding-box", params=_strip_none({"filter.latBottom": lat_min, "filter.latTop": lat_max, "filter.lonLeft": lon_min, "filter.lonRight": lon_max, "pagination.limit": pagination_limit, "pagination.nextToken": pagination_next_token}))
1012
+ r = await self._client.get("/location/vessels/bounding-box", params=_strip_none({"filter.latBottom": lat_min, "filter.latTop": lat_max, "filter.lonLeft": lon_min, "filter.lonRight": lon_max, "time.from": time_from, "time.to": time_to, "pagination.limit": pagination_limit, "pagination.nextToken": pagination_next_token}))
979
1013
  error_from_response(r.status_code, r.content)
980
1014
  return VesselsWithinLocationResponse.model_validate(r.json())
981
1015
 
982
- async def vessels_radius(self, *, latitude: float | None = None, longitude: float | None = None, radius: float | None = None, pagination_limit: int | None = None, pagination_next_token: str | None = None) -> VesselsWithinLocationResponse:
1016
+ async def vessels_radius(self, *, latitude: float | None = None, longitude: float | None = None, radius: float | None = None, time_from: str | None = None, time_to: str | None = None, pagination_limit: int | None = None, pagination_next_token: str | None = None) -> VesselsWithinLocationResponse:
983
1017
  """Retrieve vessel positions within a radius."""
984
- r = await self._client.get("/location/vessels/radius", params=_strip_none({"filter.latitude": latitude, "filter.longitude": longitude, "filter.radius": radius, "pagination.limit": pagination_limit, "pagination.nextToken": pagination_next_token}))
1018
+ r = await self._client.get("/location/vessels/radius", params=_strip_none({"filter.latitude": latitude, "filter.longitude": longitude, "filter.radius": radius, "time.from": time_from, "time.to": time_to, "pagination.limit": pagination_limit, "pagination.nextToken": pagination_next_token}))
985
1019
  error_from_response(r.status_code, r.content)
986
1020
  return VesselsWithinLocationResponse.model_validate(r.json())
987
1021
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: vessel-api-python
3
- Version: 1.1.0
3
+ Version: 1.3.0
4
4
  Summary: Python client for the Vessel Tracking API — maritime vessel tracking, port events, emissions, and navigation data.
5
5
  Project-URL: Documentation, https://vesselapi.com/docs
6
6
  Project-URL: Repository, https://github.com/vessel-api/vesselapi-python
@@ -101,6 +101,23 @@ asyncio.run(main())
101
101
 
102
102
  **37 methods total.**
103
103
 
104
+ ## Vessel Lookup & Location
105
+
106
+ ```python
107
+ # Get vessel details by IMO number (defaults to IMO; pass filter_id_type="mmsi" for MMSI).
108
+ vessel = client.vessels.get("9811000")
109
+ print(f"{vessel.vessel.name} ({vessel.vessel.vessel_type})")
110
+
111
+ # Get the vessel's latest AIS position.
112
+ pos = client.vessels.position("9811000")
113
+ print(f"Position: {pos.vessel_position.latitude}, {pos.vessel_position.longitude}")
114
+
115
+ # Find all vessels within 10 km of Rotterdam.
116
+ nearby = client.location.vessels_radius(latitude=51.9225, longitude=4.47917, radius=10000)
117
+ for v in nearby.vessels or []:
118
+ print(f"{v.vessel_name} at {v.latitude}, {v.longitude}")
119
+ ```
120
+
104
121
  ## Error Handling
105
122
 
106
123
  All methods raise specific exception types on non-2xx responses:
@@ -126,15 +143,15 @@ Every list endpoint has an `all_*` / `list_all` variant returning an iterator:
126
143
 
127
144
  ```python
128
145
  # Sync
129
- for vessel in client.search.all_vessels(filter_name="tanker"):
146
+ for vessel in client.search.all_vessels(filter_vessel_type="Tanker"):
130
147
  print(vessel.name)
131
148
 
132
149
  # Async
133
- async for vessel in client.search.all_vessels(filter_name="tanker"):
150
+ async for vessel in client.search.all_vessels(filter_vessel_type="Tanker"):
134
151
  print(vessel.name)
135
152
 
136
- # Collect all at once
137
- vessels = client.search.all_vessels(filter_name="tanker").collect()
153
+ # Collect a bounded set at once
154
+ vessels = client.search.all_vessels(filter_vessel_type="Tanker", pagination_limit=50).collect()
138
155
  ```
139
156
 
140
157
  ## Configuration
@@ -0,0 +1,13 @@
1
+ vessel_api_python/__init__.py,sha256=kmYpzbtVfaMHRXUBoom7JqZa5hCif3vGL8y-q5n4DrA,4599
2
+ vessel_api_python/_client.py,sha256=39yKlQ4W2TnE85sTtK7KlBzFF385Pl52I5ghyq575EA,5067
3
+ vessel_api_python/_constants.py,sha256=Cp_uNnK0RljiWlyPmkMrVFoQtF5GpXTggSCD1SPvcyk,244
4
+ vessel_api_python/_errors.py,sha256=pxDm36mbrviOoDRmJ-ogtlUIsyu-dHpC0jcs5f34WDU,4310
5
+ vessel_api_python/_iterator.py,sha256=SkgsGSdxLrKtw-ad8fSUPaEDDJCamAKK0PrG_P8HX-4,3198
6
+ vessel_api_python/_models.py,sha256=eawnhctWmvGK505EJzDyszTqXpI5ctRg73-uR6AVOck,30575
7
+ vessel_api_python/_services.py,sha256=PoRoHZP7PoqcUGGEaZNszm9_a1K_nTBQu_s5OaPCIqI,79094
8
+ vessel_api_python/_transport.py,sha256=_4s-65JMRwD2S435u0iuoLGH_GyLNaX8cP_uSh_u80I,6692
9
+ vessel_api_python/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
+ vessel_api_python-1.3.0.dist-info/METADATA,sha256=omcgGfIpL-dHECfAZqvoTmHqAUn6oKf14g0NoAULcHk,7019
11
+ vessel_api_python-1.3.0.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
12
+ vessel_api_python-1.3.0.dist-info/licenses/LICENSE,sha256=zoj_abq99mj8cz-Bz71XCnwB-Qv3kU1VzVXeKEntuQU,1067
13
+ vessel_api_python-1.3.0.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.28.0
2
+ Generator: hatchling 1.29.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
@@ -1,13 +0,0 @@
1
- vessel_api_python/__init__.py,sha256=K4ob0XECb6ur-lKl_h0YAJQAhQ9HO1JSTv9fCshj9gQ,4505
2
- vessel_api_python/_client.py,sha256=39yKlQ4W2TnE85sTtK7KlBzFF385Pl52I5ghyq575EA,5067
3
- vessel_api_python/_constants.py,sha256=Cp_uNnK0RljiWlyPmkMrVFoQtF5GpXTggSCD1SPvcyk,244
4
- vessel_api_python/_errors.py,sha256=pxDm36mbrviOoDRmJ-ogtlUIsyu-dHpC0jcs5f34WDU,4310
5
- vessel_api_python/_iterator.py,sha256=SkgsGSdxLrKtw-ad8fSUPaEDDJCamAKK0PrG_P8HX-4,3198
6
- vessel_api_python/_models.py,sha256=g1c--6UUhtfDSfTv4G6wDmYxGdURN8KASNNAXXQvibE,29124
7
- vessel_api_python/_services.py,sha256=c8OZ9IbG4O9lSrooRlLKBvze1G5NTflDIDcxFppNNYs,74652
8
- vessel_api_python/_transport.py,sha256=_4s-65JMRwD2S435u0iuoLGH_GyLNaX8cP_uSh_u80I,6692
9
- vessel_api_python/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
- vessel_api_python-1.1.0.dist-info/METADATA,sha256=OnBFUQL9TxJaKWTQw0aC0mA2xyqLtguruKQ6HT8KpSc,6336
11
- vessel_api_python-1.1.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
12
- vessel_api_python-1.1.0.dist-info/licenses/LICENSE,sha256=zoj_abq99mj8cz-Bz71XCnwB-Qv3kU1VzVXeKEntuQU,1067
13
- vessel_api_python-1.1.0.dist-info/RECORD,,