Compare commits

...
86 Commits
Author SHA1 Message Date
ThePhaseless 03c98375f2 remove blank issues 2025-02-06 17:54:25 +00:00
ThePhaseless 4bfb7845dd remove btmet due to dns issue 2025-02-06 17:50:44 +00:00
renovate[bot] d7c22f042e Update dependency seleniumbase to v4.34.6 (#72)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-02-02 20:50:05 +00:00
renovate[bot] 33a1327f93 Update dependency seleniumbase to v4.34.5 (#71)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-02-02 00:57:51 +00:00
renovate[bot] e52616934b Update dependency ruff to v0.9.4 (#70)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-31 01:37:57 +00:00
renovate[bot] 892daccc60 Update dependency fastapi to v0.115.8 (#69)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-30 22:09:55 +00:00
renovate[bot] 3d91874ddb Update dependency seleniumbase to v4.34.4 (#68)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-29 09:56:16 +00:00
renovate[bot] 3026ed4a41 Update dependency pytest-asyncio to v0.25.3 (#67)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-29 01:24:38 +00:00
ThePhaseless 4b5d82b4f1 remove apt python binaries 2025-01-27 20:56:50 +00:00
ThePhaseless 56d9a4659b update seleniumbase 2025-01-26 19:50:26 +00:00
ThePhaseless 273622c30c use uv as base 2025-01-26 19:50:21 +00:00
renovate[bot] d0b51020a0 Update dependency deptry to v0.23.0 (#66)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-26 12:26:48 +00:00
renovate[bot] d17def34ba Update dependency ruff to v0.9.3 (#64)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-24 12:59:06 +00:00
renovate[bot] 40a4bf3d8f Update dependency fastapi to v0.115.7 (#63)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-24 09:49:14 +00:00
renovate[bot] e0bb4115fb Update dependency pydantic to v2.10.6 (#65)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-24 05:53:35 +00:00
renovate[bot] 9e2d40845c Update dependency pytest-retry to v1.7.0 (#61)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-19 12:26:29 +00:00
renovate[bot] 6c3da87c00 Update dependency ruff to v0.9.2 (#60)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-16 21:39:41 +00:00
ThePhaseless 78d97dfd0d [skip ci] Remove deprecated env 2025-01-16 13:43:10 +01:00
renovate[bot] 4461f5a59a Update dependency seleniumbase to v4.33.15 (#58)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-14 09:54:19 +00:00
renovate[bot] 7dac738ac5 Update dependency ruff to v0.9.1 (#57)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-11 02:22:06 +00:00
renovate[bot] ead7a09ce2 Update dependency deptry to v0.22.0 (#56)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-10 18:34:01 +00:00
renovate[bot] bf85a854fa Update dependency seleniumbase to v4.33.14 (#55)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-10 09:42:44 +00:00
renovate[bot] 9a20451ad9 Update dependency seleniumbase to v4.33.13 (#54)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-10 02:36:09 +00:00
renovate[bot] 150bf80583 Update dependency ruff to v0.9.0 (#53)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-09 22:05:49 +00:00
renovate[bot] bcce6779cc Update dependency pydantic to v2.10.5 (#52)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-09 17:51:57 +00:00
renovate[bot] cd7e803411 Update dependency pytest-asyncio to v0.25.2 (#51)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-08 17:52:39 +00:00
renovate[bot] 5dc76167c2 Update dependency ruff to v0.8.6 (#50)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-04 16:55:58 +00:00
renovate[bot] 8ae150fd87 Update dependency ruff to v0.8.5 (#49)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-02 19:58:26 +00:00
ThePhaseless 0325877e19 [skip ci] clarified xvfb platform requirement 2025-01-02 12:35:30 +00:00
ThePhaseless c4159e5c38 disable headless on docker 2025-01-02 12:29:10 +00:00
ThePhaseless 83169ce019 add headless env 2025-01-02 12:18:21 +00:00
ThePhaseless 1c0929fbc5 check if url is valid 2025-01-02 12:17:43 +00:00
renovate[bot] 9170967455 Update dependency pytest-asyncio to v0.25.1 (#48)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-02 09:14:41 +00:00
renovate[bot] d5d0bf7923 Update dependency seleniumbase to v4.33.12 (#47)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-25 09:53:33 +00:00
renovate[bot] 17854c70ed Update dependency deptry to v0.21.2 (#45)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-20 05:22:27 +00:00
renovate[bot] e30954c98c Update dependency psutil to v6.1.1 (#44)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-19 22:35:44 +00:00
renovate[bot] 2556a1bc88 Update dependency ruff to v0.8.4 (#43)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-19 15:40:42 +00:00
renovate[bot] 6c065d4dd3 Update dependency pydantic to v2.10.4 (#42)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-18 21:51:16 +00:00
ThePhaseless 096eda0fa3 fix utils 2024-12-18 13:32:37 +00:00
ThePhaseless 2ebb1bd820 optional xvfb support 2024-12-18 13:29:00 +00:00
ThePhaseless bf37539890 do not use virtual display 2024-12-17 12:03:53 +00:00
ThePhaseless d7ef83b8c6 add tags info and use latest on stable release 2024-12-17 12:03:36 +00:00
renovate[bot] 1a7cd9d657 Update dependency seleniumbase to v4.33.11 (#41)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-16 00:47:28 +00:00
renovate[bot] f9387e6942 Update dependency uvicorn to v0.34.0 (#40)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-15 19:06:58 +00:00
renovate[bot] 9d8c8db979 Update dependency uvicorn to v0.33.0 (#39)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-14 15:46:21 +00:00
renovate[bot] 979e0b4803 Update dependency ruff to v0.8.3 (#38)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-14 04:02:50 +00:00
ThePhaseless 3dbe3c424c fix circular imports 2024-12-13 22:43:29 +00:00
ThePhaseless bbb7c73065 kill old processes 2024-12-13 22:38:47 +00:00
ThePhaseless 9a353b3da2 remove poetry remains 2024-12-13 22:30:58 +00:00
ThePhaseless 140a97003e update packages 2024-12-13 21:12:30 +00:00
ThePhaseless c9e29f578d save cookies between requests 2024-12-12 23:45:24 +00:00
ThePhaseless c37ab51179 combine apt installs to one 2024-12-11 01:04:08 +00:00
ThePhaseless 962db9409c pull before build and test 2024-12-11 01:02:59 +00:00
ThePhaseless 96a9cc7ba9 test, then build 2024-12-11 01:01:00 +00:00
ThePhaseless bf9460b960 delete unused file 2024-12-11 00:52:20 +00:00
ThePhaseless c0547192dd test only on amd64 2024-12-11 00:46:53 +00:00
ThePhaseless 008077076c try using arm builder 2024-12-11 00:44:22 +00:00
ThePhaseless b33444dc48 use matrix for build 2024-12-11 00:40:11 +00:00
ThePhaseless b8c8576e5a github actions shared lib fix 2024-12-11 00:21:07 +00:00
ThePhaseless 905d802a26 add back retires 2024-12-10 23:38:13 +00:00
ThePhaseless f99429fdea update all packages but install only needed 2024-12-10 23:28:29 +00:00
ThePhaseless 1a4ec03587 Merge pull request #37 from ThePhaseless/uv
Uv
2024-12-10 23:50:34 +01:00
ThePhaseless ee2630dce2 enable auto update 2024-12-10 22:48:53 +00:00
ThePhaseless 82130b77c0 fix docker and update readme 2024-12-10 22:48:35 +00:00
ThePhaseless faf7e5e51a migrate to uv 2024-12-10 22:16:30 +00:00
ThePhaseless 597faa48dc add response type 2024-12-10 21:54:39 +00:00
ThePhaseless a28dbbe972 use docker to test 2024-12-10 21:54:29 +00:00
ThePhaseless 82124dee9b force exit on exception 2024-12-10 21:29:20 +00:00
ThePhaseless 0551c7b82b use uv 2024-12-08 16:49:38 +00:00
ThePhaseless b483dba080 [skip ci] Mili to Mega 2024-12-02 10:29:13 +01:00
ThePhaseless 7533d039ac Merge pull request #30 from ThePhaseless/renovate/python-3.x
Update python Docker tag to v3.13
2024-11-30 14:26:22 +01:00
renovate[bot] 38b2ea0798 Update python Docker tag to v3.13 2024-11-30 12:59:43 +00:00
ThePhaseless 58ae7964df remove python action update script 2024-11-30 12:59:00 +00:00
ThePhaseless 5283fb2d0e exclude python from autoupdate 2024-11-30 12:58:02 +00:00
ThePhaseless b3e7662782 fix ruff 2024-11-30 12:48:04 +00:00
ThePhaseless 074a3dd712 [skip ci] fix renovate 2024-11-30 12:47:34 +00:00
ThePhaseless cb48f16370 update python version in action with base 2024-11-30 12:45:19 +00:00
ThePhaseless 637de7572d use latest cosign 2024-11-30 12:44:08 +00:00
ThePhaseless 7b55252a73 run ruff before tests 2024-11-30 12:43:56 +00:00
ThePhaseless cbe4cf57a5 use all urls always 2024-11-30 12:43:05 +00:00
ThePhaseless 0775d107ad add version control and more verbose error return 2024-11-30 12:42:51 +00:00
ThePhaseless d36972b80e update python in action 2024-11-30 12:42:17 +00:00
renovate[bot] 27ec17f7f2 Update dependency seleniumbase to v4.33.2 (#24)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-30 12:08:29 +00:00
ThePhaseless 0b2bf9e12a use dynamic driver symlink 2024-11-30 11:38:48 +00:00
renovate[bot] 8c6906c916 Update dependency ruff to v0.8.1 (#29)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-29 06:26:30 +00:00
renovate[bot] 3103051ccf Update dependency httpx to ^0.28.0 (#28)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-28 18:20:06 +00:00
17 changed files with 1651 additions and 2387 deletions
+3 -4
View File
@@ -1,5 +1,4 @@
FROM python:3.12-bullseye
FROM ghcr.io/astral-sh/uv:debian
ENV UV_LINK_MODE=copy
RUN apt update && apt upgrade -y && apt install -y chromium chromium-driver xvfb
RUN curl -sSL https://install.python-poetry.org | python3 -
RUN apt update && apt upgrade -y && apt install -y chromium chromium-driver xvfb git
+2 -2
View File
@@ -1,9 +1,9 @@
---
name: Bug report
about: Create a report to help us improve
about: Create a bug report
title: ''
labels: ''
assignees: ''
assignees: 'ThePhaseless'
---
+1
View File
@@ -0,0 +1 @@
blank_issues_enabled: false
+19 -52
View File
@@ -23,50 +23,7 @@ env:
IMAGE_NAME: ${{ github.repository }}
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: "pip"
- name: Set up Poetry
run: pip install poetry
- name: Setup a local virtual environment (if no poetry.toml file)
run: |
poetry config virtualenvs.create true --local
poetry config virtualenvs.in-project true --local
- uses: actions/cache@v4
name: Define a cache for the virtual environment based on the dependencies lock file
with:
path: ./.venv
key: venv-${{ hashFiles('poetry.lock') }}
- name: Install dependencies
run: |
poetry install
sudo apt update
sudo apt install -y xvfb scrot python3-tk
wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
sudo apt install -y ./google-chrome-stable_current_amd64.deb
rm ./google-chrome-stable_current_amd64.deb
- name: Run tests
run: poetry run pytest --retries 2 -n auto --xvfb
- name: Upload screenshots if tests fail
if: failure()
uses: actions/upload-artifact@v4
with:
path: screenshots
build:
needs: test
runs-on: ubuntu-latest
permissions:
contents: read
@@ -83,21 +40,19 @@ jobs:
# https://github.com/sigstore/cosign-installer
- name: Install cosign
if: github.event_name != 'pull_request'
uses: sigstore/cosign-installer@dc72c7d5c4d10cd6bcb8cf6e3fd625a9e5e537da #v3.7.0
with:
cosign-release: "v2.2.4"
uses: sigstore/cosign-installer@v3
# Set up BuildKit Docker container builder to be able to build
# multi-platform images and export cache
# https://github.com/docker/setup-buildx-action
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@c47758b77c9736f4b2ef4073d4d51994fabfe349 # v3.7.1
uses: docker/setup-buildx-action@v3
# Login against a Docker registry except on PR
# https://github.com/docker/login-action
- name: Log into registry ${{ env.REGISTRY }}
if: github.event_name != 'pull_request'
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
@@ -107,7 +62,7 @@ jobs:
# https://github.com/docker/metadata-action
- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@369eb591f429131d6889c46b94e711f089e6ca96 # v5.6.1
uses: docker/metadata-action@v5
with:
tags: |
type=ref,event=branch
@@ -115,23 +70,35 @@ jobs:
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=raw,enable=${{ github.event_name != 'pull_request' && github.ref_name == 'main' }}, value=latest
type=raw,enable=${{ github.ref_type == 'tag' }}, value=latest
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
- name: Test
id: test
uses: docker/build-push-action@v6
with:
context: .
platforms: linux/amd64
cache-from: type=gha
pull: true
cache-to: type=gha,mode=max
target: test
# Build and push Docker image with Buildx (don't push on PR)
# https://github.com/docker/build-push-action
- name: Build and push Docker image
id: build-and-push
uses: docker/build-push-action@48aba3b46d1b1fec4febb7c5d0c644b249a11355 # v6.10.0
uses: docker/build-push-action@v6
with:
context: .
pull: true
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
platforms: linux/amd64,linux/arm64
cache-from: type=gha
cache-to: type=gha,mode=max
build-args: GITHUB_BUILD=true
build-args: GITHUB_BUILD=true,VERSION=${{ github.ref_name }}
# Sign the resulting Docker image digest except on PRs.
# This will only write to the public Rekor transparency log when the Docker
+19 -12
View File
@@ -1,4 +1,4 @@
FROM python:3.12-slim-bullseye
FROM debian:bullseye-slim AS base
# Inspired by https://github.com/Hudrolax/uc-docker-alpine/
@@ -11,22 +11,29 @@ ENV \
PYTHONUNBUFFERED=1 \
# prevents python creating .pyc files
PYTHONDONTWRITEBYTECODE=1 \
# do not ask any interactive question
POETRY_NO_INTERACTION=1 \
POETRY_VIRTUALENVS_IN_PROJECT=true \
PATH="${HOME}/.local/bin:$PATH" \
DISPLAY=:0
WORKDIR /app
EXPOSE 8191
RUN apt update &&\
apt install -y xvfb scrot python3-tk curl chromium chromium-driver
RUN curl -sSL https://install.python-poetry.org | python3 -
ENV PATH="${HOME}/.local/bin:$PATH"
COPY pyproject.toml poetry.lock ./
RUN poetry install
apt upgrade -y &&\
apt install -y --no-install-recommends --no-install-suggests xauth xvfb scrot curl chromium chromium-driver ca-certificates x11-common
RUN curl -LsSf https://astral.sh/uv/install.sh | sh
COPY pyproject.toml uv.lock ./
RUN uv sync
COPY . .
RUN cd .venv/lib/*/site-packages/seleniumbase/drivers && ln -s /usr/bin/chromedriver uc_driver
ENV USE_HEADLESS=false
FROM base AS test
RUN uv sync --group test
RUN ./test.sh
FROM base
EXPOSE 8191
HEALTHCHECK --interval=60s --timeout=30s --start-period=5s --retries=3 CMD [ "curl", "http://localhost:8191/health" ]
RUN ln /usr/bin/chromedriver ./.venv/lib/python3.12/site-packages/seleniumbase/drivers/uc_driver
CMD ["./cmd.sh"]
+33 -17
View File
@@ -2,46 +2,62 @@
An alternative to [FlareSolverr](https://github.com/FlareSolverr/FlareSolverr) as a drop-in replacement, build with [seleniumbase](https://seleniumbase.io/) and [FastAPI](https://fastapi.tiangolo.com).
> [!WARNING]
> [!IMPORTANT]
> Due to recent challenge changes, this software does not guarantee that the Cloudflare challenge will be bypassed. Cloudflare likely requires valid network traffic originating from the user’s public IP address to mark a connection as legitimate. While this tool may bypass the initial browser check, it does not ensure that requests will consistently pass Cloudflare's validation. More testing and data are required to understand how Cloudflare identifies connections and requests as valid. Invalid requests will result in Byparr's looping and eventually time-outing.
> [!WARNING]
> [!IMPORTANT]
> Support for NAS devices (like Synology) is minimal. Please report issues, but do not expect it to be fixed quickly. The only ARM device I have is a free Ampere Oracle VM, so I can only test ARM support on that. See [#22](https://github.com/ThePhaseless/Byparr/issues/22) and [#3](https://github.com/ThePhaseless/Byparr/issues/3)
> [!NOTE]
> Thanks to FastAPI implementation, now you can also see the API documentation at `/docs` or `/` (redirect to `/docs`) endpoints.
## Troubleshooting
## Troubleshooting (Docker required)
1. Clone repo to the host that has the container has issues on.
2. Using vscode and `SSH extention`, connect to the host and open repo in it.
3. Download `devcontainers` extention and reopen repo in container (with `CTRL + SHIFT + P` -> `Reopen in devcontainer`)
2. Using vscode and `SSH extension`, connect to the host and open repo in it.
3. Download `Dev Containers` extension and reopen repo in container (with `CTRL + SHIFT + P` -> `Reopen in devcontainer`)
4. Forward port 6080 from devcontainer (port of noVNC server) to the host.
5. Open `http://localhost:6080` and connect to the virtual desktop.
6. Check if `chromium` works by running in VNC's terminal command `chromium --no-sandbox`.
7. If chromium works, run (or debug) tests from VS Code.
1. If code works, congrats! (/s) You are on your own.
2. If it does not, try another host or network, try again and create issue about the problem.
1. If code works, congrats! (not really) You are on your own.
2. If it does not, try on another host or network and create an issue if problem persists.
## Options
| Env | Default | Description |
| -------------- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| `USE_XVFB` | `false` | Use virtual desktop with Xvfb. (Linux only) (Can cause performance hog [#14](https://github.com/ThePhaseless/Byparr/issues/14)) |
| `USE_HEADLESS` | `true/false on docker` | Use headless chromium. |
## Tags
- `v*.*.*`/`latest` - Releases considered stable
- `main` - Latest release from main branch (untested)
## Usage
### Docker Compose
```yaml
services:
byparr:
image: ghcr.io/thephaseless/byparr:latest
environment:
- LOG_LEVEL=INFO # optional
ports:
- "8191:8191" # Optional if needed to make make requests/check docs on host
See `compose.yaml`
### Docker
```bash
docker run -p 8191:8191 ghcr.io/thephaseless/byparr:latest
```
### Local
```bash
uv sync && ./cmd.sh
```
## Need help with / TODO
- [x] Slimming container (only ~650 mB now!)
- [x] Slimming container (only ~650 MB now!)
- [x] Add more anti-bot challenges
- [x] Add docstrings
- [x] Add doc strings
- [x] Implement versioning
- [ ] Proxy support
- [x] Add more architectures support
+1 -1
View File
@@ -1,3 +1,3 @@
#!/bin/sh
. .venv/bin/activate && python3 main.py
uv run main.py
+34 -12
View File
@@ -15,26 +15,27 @@ import src.utils
import src.utils.consts
from src.models.requests import LinkRequest, LinkResponse, Solution
from src.utils import logger
from src.utils.consts import LOG_LEVEL
from src.utils.consts import LOG_LEVEL, USE_HEADLESS, USE_XVFB
app = FastAPI(debug=LOG_LEVEL == logging.DEBUG, log_level=LOG_LEVEL)
cookies = []
@app.get("/")
def read_root():
"""Redirect to /docs."""
logger.info("Redirecting to /docs")
logger.debug("Redirecting to /docs")
return RedirectResponse(url="/docs", status_code=301)
@app.get("/health")
async def health_check():
"""Health check endpoint."""
logger.info("Health check")
health_check_request = read_item(
LinkRequest.model_construct(url="https://prowlarr.servarr.com/v1/ping")
)
if health_check_request.solution.status != HTTPStatus.OK:
raise HTTPException(
status_code=500,
@@ -45,24 +46,40 @@ async def health_check():
@app.post("/v1")
def read_item(request: LinkRequest):
def read_item(request: LinkRequest) -> LinkResponse:
"""Handle POST requests."""
start_time = int(time.time() * 1000)
# request.url = "https://nowsecure.nl"
logger.info(f"Request: {request}")
# Check is string is url
if not (request.url.startswith("http://") or request.url.startswith("https://")):
return LinkResponse.invalid(request.url)
response: LinkResponse
# start_time = int(time.time() * 1000)
try:
with SB(uc=True, locale_code="en", test=False, xvfb=True, ad_block=True) as sb:
with SB(
uc=True,
locale_code="en",
test=False,
ad_block=True,
xvfb=USE_XVFB,
headless=USE_HEADLESS,
) as sb:
try:
sb: BaseCase
global cookies # noqa: PLW0603
if cookies:
sb.uc_open_with_reconnect(request.url)
sb.add_cookies(cookies)
sb.uc_open_with_reconnect(request.url)
source = sb.get_page_source()
source_bs = BeautifulSoup(source, "html.parser")
title_tag = source_bs.title
logger.info(f"Got webpage: {request.url}")
logger.debug(f"Got webpage: {request.url}")
if title_tag and title_tag.string in src.utils.consts.CHALLENGE_TITLES:
logger.info("Challenge detected")
logger.debug("Challenge detected")
sb.uc_gui_click_captcha()
logger.info("Clicked captcha")
@@ -86,9 +103,14 @@ def read_item(request: LinkRequest):
),
startTimestamp=start_time,
)
except Exception as e:
logger.error(f"Error: {e}")
raise HTTPException(status_code=500, detail="Unknown error, check logs") from e
cookies = sb.get_cookies()
except Exception as e:
logger.error(f"Error: {e}")
if sb.driver:
sb.driver.quit()
raise HTTPException(
status_code=500, detail="Unknown error, check logs"
) from e
return response
Generated
-2239
View File
File diff suppressed because it is too large Load Diff
-3
View File
@@ -1,3 +0,0 @@
[virtualenvs]
in-project = true
create = true
+25 -30
View File
@@ -1,38 +1,33 @@
[tool.poetry]
# cspell:disable
[project]
authors = [{ name = "ThePhaseless", email = "kukubaorch@gmail.com" }]
license = { text = "LICENSE" }
requires-python = "<4.0,>=3.12"
name = "Byparr"
version = "0.1.0"
description = "API for getting cookies for Cloudflare challenges"
package-mode = false
authors = ["ThePhaseless <kukubaorch@gmail.com>"]
readme = "README.md"
license = "LICENSE"
repository = "https://github.com/ThePhaseless/Byparr"
dependencies = [
"beautifulsoup4==4.12.3",
"fastapi[standard]==0.115.8",
"psutil==6.1.1",
"pyautogui==0.9.54",
"pydantic==2.10.6",
"seleniumbase==4.34.6",
"uvicorn==0.34.0",
]
urls = { repository = "https://github.com/ThePhaseless/Byparr" }
# cspell:disable
[tool.poetry.dependencies]
python = "^3.12"
fastapi = { extras = ["standard"], version = "^0" }
seleniumbase = "^4.33.1"
beautifulsoup4 = "^4.12.3"
uvicorn = "^0.32.1"
pydantic = "^2.10.2"
pyautogui = "^0.9.54"
[tool.poetry.group.dev.dependencies]
ruff = "^0.8.0"
deptry = "^0.21.1"
[tool.poetry.group.test.dependencies]
pytest = "^8.3.3"
httpx = "^0.27.2"
pytest-retry = "^1.6.3"
pytest-progress = "^1.3.0"
pytest-asyncio = "^0"
pytest-xdist = "^3.6.1"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
[dependency-groups]
test = [
"httpx==0.28.1",
"pytest==8.3.4",
"pytest-asyncio==0.25.3",
"pytest-progress==1.3.0",
"pytest-retry==1.7.0",
"pytest-xdist==3.6.1",
]
dev = ["deptry==0.23.0", "ruff==0.9.4"]
[tool.deptry.per_rule_ignores]
DEP002 = ["pyautogui"]
+18 -7
View File
@@ -6,6 +6,8 @@ from typing import Any
from pydantic import BaseModel, Field
from src.utils import consts
class LinkRequest(BaseModel):
cmd: str = "get"
@@ -26,9 +28,14 @@ class Solution(BaseModel):
response: str
@classmethod
def empty(cls):
def invalid(cls, url: str):
"""
Return an empty Solution with default values.
Useful for returning an error response.
"""
return cls(
url="",
url=url,
status=HTTPStatus.INTERNAL_SERVER_ERROR,
cookies=[],
userAgent="",
@@ -43,19 +50,23 @@ class LinkResponse(BaseModel):
solution: Solution
startTimestamp: int # noqa: N815 # Ignore to preserve compatibility
endTimestamp: int = int(time.time() * 1000) # noqa: N815 # Ignore to preserve compatibility
version: str = "3.3.21" # TODO: Implement versioning
version: str = consts.VERSION
@classmethod
def invalid(cls):
def invalid(cls, url: str):
"""
Return an invalid LinkResponse with default error values.
This method is used to generate a response indicating an invalid request.
"""
return cls(
status="error",
message="Invalid request",
solution=Solution.empty(),
solution=Solution.invalid(url),
startTimestamp=int(time.time() * 1000),
endTimestamp=int(time.time() * 1000),
version="3.3.21",
)
class NoChromeExtensionError(Exception):
"""No chrome extention found."""
"""No chrome extension found."""
+26
View File
@@ -1,9 +1,35 @@
import logging
import os
def get_version_from_env():
"""
Retrieve the version from the environment variable 'VERSION'.
This function checks the 'VERSION' environment variable for a value
that starts with 'v' and returns the version without the prefix.
Returns:
str | None: The version string without the 'v' prefix, or None if
the 'VERSION' environment variable is not set or does not start
with 'v'.
"""
version_env = os.getenv("VERSION")
if not version_env or not version_env.startswith("v"):
return None
return version_env.removeprefix("v")
LOG_LEVEL = os.getenv("LOG_LEVEL") or "INFO"
LOG_LEVEL = logging.getLevelNamesMapping()[LOG_LEVEL.upper()]
VERSION = get_version_from_env() or "unknown"
USE_XVFB = os.getenv("USE_XVFB", "false") in ["true", "1"]
USE_HEADLESS = os.getenv("USE_HEADLESS", "true").lower() in ["true", "1"]
CHALLENGE_TITLES = [
# Cloudflare
"Just a moment...",
Executable
+3
View File
@@ -0,0 +1,3 @@
#!/bin/sh
uv run pytest --retries 2 -n auto
-8
View File
@@ -10,21 +10,13 @@ from src.models.requests import LinkRequest
client = TestClient(app)
test_websites = [
"https://btmet.com/",
"https://ext.to/",
]
# Not testable on github actions
github_restricted = [
"https://www.ygg.re/",
"https://extratorrent.st/",
"https://idope.se/",
"https://speed.cd/login",
]
# if os.getenv("GITHUB_ACTIONS") != "true":
test_websites.extend(github_restricted)
@pytest.mark.parametrize("website", test_websites)
def test_bypass(website: str):
Generated
+1467
View File
File diff suppressed because it is too large Load Diff