Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/constants.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
REQUEST_TIMEOUT = 100
CONNECTION_TIMEOUT = 30
BASE_URL = 'https://graph.microsoft.com/v1.0'
SDK_VERSION = 'graph-python-0.0.1'
45 changes: 45 additions & 0 deletions src/core/http_client_factory.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
from requests import Session

from requests_middleware import MiddlewareHTTPAdapter

from src.constants import BASE_URL, SDK_VERSION


class HTTPClientFactory:
@classmethod
def with_graph_middlewares(cls, middlewares):
return _HTTPClient(middlewares=middlewares)


class _HTTPClient(Session):
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_HTTPClient [](start = 6, length = 11)

shouldn't this just be HTTPClient?

Copy link
Contributor Author

@jobala jobala Mar 3, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Python compensates for lack of access modifiers with prefixing private fields/classes with an underscore.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok so your intent here is that everything is always called through the factory and there are no guarantees made that _HTTPClient wouldn't break in some non-compatible way. I see your point but at the same time callers will work directly against this class and it's not completely abstracted in the library so there'd be some back compat expectations.

def __init__(self, **kwargs):
super(_HTTPClient, self).__init__()
self.headers.update({'sdkVersion': SDK_VERSION})
self._base_url = BASE_URL

adapter = MiddlewareHTTPAdapter(kwargs.get('middlewares'))
self.mount('https://', adapter)

def get(self, url, **kwargs):
request_url = self._get_url(url)
super(_HTTPClient, self).get(request_url, **kwargs)

def post(self, url, data=None, json=None, **kwargs):
request_url = self._get_url(url)
super(_HTTPClient, self).post(request_url, data=None, json=None, **kwargs)

def put(self, url, data=None, **kwargs):
request_url = self._get_url(url)
super(_HTTPClient, self).put(request_url, data=None, **kwargs)

def patch(self, url, data=None, **kwargs):
request_url = self._get_url(url)
super(_HTTPClient, self).patch(request_url, data=None, **kwargs)

def delete(self, url, **kwargs):
request_url = self._get_url(url)
super(_HTTPClient, self).delete(request_url, **kwargs)

def _get_url(self, url):
return self._base_url+url if (url[0] == '/') else url

Empty file removed tests/test.py
Empty file.
44 changes: 44 additions & 0 deletions tests/test_http_client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
from unittest import TestCase

from requests import Session
import responses

from src.core.http_client_factory import _HTTPClient
from src.constants import BASE_URL, SDK_VERSION


class HTTPClientTest(TestCase):
def setUp(self) -> None:
self.requests = _HTTPClient()

def tearDown(self) -> None:
self.requests = None

def test_creates_instance_of_session(self):
self.assertIsInstance(self.requests, Session)

def test_has_graph_url_as_base_url(self):
self.assertEqual(self.requests._base_url, BASE_URL)

def test_has_sdk_version_header(self):
self.assertEqual(self.requests.headers.get('sdkVersion'), SDK_VERSION)

@responses.activate
def test_builds_graph_urls(self):
graph_url = BASE_URL+'/me'
responses.add(responses.GET, graph_url, status=200)

self.requests.get('/me')
request_url = responses.calls[0].request.url

self.assertEqual(graph_url, request_url)

@responses.activate
def test_does_not_build_graph_urls_for_full_urls(self):
other_url = 'https://microsoft.com/'
responses.add(responses.GET, other_url, status=200)

self.requests.get(other_url)
request_url = responses.calls[0].request.url

self.assertEqual(other_url, request_url)
24 changes: 24 additions & 0 deletions tests/test_http_client_factory.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from unittest import TestCase

from requests_middleware import BaseMiddleware, MiddlewareHTTPAdapter

from src.core.http_client_factory import HTTPClientFactory


class HTTPClientFactoryTest(TestCase):
def test_initialized_with_middlewares(self):
middlewares = [
BaseMiddleware()
]

requests = HTTPClientFactory.with_graph_middlewares(middlewares)
mocked_middleware = requests.get_adapter('https://')

self.assertIsInstance(mocked_middleware, MiddlewareHTTPAdapter)

def test_created_with_authentication_provider(self):
"""
TODO: Implement create with authentication provider
:return:
"""
pass