Skip to content

Commit d082d9d

Browse files
committed
Put together first pass of a self contained core service API client.
1 parent f093e2f commit d082d9d

File tree

3 files changed

+139
-1
lines changed

3 files changed

+139
-1
lines changed

mig/lib/coreapi/__init__.py

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import codecs
2+
import json
3+
from urllib.request import Request, urlopen
4+
from urllib.error import HTTPError
5+
6+
from mig.lib.coresvc.payloads import PAYLOAD_POST_USER
7+
8+
9+
def attempt_to_decode_response_data(data, response_encoding=None):
10+
if data is None:
11+
return None
12+
elif response_encoding == 'textual':
13+
data = codecs.decode(data, 'utf8')
14+
15+
try:
16+
return json.loads(data)
17+
except Exception as e:
18+
return data
19+
elif response_encoding == 'binary':
20+
return data
21+
else:
22+
raise AssertionError(
23+
'issue_POST: unknown response_encoding "%s"' % (response_encoding,))
24+
25+
26+
class CoreApiClient:
27+
def __init__(self, base_url):
28+
self._base_url = base_url
29+
30+
def _issue_GET(self, request_path, query_dict=None, response_encoding='textual'):
31+
request_url = ''.join((self._base_url, request_path))
32+
33+
if query_dict is not None:
34+
query_string = urlencode(query_dict)
35+
request_url = ''.join((request_url, '?', query_string))
36+
37+
status = 0
38+
data = None
39+
40+
try:
41+
response = urlopen(request_url, None, timeout=2000)
42+
43+
status = response.getcode()
44+
data = response.read()
45+
except HTTPError as httpexc:
46+
status = httpexc.code
47+
data = None
48+
49+
content = attempt_to_decode_response_data(data, response_encoding)
50+
return (status, content)
51+
52+
def _issue_POST(self, request_path, request_data=None, request_json=None, response_encoding='textual'):
53+
request_url = ''.join((self._base_url, request_path))
54+
55+
if request_data and request_json:
56+
raise ValueError(
57+
"only one of data or json request data may be specified")
58+
59+
status = 0
60+
data = None
61+
62+
try:
63+
if request_json is not None:
64+
request_data = codecs.encode(json.dumps(request_json), 'utf8')
65+
request_headers = {
66+
'Content-Type': 'application/json'
67+
}
68+
request = Request(request_url, request_data,
69+
headers=request_headers)
70+
elif request_data is not None:
71+
request = Request(request_url, request_data)
72+
else:
73+
request = Request(request_url)
74+
75+
response = urlopen(request, timeout=2000)
76+
77+
status = response.getcode()
78+
data = response.read()
79+
except HTTPError as httpexc:
80+
status = httpexc.code
81+
data = httpexc.file.read()
82+
83+
content = attempt_to_decode_response_data(data, response_encoding)
84+
return (status, content)
85+
86+
def createUser(self, user_dict):
87+
payload = PAYLOAD_POST_USER.ensure(user_dict)
88+
89+
return self._issue_POST('/user', request_json=dict(payload))

tests/support/serversupp.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ class ServerWithinThreadExecutor:
4141

4242
def __init__(self, ServerClass, *args, **kwargs):
4343
self._serverclass = ServerClass
44-
self._serverclass_on_instance = kwargs.pop('on_instance')
44+
self._serverclass_on_instance = kwargs.pop('on_instance', None)
4545
self._arguments = (args, kwargs)
4646
self._started = ThreadEvent()
4747
self._thread = None

tests/test_mig_lib_coreapi.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
from http.server import HTTPServer, BaseHTTPRequestHandler
2+
3+
from tests.support import MigTestCase, testmain
4+
from tests.support.serversupp import make_wrapped_server
5+
6+
from mig.lib.coreapi import CoreApiClient
7+
8+
9+
class TestRequestHandler(BaseHTTPRequestHandler):
10+
def do_POST(self):
11+
self.send_response(418)
12+
self.end_headers()
13+
self.wfile.write(b'')
14+
15+
16+
class TestHTTPServer(HTTPServer):
17+
def __init__(self, addr, **kwargs):
18+
self._on_start = kwargs.pop('on_start', lambda _: None)
19+
20+
HTTPServer.__init__(self, addr, TestRequestHandler, **kwargs)
21+
22+
def server_activate(self):
23+
HTTPServer.server_activate(self)
24+
self._on_start(self)
25+
26+
27+
class TestBooleans(MigTestCase):
28+
def test_true(self):
29+
server_addr = ('localhost', 4567)
30+
server = make_wrapped_server(TestHTTPServer, server_addr)
31+
server.start_wait_until_ready()
32+
33+
instance = CoreApiClient("http://%s:%s/" % server_addr)
34+
35+
status, content = instance.createUser({
36+
'full_name': "Test User",
37+
'organization': "Test Org",
38+
'state': "NA",
39+
'country': "DK",
40+
'email': "user@example.com",
41+
'comment': "This is the create comment",
42+
'password': "password",
43+
})
44+
45+
self.assertEqual(status, 418)
46+
47+
48+
if __name__ == '__main__':
49+
testmain()

0 commit comments

Comments
 (0)