add gps positions get endpoint

This commit is contained in:
rmanach 2024-12-18 11:30:31 +01:00
parent a99621c42b
commit 0e482fcbc4
5 changed files with 86 additions and 25 deletions

View File

@ -28,7 +28,7 @@ if __name__ == "__main__":
cli = Client.from_env() cli = Client.from_env()
and use all the available methods to interact with the WhereIs API. and use all the available methods to interact with the WhereIs API.
Sessions: Sessions:
- create_session - create_session
- get_sessions - get_sessions
@ -43,6 +43,8 @@ if __name__ == "__main__":
- get_wstokens - get_wstokens
- create_wstoken - create_wstoken
- delete_wstoken - delete_wstoken
GPS positions:
- get_gps_positions
""" """
logging.info(f"WhereIs client v{VERSION}") logging.info(f"WhereIs client v{VERSION}")
@ -111,8 +113,9 @@ if __name__ == "__main__":
# get session events # get session events
cli.watch_session_events(session.get("id")) cli.watch_session_events(session.get("id"))
# doing your stuff... # get gps positions from "2024-12-25T23:00:00" to infinity...
time.sleep(2) gps_positions = cli.get_gps_positions(date_start="2024-12-25T23:00:00")
print(json.dumps(gps_positions, indent=2))
# close the session # close the session
session = cli.close_session(session.get("id")) session = cli.close_session(session.get("id"))

View File

@ -8,6 +8,8 @@ dynamic = ["version"]
description = "WhereIs API client library" description = "WhereIs API client library"
dependencies = [ dependencies = [
"requests==2.32.3", "requests==2.32.3",
"python-dotenv==1.0.1",
"sseclient-py==1.8.0",
] ]
[tool.hatch.version] [tool.hatch.version]
@ -20,7 +22,7 @@ packages = ["src"]
only-include = ["src"] only-include = ["src"]
[tool.hatch.build.targets.wheel.sources] [tool.hatch.build.targets.wheel.sources]
"src" = "whereis-client" "src" = "whereis_client"
[tool.ruff] [tool.ruff]
select = ["E", "F", "I"] select = ["E", "F", "I"]

View File

@ -2,4 +2,4 @@ from .client import Client, OrderField
__all__ = ["Client", "OrderField"] __all__ = ["Client", "OrderField"]
VERSION = "0.1.0" VERSION = "0.1.0a0"

View File

@ -1,6 +1,7 @@
import logging import logging
import os import os
from dataclasses import dataclass, field from dataclasses import dataclass, field
from datetime import datetime as dt
from enum import Enum from enum import Enum
from threading import Event, Thread from threading import Event, Thread
from typing import Any, Callable from typing import Any, Callable
@ -29,12 +30,17 @@ def refresh():
def decorator(func): def decorator(func):
def wrapper(*args, **kwargs): def wrapper(*args, **kwargs):
if len(args) > 0 and isinstance(args[0], Client): if len(args) > 0 and isinstance(args[0], Client):
try: for i in range(2):
return func(*args, **kwargs) try:
except UnauthorizedException: return func(*args, **kwargs)
logging.warning("refresh access token...") except UnauthorizedException as e:
args[0]._refresh() if i == 1: # second attempt
return func(*args, **kwargs) logging.error(
"second call attempt failed after refreshing token"
)
raise e
logging.warning("refresh access token...")
args[0]._refresh()
return wrapper return wrapper
@ -211,11 +217,10 @@ class Client:
"""Get paginate sessions.""" """Get paginate sessions."""
res = self.session.get(url) res = self.session.get(url)
if res.status_code == 401: if res.status_code == 401:
raise UnauthorizedException() raise UnauthorizedException(url, res)
if res.status_code >= 400: if res.status_code >= 400:
if res.status_code >= 400: raise WhereIsException(url, res)
raise WhereIsException(url, res)
return res.json() return res.json()
@ -265,7 +270,7 @@ class Client:
res = self.session.get(session_url) res = self.session.get(session_url)
if res.status_code == 401: if res.status_code == 401:
raise UnauthorizedException() raise UnauthorizedException(session_url, res)
if res.status_code >= 400: if res.status_code >= 400:
raise WhereIsException(session_url, res) raise WhereIsException(session_url, res)
@ -293,7 +298,7 @@ class Client:
) )
if res.status_code == 401: if res.status_code == 401:
raise UnauthorizedException() raise UnauthorizedException(sessions_url, res)
if res.status_code >= 400: if res.status_code >= 400:
raise WhereIsException(sessions_url, res) raise WhereIsException(sessions_url, res)
@ -322,7 +327,7 @@ class Client:
res = self.session.patch(session_url, json=data) res = self.session.patch(session_url, json=data)
if res.status_code == 401: if res.status_code == 401:
raise UnauthorizedException() raise UnauthorizedException(session_url, res)
if res.status_code >= 400: if res.status_code >= 400:
raise WhereIsException(session_url, res) raise WhereIsException(session_url, res)
@ -341,7 +346,7 @@ class Client:
res = self.session.delete(session_url) res = self.session.delete(session_url)
if res.status_code == 401: if res.status_code == 401:
raise UnauthorizedException() raise UnauthorizedException(session_url, res)
if res.status_code >= 400: if res.status_code >= 400:
raise WhereIsException(session_url, res) raise WhereIsException(session_url, res)
@ -363,7 +368,7 @@ class Client:
res = self.session.post(session_url, json={"users": users}) res = self.session.post(session_url, json={"users": users})
if res.status_code == 401: if res.status_code == 401:
raise UnauthorizedException() raise UnauthorizedException(session_url, res)
if res.status_code >= 400: if res.status_code >= 400:
raise WhereIsException(session_url, res) raise WhereIsException(session_url, res)
@ -378,7 +383,7 @@ class Client:
res = self.session.post(session_url) res = self.session.post(session_url)
if res.status_code == 401: if res.status_code == 401:
raise UnauthorizedException() raise UnauthorizedException(session_url, res)
if res.status_code >= 400: if res.status_code >= 400:
raise WhereIsException(session_url, res) raise WhereIsException(session_url, res)
@ -446,7 +451,7 @@ class Client:
res = self.session.get(wstoken_url) res = self.session.get(wstoken_url)
if res.status_code == 401: if res.status_code == 401:
raise UnauthorizedException() raise UnauthorizedException(wstoken_url, res)
if res.status_code >= 400: if res.status_code >= 400:
raise WhereIsException(wstoken_url, res) raise WhereIsException(wstoken_url, res)
@ -467,7 +472,7 @@ class Client:
res = self.session.post(wstoken_url) res = self.session.post(wstoken_url)
if res.status_code == 401: if res.status_code == 401:
raise UnauthorizedException() raise UnauthorizedException(wstoken_url, res)
if res.status_code >= 400: if res.status_code >= 400:
raise WhereIsException(wstoken_url, res) raise WhereIsException(wstoken_url, res)
@ -482,9 +487,60 @@ class Client:
res = self.session.delete(wstoken_url) res = self.session.delete(wstoken_url)
if res.status_code == 401: if res.status_code == 401:
raise UnauthorizedException() raise UnauthorizedException(wstoken_url, res)
if res.status_code >= 400: if res.status_code >= 400:
raise WhereIsException(wstoken_url, res) raise WhereIsException(wstoken_url, res)
return None return None
@refresh()
def _get_paginate_gps_postions(self, url: str) -> dict[str, Any] | WhereIsException:
res = self.session.get(url)
if res.status_code == 401:
raise UnauthorizedException(url, res)
if res.status_code >= 400:
raise WhereIsException(url, res)
return res.json()
def get_gps_positions(
self,
date_start: str | None = None,
date_end: str | None = None,
) -> list[dict[str, Any]] | ValueError | WhereIsException:
"""
Gets GPS positions data.
You can get GPS positions filtered by date interval using
optionals arguments `date_start` and `date_end`:
- `date_start`: [date_start,]
- `date_end`: [date_end,]
- `date_start` & `date_end`: [date_start,date_end]
The dates formats must be in any valid ISO 8601 format otherwise
it will raise a ValueError.
"""
gps_url = urljoin(self.base_url, "/gps/positions/")
lst_gps_positions: list[dict[str, Any]] = []
if date_start:
ds = dt.fromisoformat(date_start)
gps_url += f"?date_start={ds.isoformat()}"
if date_end:
de = dt.fromisoformat(date_end)
if date_start:
gps_url += f"&date_end={de.isoformat()}"
else:
gps_url += f"?date_end={de.isoformat()}"
while gps_url is not None:
logging.info(f"get gps data from: {gps_url}")
data = self._get_paginate_gps_postions(gps_url)
lst_gps_positions.extend([d for d in data["results"]])
gps_url = data["next"]
return lst_gps_positions

View File

@ -1,6 +1,6 @@
from requests import Response from requests import Response
__all__ = ["WhereIsException"] __all__ = ["WhereIsException", "UnauthorizedException"]
class WhereIsException(Exception): class WhereIsException(Exception):
@ -19,5 +19,5 @@ class WhereIsException(Exception):
return f"error calling: {self.url} - {self.error_code} - {self.content}" return f"error calling: {self.url} - {self.error_code} - {self.content}"
class UnauthorizedException(Exception): class UnauthorizedException(WhereIsException):
pass pass