Skip to content

refactor: replace manual cookie handling with session-based APIClient#101

Merged
JeanExtreme002 merged 2 commits into
mainfrom
jeanextreme002/session
May 11, 2026
Merged

refactor: replace manual cookie handling with session-based APIClient#101
JeanExtreme002 merged 2 commits into
mainfrom
jeanextreme002/session

Conversation

@JeanExtreme002
Copy link
Copy Markdown
Owner

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.

  • 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.

Checklist (complete all items):

  • [ x ] Added tests as necessary.
  • [ x ] There is no breaking change for existing features.

References:

No references to be shared.

Notes:

No notes to be shared.

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.
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 APIClient wrapping a curl_cffi Session, update APIRequest to accept an optional session, and migrate FlightRadar24API to use the client (including cookie reset on login and guaranteed cookie clearing on logout).
  • Node.js: introduce a lightweight Session + APIClient wrapper over the existing request() function, and migrate FlightRadar24API to 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.

Comment thread python/FlightRadar24/api.py
Comment thread python/FlightRadar24/api.py
Comment thread nodejs/FlightRadar24/api.js
Comment thread nodejs/FlightRadar24/api.js
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 JeanExtreme002 merged commit 09ea390 into main May 11, 2026
7 checks passed
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.
@JeanExtreme002 JeanExtreme002 deleted the jeanextreme002/session branch May 13, 2026 04:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants