Skip to content

Commit 4a0031c

Browse files
authored
Possibility of using local Playwright (#43)
1 parent 45ce697 commit 4a0031c

File tree

4 files changed

+72
-2
lines changed

4 files changed

+72
-2
lines changed

docs/local.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Local Playwright
2+
3+
In case the Playwright serverless functions are down or you prefer not to use them, you can run the Playwright server locally and request against that.
4+
5+
1. Install this package with the dependencies needed for Playwright:
6+
7+
```bash
8+
pip install fast-flights[local]
9+
```
10+
11+
2. Install the Playwright browser:
12+
13+
```bash
14+
python -m playwright install chromium # or `python -m playwright install` if you want to install all browsers
15+
```
16+
17+
3. Now you can use the `fetch_mode="local"` parameter in `get_flights`:
18+
19+
```python
20+
get_flights(
21+
...,
22+
fetch_mode="local" # common/fallback/force-fallback/local
23+
)
24+
25+
# ...or:
26+
27+
get_fights_from_filter(
28+
filter,
29+
mode="local" # common/fallback/force-fallback/local
30+
)
31+
```

fast_flights/core.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def get_flights_from_filter(
2020
filter: TFSData,
2121
currency: str = "",
2222
*,
23-
mode: Literal["common", "fallback", "force-fallback"] = "common",
23+
mode: Literal["common", "fallback", "force-fallback", "local"] = "common",
2424
) -> Result:
2525
data = filter.as_b64()
2626

@@ -40,6 +40,11 @@ def get_flights_from_filter(
4040
else:
4141
raise e
4242

43+
elif mode == "local":
44+
from .local_playwright import local_playwright_fetch
45+
46+
res = local_playwright_fetch(params)
47+
4348
else:
4449
res = fallback_playwright_fetch(params)
4550

@@ -57,7 +62,7 @@ def get_flights(
5762
trip: Literal["round-trip", "one-way", "multi-city"],
5863
passengers: Passengers,
5964
seat: Literal["economy", "premium-economy", "business", "first"],
60-
fetch_mode: Literal["common", "fallback", "force-fallback"] = "common",
65+
fetch_mode: Literal["common", "fallback", "force-fallback", "local"] = "common",
6166
max_stops: Optional[int] = None,
6267
) -> Result:
6368
return get_flights_from_filter(

fast_flights/local_playwright.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
from typing import Any
2+
import asyncio
3+
from playwright.async_api import async_playwright
4+
5+
async def fetch_with_playwright(url: str) -> str:
6+
async with async_playwright() as p:
7+
browser = await p.chromium.launch()
8+
page = await browser.new_page()
9+
await page.goto(url)
10+
if page.url.startswith("https://consent.google.com"):
11+
await page.click('text="Accept all"')
12+
locator = page.locator('.eQ35Ce')
13+
await locator.wait_for()
14+
body = await page.evaluate(
15+
"() => document.querySelector('[role=\"main\"]').innerHTML"
16+
)
17+
await browser.close()
18+
return body
19+
20+
def local_playwright_fetch(params: dict) -> Any:
21+
url = "https://www.google.com/travel/flights?" + "&".join(f"{k}={v}" for k, v in params.items())
22+
body = asyncio.run(fetch_with_playwright(url))
23+
24+
class DummyResponse:
25+
status_code = 200
26+
text = body
27+
text_markdown = body
28+
29+
return DummyResponse

pyproject.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ dependencies = [
2424
"selectolax"
2525
]
2626

27+
[project.optional-dependencies]
28+
local = [
29+
"playwright"
30+
]
31+
2732
[project.urls]
2833
"Source" = "https://github.com/AWeirdDev/flights"
2934
"Issues" = "https://github.com/AWeirdDev/flights/issues"

0 commit comments

Comments
 (0)