flight_summary.get_light / get_full send datetime params in wrong format, API returns 400
Summary
FlightSummaryResource.get_light() and get_full() accept flight_datetime_from and flight_datetime_to as Python datetime objects, but serialize them with str(), which produces the format 2026-05-17 00:00:00+00:00 (space separator, with tz offset). The Flightradar24 API requires ISO 8601 in the format YYYY-MM-DDTHH:MM:SS (T separator, no offset), so every call with these parameters fails with a 400.
Environment
fr24sdk version: 0.3.0 (latest as of report)
- Python: 3.10
- httpx: bundled with SDK
Minimal reproduction
from datetime import datetime, timezone
from fr24sdk.client import Client
with Client(api_token="<token>") as client:
client.flight_summary.get_full(
flights=["AA123"],
flight_datetime_from=datetime(2026, 5, 17, tzinfo=timezone.utc),
flight_datetime_to=datetime(2026, 5, 20, 23, 59, 59, tzinfo=timezone.utc),
)
Actual outgoing request
GET https://fr24api.flightradar24.com/api/flight-summary/full
?flight_datetime_from=2026-05-17%2000%3A00%3A00%2B00%3A00
&flight_datetime_to=2026-05-20%2023%3A59%3A59%2B00%3A00
&flights=AA123
Actual response
fr24sdk.exceptions.BadRequestError: 400 Bad Request:
The 'flight_datetime_from' field must be a valid datetime in the format 'YYYY-MM-DDTHH:MM:SS'.,
The 'flight_datetime_to' field must be a valid datetime in the format 'YYYY-MM-DDTHH:MM:SS'.
Expected outgoing request
GET https://fr24api.flightradar24.com/api/flight-summary/full
?flight_datetime_from=2026-05-17T00%3A00%3A00
&flight_datetime_to=2026-05-20T23%3A59%3A59
&flights=AA123
The reproduction fails the same way when datetime objects are passed naive (no tzinfo) — str(datetime(2026, 5, 17)) produces '2026-05-17 00:00:00', which still uses a space rather than T.
Root cause
src/fr24sdk/resources/flight_summary.py, in _FlightSummaryParams._to_query_dict:
@model_serializer(mode="plain")
def _to_query_dict(self) -> dict[str, Any]:
query: dict[str, Any] = {}
for key, value in self.__dict__.items():
if value is None:
continue
if isinstance(value, list):
query[key] = ",".join(map(str, value))
else:
query[key] = str(value) # ← bug: str(datetime) is not ISO 8601
return query
str(datetime(...)) uses datetime.__str__, which is equivalent to isoformat(sep=' '). The API requires isoformat(sep='T') (and no timezone suffix).
Suggested fix
Special-case datetime (and date) in the serializer so they're formatted to the API's expected shape:
from datetime import date, datetime
@model_serializer(mode="plain")
def _to_query_dict(self) -> dict[str, Any]:
query: dict[str, Any] = {}
for key, value in self.__dict__.items():
if value is None:
continue
if isinstance(value, list):
query[key] = ",".join(map(str, value))
elif isinstance(value, datetime):
# API spec requires YYYY-MM-DDTHH:MM:SS with no timezone
naive = value.astimezone(timezone.utc).replace(tzinfo=None) if value.tzinfo else value
query[key] = naive.strftime("%Y-%m-%dT%H:%M:%S")
elif isinstance(value, date):
query[key] = value.isoformat()
else:
query[key] = str(value)
return query
(If the API accepts/expects UTC offsets in the future, this can be adjusted, but the current docs and 400 message specify the un-offset format.)
Impact
flight_summary.get_light(), get_full(), get_count(), and the deprecated count() are all affected.
- Any other resource whose
_to_query_dict runs a datetime through str() is likely affected the same way. A grep for model_serializer + str(value) in src/fr24sdk/resources/ would surface any others.
Workaround we're using
Bypassing the typed resource and calling client.transport.request() directly with pre-formatted strings:
client.transport.request(
"GET",
"/api/flight-summary/full",
params={
"flights": flight_code,
"flight_datetime_from": window_start.strftime("%Y-%m-%dT%H:%M:%S"),
"flight_datetime_to": window_end.strftime("%Y-%m-%dT%H:%M:%S"),
},
)
This works but gives up the typed parameter validation that's the main point of the SDK wrapper.
flight_summary.get_light/get_fullsend datetime params in wrong format, API returns 400Summary
FlightSummaryResource.get_light()andget_full()acceptflight_datetime_fromandflight_datetime_toas Pythondatetimeobjects, but serialize them withstr(), which produces the format2026-05-17 00:00:00+00:00(space separator, with tz offset). The Flightradar24 API requires ISO 8601 in the formatYYYY-MM-DDTHH:MM:SS(T separator, no offset), so every call with these parameters fails with a 400.Environment
fr24sdkversion: 0.3.0 (latest as of report)Minimal reproduction
Actual outgoing request
Actual response
Expected outgoing request
The reproduction fails the same way when
datetimeobjects are passed naive (notzinfo) —str(datetime(2026, 5, 17))produces'2026-05-17 00:00:00', which still uses a space rather thanT.Root cause
src/fr24sdk/resources/flight_summary.py, in_FlightSummaryParams._to_query_dict:str(datetime(...))usesdatetime.__str__, which is equivalent toisoformat(sep=' '). The API requiresisoformat(sep='T')(and no timezone suffix).Suggested fix
Special-case
datetime(anddate) in the serializer so they're formatted to the API's expected shape:(If the API accepts/expects UTC offsets in the future, this can be adjusted, but the current docs and 400 message specify the un-offset format.)
Impact
flight_summary.get_light(),get_full(),get_count(), and the deprecatedcount()are all affected._to_query_dictruns adatetimethroughstr()is likely affected the same way. A grep formodel_serializer+str(value)insrc/fr24sdk/resources/would surface any others.Workaround we're using
Bypassing the typed resource and calling
client.transport.request()directly with pre-formatted strings:This works but gives up the typed parameter validation that's the main point of the SDK wrapper.