diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..dba8b9e --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "DockerRun.DisableDockerrc": true, + "DockerRun.Containers": [ + "46e215536e7d", + "732a3217f373" + ] +} \ No newline at end of file diff --git a/README.md b/README.md index 61a8722..21fa0aa 100644 --- a/README.md +++ b/README.md @@ -172,3 +172,104 @@ If you'd like to contribute to this project, feel free to fork the repository an - Implement a user-friendly web interface for easier interaction with the API. ----- + +### Branch Martin Updates by https://github.com/TintinSDev + +- Implemented pickachu's twocapthca code to solve 500 server error on gen-proxy +- Added logging, retries and delay for detailed error info on url requests + +``` import logging + def make_request(self, url, method, data=None, headers=None, retries=3, delay=2): + {* Rest of code *} + for attempt in range(retries): + print(f"Attempt {attempt + 1}/{retries}") + if method == 'POST': + captcha_solution = self.solve_captcha() + if captcha_solution: + headers["H-Captcha-Token"] = captcha_solution + response = requests.post(url, headers=headers, json=data) + else: + response = requests.get(url, headers=headers) + + if response.status_code == 500: + print(f"500 Server Error: Retrying {attempt + 1}/{retries}") + time.sleep(delay) + else: + response.raise_for_status() + return response + + print(f"Error making {method} request to {url}: {response.text}") + return None + except requests.exceptions.RequestException as e: + logging.error(f"Error making {method} request to {url}: {e}", exc_info=True) #Error making logger + return None +``` +- Implemented twocapthca api_key purchased and paid. auth_token to be generated by user + ``` + auth_token = "your_api_key_here" #add yout api key generated from cookies as per README instructions + twocaptcha_api_key = "e565f9c19a3eccd58ebc8ee4a32eccc3" + udio_wrapper = UdioWrapper(auth_token, twocaptcha_api_key) + response = udio_wrapper.make_request("https://www.udio.com/api/generate-proxy", "POST") + if response: + print(response.json()) + ``` +- Installed and applied nginx a high performance web server and a reverse proxy server for the generate-proxy error + To access the nginx config file use the following command; +``` + sudo nano /etc/nginx/sites-available/default +``` + The following configuration will be displayed; where the proxy redirects to pyproxy.com +``` + server { + listen 80; + server_name _; + + location /api/generate-proxy { + proxy_pass https://www.pyproxy.com/; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_redirect off; + proxy_buffering off; + proxy_request_buffering off; + client_max_body_size 0; + proxy_read_timeout 3600; + proxy_send_timeout 3600; + proxy_connect_timeout 3600; + add_header Access-Control-Allow-Origin *; + add_header Access-Control-Allow-Methods "GET, POST, OPTIONS"; + add_header Access-Control-Allow-Headers "Content-Type, Authorization"; + + # Added to follow redirects + proxy_intercept_errors on; + error_page 301 302 307 = @handle_redirects; + } + + location @handle_redirects { + set $saved_redirect_location '$upstream_http_location'; + proxy_pass $saved_redirect_location; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + + index index.html index.htm index.nginx-debian.html; + } + +``` +- Make sure to restart the nginx server and also check status server + +``` +sudo systemctl restart nginx +sudo systemctl status nginx +``` +- Check Nginx Logs for proxy related errors +``` + sudo tail -f /var/log/nginx/error.log +``` + diff --git a/requirements.txt b/requirements.txt index 077c95d..b971ed2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1,7 @@ -requests==2.31.0 \ No newline at end of file +requests==2.31.0-i https://pypi.org/simple +certifi==2024.2.2; python_version >= '3.6' +charset-normalizer==3.3.2; python_full_version >= '3.7.0' +idna==3.7; python_version >= '3.5' +pymysql==1.1.0; python_version >= '3.7' +requests==2.31.0; python_version >= '3.7' +urllib3==2.2.1; python_version >= '3.8' diff --git a/udio_wrapper/__init__.py b/udio_wrapper/__init__.py index d4ed8fe..13a2852 100644 --- a/udio_wrapper/__init__.py +++ b/udio_wrapper/__init__.py @@ -9,24 +9,57 @@ import requests import os import time +from twocaptcha import TwoCaptcha +import logging class UdioWrapper: API_BASE_URL = "https://www.udio.com/api" - def __init__(self, auth_token): + def __init__(self, auth_token, twocaptcha_api_key): self.auth_token = auth_token self.all_track_ids = [] + self.solver = TwoCaptcha(twocaptcha_api_key) - def make_request(self, url, method, data=None, headers=None): + def solve_captcha(self): try: - if method == 'POST': - response = requests.post(url, headers=headers, json=data) - else: - response = requests.get(url, headers=headers) - response.raise_for_status() - return response + result = self.solver.hcaptcha( + sitekey='2945592b-1928-43a9-8473-7e7fed3d752e', + url='https://www.udio.com/api/generate-proxy' + ) + return result['code'] + except Exception as e: + print(f"Failed to solve captcha: {e}") + return None + + + def make_request(self, url, method, data=None, headers=None, retries=3, delay=2): + try: + headers = headers or {} + headers["Accept"] = "application/json, text/plain, */*" + headers["Content-Type"] = "application/json" + headers["Cookie"] = f"sb-api-auth-token={self.auth_token}" + + for attempt in range(retries): + print(f"Attempt {attempt + 1}/{retries}") + if method == 'POST': + captcha_solution = self.solve_captcha() + if captcha_solution: + headers["H-Captcha-Token"] = captcha_solution + response = requests.post(url, headers=headers, json=data) + else: + response = requests.get(url, headers=headers) + + if response.status_code == 500: + print(f"500 Server Error: Retrying {attempt + 1}/{retries}") + time.sleep(delay) + else: + response.raise_for_status() + return response + + print(f"Error making {method} request to {url}: {response.text}") + return None except requests.exceptions.RequestException as e: - print(f"Error making {method} request to {url}: {e}") + logging.error(f"Error making {method} request to {url}: {e}", exc_info=True) #Error making logger return None def get_headers(self, get_request=False): @@ -220,3 +253,9 @@ def download_song(self, song_url, song_title, folder="downloaded_songs"): except requests.exceptions.RequestException as e: print(f"Failed to download the song. Error: {e}") +auth_token = "your_api_key_here" #add yout api key generated from cookies as per README instructions +twocaptcha_api_key = "e565f9c19a3eccd58ebc8ee4a32eccc3" +udio_wrapper = UdioWrapper(auth_token, twocaptcha_api_key) +response = udio_wrapper.make_request("https://www.udio.com/api/generate-proxy", "POST") +if response: + print(response.json())