Skip to content

Commit a14e38a

Browse files
committed
Replaced most cases of using of urlopen(), instead using the higher-level 'requests' module where it simplifies the code.
- Legacy-Id: 17380
1 parent 941a27b commit a14e38a

7 files changed

Lines changed: 33 additions & 51 deletions

File tree

PLAN

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,6 @@ Updated: $Date$
77
Planned work in rough order
88
===========================
99

10-
* Refactor the use of urlopen(). This is triggered by the transition to
11-
python 3: All instances of .read() from urlopen() objects return byte
12-
streams under Python 3, while the code wants to deal with str objects, which
13-
are unicode under Python 3. Instead of building our own adapter to extract
14-
the charset and do the decoding, we should transition to the 'requests'
15-
module, which provides decoded unicode text directly from the response.
16-
1710
* Transition to Django 2.x (depends on Python 3.x). Security updates to
1811
Django 1.11 will cease around April 2020.
1912

ietf/doc/tests_ballot.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -619,10 +619,10 @@ def verify_can_see(username, url):
619619
verify_can_see(username, url)
620620

621621
class ApproveBallotTests(TestCase):
622-
@mock.patch('ietf.sync.rfceditor.urlopen', autospec=True)
622+
@mock.patch('ietf.sync.rfceditor.requests.post', autospec=True)
623623
def test_approve_ballot(self, mock_urlopen):
624-
mock_urlopen.return_value.read = lambda : b'OK'
625-
mock_urlopen.return_value.getcode = lambda :200
624+
mock_urlopen.return_value.text = b'OK'
625+
mock_urlopen.return_value.status_code = 200
626626
#
627627
ad = Person.objects.get(name="Areað Irector")
628628
draft = IndividualDraftFactory(ad=ad, intended_std_level_id='ps')

ietf/doc/tests_draft.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1199,10 +1199,10 @@ def test_confirm_submission(self):
11991199

12001200

12011201
class RequestPublicationTests(TestCase):
1202-
@mock.patch('ietf.sync.rfceditor.urlopen', autospec=True)
1203-
def test_request_publication(self, mock_urlopen):
1204-
mock_urlopen.return_value.read = lambda : b'OK'
1205-
mock_urlopen.return_value.getcode = lambda :200
1202+
@mock.patch('ietf.sync.rfceditor.requests.post', autospec=True)
1203+
def test_request_publication(self, mockobj):
1204+
mockobj.return_value.text = b'OK'
1205+
mockobj.return_value.status_code = 200
12061206
#
12071207
draft = IndividualDraftFactory(stream_id='iab',group__acronym='iab',intended_std_level_id='inf',states=[('draft-stream-iab','approved')])
12081208

ietf/meeting/tests_views.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import datetime
88
import io
9+
import json
910
import os
1011
import random
1112
import re
@@ -436,9 +437,10 @@ def test_proceedings_acknowledgements(self):
436437
response = self.client.get(url)
437438
self.assertContains(response, 'test acknowledgements')
438439

439-
@patch('six.moves.urllib.request.urlopen')
440-
def test_proceedings_attendees(self, mock_urlopen):
441-
mock_urlopen.return_value = six.BytesIO(b'[{"LastName":"Smith","FirstName":"John","Company":"ABC","Country":"US"}]')
440+
@patch('ietf.meeting.utils.requests.get')
441+
def test_proceedings_attendees(self, mockobj):
442+
mockobj.return_value.text = b'[{"LastName":"Smith","FirstName":"John","Company":"ABC","Country":"US"}]'
443+
mockobj.return_value.json = lambda: json.loads(b'[{"LastName":"Smith","FirstName":"John","Company":"ABC","Country":"US"}]')
442444
make_meeting_test_data()
443445
meeting = MeetingFactory(type_id='ietf', date=datetime.date(2016,7,14), number="96")
444446
finalize(meeting)

ietf/meeting/utils.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1-
# Copyright The IETF Trust 2016-2019, All Rights Reserved
1+
# Copyright The IETF Trust 2016-2020, All Rights Reserved
22
# -*- coding: utf-8 -*-
33

44

55
from __future__ import absolute_import, print_function, unicode_literals
66

77
import datetime
8-
import json
9-
import six.moves.urllib.request
8+
import requests
109

1110
from six.moves.urllib.error import HTTPError
1211
from django.conf import settings
@@ -115,7 +114,7 @@ def create_proceedings_templates(meeting):
115114
# Get meeting attendees from registration system
116115
url = settings.STATS_REGISTRATION_ATTENDEES_JSON_URL.format(number=meeting.number)
117116
try:
118-
attendees = json.load(six.moves.urllib.request.urlopen(url))
117+
attendees = requests.get(url).json()
119118
except (ValueError, HTTPError):
120119
attendees = []
121120

ietf/sync/iana.py

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@
99
import email
1010
import json
1111
import re
12-
13-
from six.moves.urllib.request import Request, urlopen
12+
import requests
1413

1514
from django.conf import settings
1615
from django.utils.encoding import smart_bytes, force_str
@@ -23,19 +22,12 @@
2322
from ietf.doc.utils import add_state_change_event
2423
from ietf.person.models import Person
2524
from ietf.utils.mail import parseaddr
26-
from ietf.utils.text import decode
2725
from ietf.utils.timezone import local_timezone_to_utc, email_time_to_local_timezone, utc_to_local_timezone
2826

2927

3028
#PROTOCOLS_URL = "https://www.iana.org/protocols/"
3129
#CHANGES_URL = "https://datatracker.dev.icann.org:8080/data-tracker/changes"
3230

33-
def fetch_protocol_page(url):
34-
f = urlopen(settings.IANA_SYNC_PROTOCOLS_URL)
35-
text = decode(f.read())
36-
f.close()
37-
return text
38-
3931
def parse_protocol_page(text):
4032
"""Parse IANA protocols page to extract referenced RFCs (as
4133
rfcXXXX document names)."""
@@ -75,14 +67,11 @@ def update_rfc_log_from_protocol_page(rfc_names, rfc_must_published_later_than):
7567
def fetch_changes_json(url, start, end):
7668
url += "?start=%s&end=%s" % (urlquote(local_timezone_to_utc(start).strftime("%Y-%m-%d %H:%M:%S")),
7769
urlquote(local_timezone_to_utc(end).strftime("%Y-%m-%d %H:%M:%S")))
78-
request = Request(url)
7970
# HTTP basic auth
8071
username = "ietfsync"
8172
password = settings.IANA_SYNC_PASSWORD
82-
request.add_header("Authorization", "Basic %s" % force_str(base64.encodestring(smart_bytes("%s:%s" % (username, password)))).replace("\n", ""))
83-
f = urlopen(request)
84-
text = decode(f.read())
85-
f.close()
73+
headers = { "Authorization": "Basic %s" % force_str(base64.encodestring(smart_bytes("%s:%s" % (username, password)))).replace("\n", "") }
74+
text = requests.get(url, headers=headers).text
8675
return text
8776

8877
def parse_changes_json(text):

ietf/sync/rfceditor.py

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@
77
import base64
88
import datetime
99
import re
10+
import requests
1011
import six
1112

12-
from six.moves.urllib.request import Request, urlopen
1313
from six.moves.urllib.parse import urlencode
1414
from xml.dom import pulldom, Node
1515

1616
from django.conf import settings
17-
from django.utils.encoding import smart_bytes, force_str
17+
from django.utils.encoding import smart_bytes, force_str, force_text
1818

1919
import debug # pyflakes:ignore
2020

@@ -27,7 +27,6 @@
2727
from ietf.person.models import Person
2828
from ietf.utils.log import log
2929
from ietf.utils.mail import send_mail_text
30-
from ietf.utils.text import decode
3130

3231
#QUEUE_URL = "https://www.rfc-editor.org/queue2.xml"
3332
#INDEX_URL = "https://www.rfc-editor.org/rfc/rfc-index.xml"
@@ -530,28 +529,28 @@ def post_approved_draft(url, name):
530529
the data from the Datatracker and start processing it. Returns
531530
response and error (empty string if no error)."""
532531

533-
request = Request(url)
534-
request.add_header("Content-type", "application/x-www-form-urlencoded")
535-
request.add_header("Accept", "text/plain")
536532
# HTTP basic auth
537533
username = "dtracksync"
538534
password = settings.RFC_EDITOR_SYNC_PASSWORD
539-
request.add_header("Authorization", "Basic %s" % force_str(base64.encodestring(smart_bytes("%s:%s" % (username, password)))).replace("\n", ""))
535+
headers = {
536+
"Content-type": "application/x-www-form-urlencoded",
537+
"Accept": "text/plain",
538+
"Authorization": "Basic %s" % force_str(base64.encodestring(smart_bytes("%s:%s" % (username, password)))).replace("\n", ""),
539+
}
540540

541541
log("Posting RFC-Editor notifcation of approved draft '%s' to '%s'" % (name, url))
542542
text = error = ""
543+
543544
try:
544-
f = urlopen(request, data=smart_bytes(urlencode({ 'draft': name })), timeout=20)
545-
text = decode(f.read())
546-
status_code = f.getcode()
547-
f.close()
548-
log("RFC-Editor notification result for draft '%s': %s:'%s'" % (name, status_code, text))
545+
r = requests.post(url, headers=headers, data=smart_bytes(urlencode({ 'draft': name })), timeout=20)
546+
547+
log("RFC-Editor notification result for draft '%s': %s:'%s'" % (name, r.status_code, r.text))
549548

550-
if status_code != 200:
551-
raise RuntimeError("Status code is not 200 OK (it's %s)." % status_code)
549+
if r.status_code != 200:
550+
raise RuntimeError("Status code is not 200 OK (it's %s)." % r.status_code)
552551

553-
if text != "OK":
554-
raise RuntimeError("Response is not \"OK\".")
552+
if force_text(r.text) != "OK":
553+
raise RuntimeError('Response is not "OK" (it\'s "%s").' % r.text)
555554

556555
except Exception as e:
557556
# catch everything so we don't leak exceptions, convert them

0 commit comments

Comments
 (0)