upload code
This commit is contained in:
parent
a0e59b59c0
commit
d3e621ce66
|
@ -0,0 +1,2 @@
|
|||
*.pyc
|
||||
cookies.txt
|
17
README.md
17
README.md
|
@ -1,3 +1,18 @@
|
|||
# huggingface-proxy
|
||||
|
||||
Host a proxy server on Huggingface Spaces
|
||||
_Host a proxy server on Huggingface Spaces._
|
||||
|
||||
### Setup
|
||||
#### Space
|
||||
1. Create a new Space using `./space/Dockerfile`.
|
||||
2. Upload your rathole client config to the space under the path `./rathole-client.toml`
|
||||
3. Upload `./space/server.py` and `./space/supervisord.conf`
|
||||
4. "Factory Reboot" the space to get it to rebuild.
|
||||
|
||||
|
||||
#### Keep Alive
|
||||
On a local machine, run the keep alive script to prevent Huggingface from stopping your space due to "inactivity". You'll have to create a write API key on your account and save your cookies to `cookies.txt`.
|
||||
|
||||
```
|
||||
python3 ./keepalive/keepalive.py --token hf_XXX --username XXX --cookies ./cookies.txt --headless
|
||||
```
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
[Unit]
|
||||
Description=Huggingface Proxy Upkeep Daemon
|
||||
After=network.target
|
||||
StartLimitIntervalSec=0
|
||||
|
||||
[Service]
|
||||
User=server
|
||||
Group=server
|
||||
Type=simple
|
||||
ExecStart=/srv/server/huggingface-proxy/venv/bin/python3 /srv/server/huggingface-proxy/keepalive.py --token hf_XXX --username example --cookies /srv/server/huggingface-proxy/cookies.txt --headless
|
||||
Restart=always
|
||||
RestartSec=3
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
|
@ -0,0 +1,81 @@
|
|||
import argparse
|
||||
import random
|
||||
import time
|
||||
from pathlib import Path
|
||||
|
||||
from huggingface_hub import HfApi
|
||||
from selenium.webdriver.common.by import By
|
||||
from selenium.webdriver.support import expected_conditions as EC
|
||||
from selenium.webdriver.support.ui import WebDriverWait
|
||||
|
||||
from lib.hf import list_spaces, login
|
||||
from lib.webdriver import create_driver, load_cookies, save_cookies
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--cookies", required=True, help="Path to the file containing your HF cookies")
|
||||
parser.add_argument("--token", required=True, help="Your HF API token")
|
||||
parser.add_argument("--username", required=True, help="Your HF username")
|
||||
parser.add_argument("--password", required=True, help="Your HF password")
|
||||
parser.add_argument("--headless", action='store_true', help="Run Selinium in headless mode")
|
||||
args = parser.parse_args()
|
||||
|
||||
cookies_file = Path(args.cookies).resolve().expanduser().absolute()
|
||||
|
||||
login(args.token)
|
||||
|
||||
driver = create_driver(args.headless)
|
||||
|
||||
driver.get(f'https://huggingface.co')
|
||||
if cookies_file.exists():
|
||||
load_cookies(cookies_file)
|
||||
|
||||
driver.get('https://huggingface.co/settings/profile')
|
||||
if driver.current_url != 'https://huggingface.co/settings/profile':
|
||||
print('Not logged in!')
|
||||
username = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.NAME, "username")))
|
||||
username.send_keys(args.username)
|
||||
password = driver.find_element(By.NAME, "password")
|
||||
password.send_keys(args.password)
|
||||
login_button = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, '//button[@type="submit"]')))
|
||||
login_button.click()
|
||||
save_cookies(driver, cookies_file)
|
||||
print('Manually logged in.')
|
||||
else:
|
||||
print('Auth is correct')
|
||||
|
||||
while True:
|
||||
our_spaces = [x.id for x in list_spaces(args.username) if 'proxy' in x.id]
|
||||
random.shuffle(our_spaces)
|
||||
|
||||
driver.get(f'https://huggingface.co')
|
||||
time.sleep(5)
|
||||
for space in our_spaces:
|
||||
print(space)
|
||||
driver.get(f'https://huggingface.co/spaces/{space}')
|
||||
time.sleep(100)
|
||||
|
||||
# try:
|
||||
if len(driver.find_elements(By.ID, 'captcha-container')):
|
||||
print('CAPTCHA!!!')
|
||||
else:
|
||||
for iframe in driver.find_elements(By.TAG_NAME, 'iframe'):
|
||||
src = iframe.get_attribute('src')
|
||||
if 'hf.space' in src and '?__sign' in src:
|
||||
print('Space is online')
|
||||
break
|
||||
else:
|
||||
api = HfApi()
|
||||
try:
|
||||
api.restart_space(repo_id=space)
|
||||
print('Restarted space')
|
||||
except Exception as e:
|
||||
print('Failed to restart space!', e)
|
||||
|
||||
time.sleep(30)
|
||||
|
||||
# Avoid the captcha
|
||||
driver.get('https://huggingface.co')
|
||||
time.sleep(30)
|
||||
sleep_time = 300
|
||||
print(f'Sleeping {sleep_time} seconds...')
|
||||
time.sleep(sleep_time)
|
|
@ -0,0 +1,14 @@
|
|||
from huggingface_hub import login as hf_login
|
||||
from huggingface_hub import HfApi
|
||||
|
||||
|
||||
def login(token: str):
|
||||
return hf_login(token)
|
||||
|
||||
|
||||
def list_spaces(author: str):
|
||||
api = HfApi()
|
||||
result = []
|
||||
for space in api.list_spaces(author=author):
|
||||
result.append(space)
|
||||
return result
|
|
@ -0,0 +1,46 @@
|
|||
import http.cookiejar
|
||||
|
||||
import undetected_chromedriver as uc
|
||||
from selenium.common import InvalidSessionIdException
|
||||
from selenium.webdriver.chrome.options import Options
|
||||
from selenium.webdriver.chrome.webdriver import WebDriver
|
||||
from webdriver_manager.chrome import ChromeDriverManager
|
||||
|
||||
driver: WebDriver = None
|
||||
|
||||
|
||||
def create_driver(headless=False):
|
||||
global driver
|
||||
if driver:
|
||||
try:
|
||||
driver.close()
|
||||
except InvalidSessionIdException:
|
||||
pass
|
||||
|
||||
options = Options()
|
||||
if headless:
|
||||
options.add_argument('--headless')
|
||||
options.add_argument("--window-size=1920,1200")
|
||||
options.add_argument("--incognito")
|
||||
driver = uc.Chrome(driver_executable_path=ChromeDriverManager().install(), options=options, use_subprocess=False)
|
||||
return driver
|
||||
|
||||
|
||||
def load_cookies(file):
|
||||
cookie_jar = http.cookiejar.MozillaCookieJar()
|
||||
cookie_jar.load(file, ignore_discard=True, ignore_expires=True)
|
||||
for cookie in cookie_jar:
|
||||
driver.add_cookie({"name": cookie.name, "value": cookie.value, 'domain': cookie.domain})
|
||||
|
||||
|
||||
def save_cookies(driver, location):
|
||||
with open(location, 'w') as file:
|
||||
file.write('# Netscape HTTP Cookie File\n')
|
||||
for cookie in driver.get_cookies():
|
||||
file.write(f"{cookie['domain']}\t"
|
||||
f"{'TRUE' if cookie['domain'].startswith('.') else 'FALSE'}\t"
|
||||
f"{cookie['path']}\t"
|
||||
f"{'TRUE' if 'secure' in cookie else 'FALSE'}\t"
|
||||
f"{str(int(cookie['expiry'])) if 'expiry' in cookie else '0'}\t"
|
||||
f"{cookie['name']}\t"
|
||||
f"{cookie['value']}\n")
|
|
@ -0,0 +1,5 @@
|
|||
undetected-chromedriver
|
||||
selenium==4.9.1
|
||||
huggingface_hub
|
||||
webdriver_manager
|
||||
pyvirtualdisplay
|
|
@ -0,0 +1,24 @@
|
|||
import argparse
|
||||
import random
|
||||
|
||||
from huggingface_hub import HfApi
|
||||
|
||||
from lib.hf import list_spaces, login
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--token", required=True, help="Your HF API token")
|
||||
parser.add_argument("--username", required=True, help="Your HF username")
|
||||
args = parser.parse_args()
|
||||
|
||||
login(args.token)
|
||||
|
||||
our_spaces = [x.id for x in list_spaces(args.username) if 'proxy' in x.id]
|
||||
random.shuffle(our_spaces)
|
||||
|
||||
for space in our_spaces:
|
||||
api = HfApi()
|
||||
try:
|
||||
api.restart_space(repo_id=space)
|
||||
print(space)
|
||||
except Exception as e:
|
||||
print('Failed to restart space!', e)
|
|
@ -0,0 +1,25 @@
|
|||
FROM debian:stable
|
||||
RUN apt-get update && \
|
||||
apt-get install -y git wget python3 python3-pip unzip && \
|
||||
rm -rf /var/cache/apt/archives /var/lib/apt/lists/*
|
||||
|
||||
RUN mkdir -p /var/log/app
|
||||
|
||||
RUN git clone "https://git.evulid.cc/cyberes/huggingface-proxy.git" /app/huggingface
|
||||
|
||||
COPY ./rathole-client.toml /app/huggingface/rathole-client.toml
|
||||
COPY ./server.py /app/huggingface/space/server.py
|
||||
|
||||
RUN wget https://github.com/rapiz1/rathole/releases/download/v0.5.0/rathole-x86_64-unknown-linux-gnu.zip -O /tmp/rathole.zip
|
||||
RUN unzip /tmp/rathole.zip -d /app
|
||||
|
||||
RUN pip install --break-system-packages supervisor requests flask proxy.py "httpx[http2]"
|
||||
|
||||
RUN adduser --disabled-password --gecos '' --uid 1000 newuser
|
||||
|
||||
RUN chown -R newuser:newuser /app
|
||||
|
||||
EXPOSE 7860
|
||||
USER newuser
|
||||
|
||||
CMD cd /app && /usr/local/bin/supervisord -c /app/huggingface/space/supervisord.conf
|
|
@ -0,0 +1,14 @@
|
|||
import requests
|
||||
from flask import Flask, Response
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
|
||||
@app.route('/')
|
||||
def home():
|
||||
r = requests.get('https://api.ipify.org')
|
||||
return Response(r.text, mimetype='text/plain')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(host="0.0.0.0", port=7860)
|
|
@ -0,0 +1,30 @@
|
|||
[supervisord]
|
||||
nodaemon=true
|
||||
|
||||
[program:rathole]
|
||||
command=/bin/bash -c '/app/rathole -c /app/huggingface/rathole-client.toml 2>&1 | tee -a /app/rathole.log'
|
||||
autostart=true
|
||||
autorestart=true
|
||||
stdout_logfile=/dev/fd/1
|
||||
stdout_logfile_maxbytes=0
|
||||
stderr_logfile=/dev/fd/2
|
||||
stderr_logfile_maxbytes=0
|
||||
|
||||
[program:flask]
|
||||
command=/usr/bin/python3 /app/huggingface/space/server.py
|
||||
autostart=true
|
||||
autorestart=true
|
||||
stdout_logfile=/dev/fd/1
|
||||
stdout_logfile_maxbytes=0
|
||||
stderr_logfile=/dev/fd/2
|
||||
stderr_logfile_maxbytes=0
|
||||
|
||||
[program:proxy]
|
||||
command=proxy --hostname 0.0.0.0 --port 3128 --timeout 300 --plugins proxy.plugin.CloudflareDnsResolverPlugin
|
||||
autostart=true
|
||||
autorestart=true
|
||||
stdout_logfile=/dev/fd/1
|
||||
stdout_logfile_maxbytes=0
|
||||
stderr_logfile=/dev/fd/2
|
||||
stderr_logfile_maxbytes=0
|
||||
environment=PORT=3128
|
Reference in New Issue