refactor: replace manual cookie handling with session-based APIClient#101
Merged
Conversation
Introduce APIClient in both packages as the single point of HTTP concerns (session, cookies, TLS fingerprint). FlightRadar24API now delegates all transport details to APIClient and has no knowledge of sessions, curl_cffi or cookie jars. - Python: APIClient wraps curl_cffi Session; exposes request(), request_standalone() for thread-safe calls, get_cookie() and clear_cookies(). APIRequest accepts an optional session parameter. - Node.js: APIClient wraps a Session (cookie jar over undici fetch); same interface minus request_standalone (not needed in single-threaded event loop). - login() resets cookies before attempting auth to guarantee a clean state on re-login or failed login attempts. - logout() uses try/finally to ensure cookies are always cleared even if the logout request throws.
There was a problem hiding this comment.
Pull request overview
This PR refactors both the Python and Node.js SDKs to centralize HTTP/session concerns (cookies, session reuse, TLS fingerprinting) behind a new APIClient, removing manual cookie plumbing from the higher-level FlightRadar24API implementations.
Changes:
- Python: introduce
APIClientwrapping acurl_cffiSession, updateAPIRequestto accept an optional session, and migrateFlightRadar24APIto use the client (including cookie reset on login and guaranteed cookie clearing on logout). - Node.js: introduce a lightweight
Session+APIClientwrapper over the existingrequest()function, and migrateFlightRadar24APIto use the client (including cookie reset on login and guaranteed cookie clearing on logout). - Remove manual cookie passing/storage in both APIs in favor of session-managed cookies.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| python/FlightRadar24/request.py | Adds APIClient and session-aware APIRequest to centralize HTTP/session handling. |
| python/FlightRadar24/api.py | Migrates API methods to use APIClient; resets/clears cookies during login/logout. |
| nodejs/FlightRadar24/request.js | Adds Session and APIClient wrappers to persist cookies across requests. |
| nodejs/FlightRadar24/api.js | Migrates API methods to use APIClient; resets/clears cookies during login/logout. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Add ESLint rule object-curly-spacing: always and apply spacing consistently across all source files. Fix two lines exceeding the 130-char limit in api.js.
JeanExtreme002
added a commit
that referenced
this pull request
May 11, 2026
#102) * refactor: harden SDK against Cloudflare blocks and add offline test suite - Detect Cloudflare also on HTTP 403 (cf-mitigated / Server: cloudflare), previously only 520 was mapped to CloudflareError. - Fix TypeError in Flight.get_altitude / get_flight_level / get_ground_speed / get_heading / get_vertical_speed (and Node camelCase equivalents) when the underlying field arrived as the "N/A" sentinel. - Add opt-in RetryPolicy with exponential backoff + jitter; passed via FlightRadar24API(retry=...) / new FlightRadar24API({ retry: ... }). - Make Chrome TLS impersonation parameter-driven (Python: impersonate="chromeNNN"; Node: { impersonate: { ciphers, sigalgs, ecdhCurve } }), so users can override the bundled chrome136 profile without waiting for a release. - Replace jsdom with node-html-parser: zero transitive deps and works on Node 18 (cheerio 1.x pulls a recent undici that requires the File global). - parse_airports_html / parseAirportsHtml no longer silently coerce invalid coordinates to (0,0); emit a warning and return None/null. Missing <tbody> also logs a warning. - Add offline parser test suite with bundled HTML fixtures (11 tests per SDK). CI now gates PRs on the offline suite and runs live integration tests under retry without blocking pushes when FR24 changes layout. - Dedupe Entity._get_info between Flight and Airport (Python); drop the unused ABC declaration; introduce EARTH_RADIUS_KM constant in both SDKs. - Switch default accept-language header from pt-BR,pt;q=0.9,... to en-US,en;q=0.9. - Add Airport.from_basic_info / from_info / from_details classmethods (Python) and Airport.fromBasicInfo / fromInfo / fromDetails static methods (Node) as intention-revealing aliases. The existing constructor forms remain. - Sync nodejs/FlightRadar24/index.d.ts with the post-#101 surface; remove the phantom cookies field on __loginData; expose APIClient and RetryPolicy. - CI: add pip-audit, npm audit and pytest --cov steps. * fix: narrow Cloudflare 403 detection to cf-mitigated header The previous heuristic treated any 403 with `Server: cloudflare` as a CloudflareError. FR24 fronts every endpoint with Cloudflare, so legitimate plan-restricted 403s (e.g. a free account hitting get_history_data) were being misclassified as bot-mitigation blocks. Rely solely on the `cf-mitigated` header, which Cloudflare sets only when its own bot management actually mitigated the request. * fix: address Copilot review findings on RetryPolicy - Node: timeouts were silently dropped from the retry path. fetch's native AbortError was being re-wrapped into a generic Error("Request timed out…"), losing the `name === "AbortError"` signal that runWithRetry relied on. Introduce a TimeoutError class and check `err instanceof TimeoutError` alongside the existing transient signals. - Python: RetryPolicy validated max_attempts but accepted negative base_delay / max_delay / jitter, which could feed time.sleep() a negative value and crash with ValueError. Reject negatives in __init__. - Node: mirror the validation in RetryPolicy for parity, even though setTimeout clamps negatives to 0 rather than crashing. * fix: deep-freeze TLS profile and guard retry loop against -O stripping - Deep-freeze CHROME136_PROFILE arrays so exported consumers cannot mutate them. - Replace assert in _run_with_retry with explicit RuntimeError to survive python -O. - Mark dependency audits as informational (continue-on-error) until baseline is clean. * test: add offline policy/transport suites and harden Airport parsing Splits the request-layer tests into two suites — policy (retry math, Cloudflare detection rules, error taxonomy) and transport (adapter-shaped behavior tied to undici/curl_cffi) — so the transport can be swapped without rewriting the policy tests. Also makes Airport entity initialization defensive against missing position/code/country/region keys, replaces a pair of assert-based login checks with explicit None checks on the private __login_data, downgrades a swallowed decompression failure to a logged warning, and updates the Node docs to drop the spurious await on the synchronous getZones() helper.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why is this PR necessary, what does it do?
Introduce APIClient in both packages as the single point of HTTP concerns (session, cookies, TLS fingerprint). FlightRadar24API now delegates all transport details to APIClient and has no knowledge of sessions, curl_cffi or cookie jars.
Checklist (complete all items):
References:
No references to be shared.
Notes:
No notes to be shared.