I'm trying to download a file from Firebase Storage via the Flask app.
The target URL works on browser and when I hardcode it.
However, when I pass the target URL from the frontend as a parameter, it says urllib.error.HTTPError: HTTP Error 403: Forbidden
.
Frontend Code (JavaScript)
async function testTriggerLocalFunction(downloadURL) {
const response = await fetch(
// downloadURL is a string like "https://firebasestorage.googleapis.com...."
"http://127.0.0.1:5001?audioURL=" downloadURL
);
// console.log(response);
}
Backend Code (Flask)
@app.route('/')
def handle_request():
result = analyze(request.args.get("audioURL"))
def analyze(audioURL):
# Download sound file
# url = audioURL
input_name = "input.wav"
input_path = get_file_path(input_name)
# 403 error when audioURL passed from url parameter passed!
urllib.request.urlretrieve(audioURL, input_path)
# But it will work if I do something like "audioURL = "https://firebasestorage.googleapis.com...."
Possible error points
- Maybe you lack proper authorization?
- Maybe you lack a proper header?
- these two seem unlikely because the code works when the URL is hardcoded.
- URL encoding?
- This PHP question has some URL encoding problem but I'm not sure if this applies to me.
What else can be causing this problem?
127.0.0.1 - - [09/Dec/2021 14:08:59] "GET /?audioURL=https://firebasestorage.googleapis.com/MY_TARGET_AUDIO_URL" 500 -
Traceback (most recent call last):
File "/Users/leochoo/.virtualenvs/py-vocal-journal/lib/python3.9/site-packages/flask/app.py", line 2091, in __call__
return self.wsgi_app(environ, start_response)
File "/Users/leochoo/.virtualenvs/py-vocal-journal/lib/python3.9/site-packages/flask/app.py", line 2076, in wsgi_app
response = self.handle_exception(e)
File "/Users/leochoo/.virtualenvs/py-vocal-journal/lib/python3.9/site-packages/flask/app.py", line 2073, in wsgi_app
response = self.full_dispatch_request()
File "/Users/leochoo/.virtualenvs/py-vocal-journal/lib/python3.9/site-packages/flask/app.py", line 1518, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/Users/leochoo/.virtualenvs/py-vocal-journal/lib/python3.9/site-packages/flask/app.py", line 1516, in full_dispatch_request
rv = self.dispatch_request()
File "/Users/leochoo/.virtualenvs/py-vocal-journal/lib/python3.9/site-packages/flask/app.py", line 1502, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
File "/Users/leochoo/dev/vocal-journal/backend/playground/py-vocal-journal/app.py", line 68, in handle_request
result = analyze(request.args.get("audioURL"))
File "/Users/leochoo/dev/vocal-journal/backend/playground/py-vocal-journal/app.py", line 98, in analyze
urllib.request.urlretrieve(audioURL, input_path)
File "/Users/leochoo/.pyenv/versions/3.9.1/lib/python3.9/urllib/request.py", line 239, in urlretrieve
with contextlib.closing(urlopen(url, data)) as fp:
File "/Users/leochoo/.pyenv/versions/3.9.1/lib/python3.9/urllib/request.py", line 214, in urlopen
return opener.open(url, data, timeout)
File "/Users/leochoo/.pyenv/versions/3.9.1/lib/python3.9/urllib/request.py", line 523, in open
response = meth(req, response)
File "/Users/leochoo/.pyenv/versions/3.9.1/lib/python3.9/urllib/request.py", line 632, in http_response
response = self.parent.error(
File "/Users/leochoo/.pyenv/versions/3.9.1/lib/python3.9/urllib/request.py", line 561, in error
return self._call_chain(*args)
File "/Users/leochoo/.pyenv/versions/3.9.1/lib/python3.9/urllib/request.py", line 494, in _call_chain
result = func(*args)
File "/Users/leochoo/.pyenv/versions/3.9.1/lib/python3.9/urllib/request.py", line 641, in http_error_default
raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 403: Forbidden
I look at similar issues, but I could not identify the solution to my situation.
Can't access FireBase Database via HTTP/REST error 403 Forbidden 403 error when passing url as a parameter requests.get returns 403 while the same url works in browser urllib.request.urlretrieve ERROR trying to download jpeg in Python
CodePudding user response:
There are a few ways to do this since the ?audioURL={url} parameter is acting as two parameters since it contains a & symbol:
Combine both query parameters that are being received on the python server code instead of the singular one which you have intended to pass through
Encode the audioURL data variable using base64 on client-side then decode on the server-side to keep the special characters that mess up the query param formatting
Glad to have helped!