Repository: internetarchive/openlibrary

Issue:
Python 3: Add Cover Image hangs
<!-- What problem are we solving? What does the experience look like today? What are the symptoms? -->

### Evidence / Screenshot (if possible)
http://localhost:8080/works/OL6037022W/Remix?debug=true on Docker Python 3
* Or http://staging.openlibrary.org/works/OL6037022W/Remix?debug=true

Command to launch Open Library on Docker on Python 3:
```
docker-compose down ; \
    PYENV_VERSION=3.9.0 docker-compose -f docker-compose.yml -f docker-compose.infogami-local.yml up -d ; \
    docker-compose logs -f --tail=10 web
```
### Relevant url?
<!-- `https://openlibrary.org/...` -->
1. http://localhost:8080/works/OL6037022W/Remix?debug=true
2. On the image, click Add Cover Image
3. Browse and select an appropriate local image file and click Submit
4. Internal Server Error

### Steps to Reproduce
<!-- What steps caused you to find the bug? -->
1. Go to ...
2. Do ...

<!-- What actually happened after these steps? What did you expect to happen? -->
* Actual: 
* Expected: 

### Details

- **Logged in (Y/N)?** 
- **Browser type/version?** 
- **Operating system?** 
- **Environment (prod/dev/local)?** prod
<!-- If not sure, put prod -->

### Proposal & Constraints
<!-- What is the proposed solution / implementation? Is there a precedent of this approach succeeding elsewhere? -->

### Related files
<!-- Files related to this issue; this is super useful for new contributors who might want to help! If you're not sure, leave this blank; a maintainer will add them. -->

### Stakeholders
<!-- @ tag stakeholders of this bug -->


Discussion:
I am struggling with how to debug this on
http://localhost:8080/books/OL23703735M/Remix/add-cover?debug=true
1. The problem occurs but the debug=true does not provide the internal debugger.
2. The VS Code debugger is not stopping on the breakpoints that I have set.
3. If I use Python `breakpoint()` then `docker-compose up` fails.
4. Looking at the logs inside Docker `cat /var/log/openlibrary/ol-errors/2020-08-12/* | more` provides more heat than light.
5. I was able to use Firefox Debugger Pause on exceptions to get to this but I do not speak JavaScript...

<img width="910" alt="Screenshot 2020-08-12 at 18 04 21" src="https://user-images.githubusercontent.com/3709715/90039298-bbc35f00-dcc6-11ea-8701-d5ee37e73583.png">

```
Traceback (most recent call last):
  File "/home/openlibrary/.pyenv/versions/3.8.5/lib/python3.8/site-packages/web/application.py", line 280, in process
    return self.handle()
  File "/home/openlibrary/.pyenv/versions/3.8.5/lib/python3.8/site-packages/web/application.py", line 271, in handle
    return self._delegate(fn, self.fvars, args)
  File "/home/openlibrary/.pyenv/versions/3.8.5/lib/python3.8/site-packages/web/application.py", line 514, in _delegate
    return handle_class(cls)
  File "/home/openlibrary/.pyenv/versions/3.8.5/lib/python3.8/site-packages/web/application.py", line 492, in handle_class
    return tocall(*args)
  File "/openlibrary/infogami/utils/app.py", line 187, in <lambda>
    HEAD = GET = POST = PUT = DELETE = lambda self: delegate()
  File "/openlibrary/infogami/utils/app.py", line 206, in delegate
    return getattr(cls(), method)(*args)
  File "/openlibrary/openlibrary/plugins/upstream/covers.py", line 36, in POST
    data = self.upload(key, i)
  File "/openlibrary/openlibrary/plugins/upstream/covers.py", line 74, in upload
    response = urllib.request.urlopen(upload_url, urllib.parse.urlencode(params))
  File "/home/openlibrary/.pyenv/versions/3.8.5/lib/python3.8/urllib/request.py", line 222, in urlopen
    return opener.open(url, data, timeout)
  File "/home/openlibrary/.pyenv/versions/3.8.5/lib/python3.8/urllib/request.py", line 522, in open
    req = meth(req)
  File "/home/openlibrary/.pyenv/versions/3.8.5/lib/python3.8/urllib/request.py", line 1281, in do_request_
    raise TypeError(msg)
TypeError: POST data should be bytes, an iterable of bytes, or a file object. It cannot be of type str.
```
Let's try testing this on staging.openlibrary.org to see if it's a blocker for adding web1 to the cluster. This code might by a part of coverstore, which is currently python2. If it is, then it won't break on prod (yet :P )


Resolving patch:
diff --git a/openlibrary/plugins/upstream/covers.py b/openlibrary/plugins/upstream/covers.py
--- a/openlibrary/plugins/upstream/covers.py
+++ b/openlibrary/plugins/upstream/covers.py
@@ -1,7 +1,7 @@
 """Handle book cover/author photo upload.
 """
+import requests
 import web
-import simplejson
 
 from infogami.utils import delegate
 from infogami.utils.view import safeint
@@ -9,8 +9,6 @@
 from openlibrary.plugins.upstream.models import Image
 from openlibrary.plugins.upstream.utils import get_coverstore_url, render_template
 
-from six.moves import urllib
-
 
 def setup():
     pass
@@ -71,12 +69,10 @@ def upload(self, key, i):
             upload_url = "http:" + upload_url
 
         try:
-            response = urllib.request.urlopen(upload_url, urllib.parse.urlencode(params))
-            out = response.read()
-        except urllib.error.HTTPError as e:
-            out = {'error': e.read()}
-
-        return web.storage(simplejson.loads(out))
+            payload = requests.compat.urlencode(params).encode('utf-8')
+            return web.storage(requests.post(upload_url, data=payload).json())
+        except requests.HTTPError as e:
+            return web.storage({'error': e.read()})
 
     def save(self, book, coverid, url=None):
         book.covers = [coverid] + [cover.id for cover in book.get_covers()]


Test patch: