Skip to content

Commit

Permalink
Merge pull request #191 from prkumar/master
Browse files Browse the repository at this point in the history
Release v0.9.1
  • Loading branch information
prkumar authored Feb 8, 2020
2 parents ff72f3f + a6a9bcd commit d0ff443
Show file tree
Hide file tree
Showing 21 changed files with 191 additions and 79 deletions.
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ python:
- '3.4'
- '3.5'
- '3.6'
- '3.6-dev'
- '3.7-dev'
- '3.7'
- '3.8'
before_script:
- pip install tox
- if [[ $TRAVIS_PYTHON_VERSION == 3.6 ]]; then pip install flake8 flake8-bugbear; fi
Expand Down
23 changes: 22 additions & 1 deletion CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,20 @@ All notable changes to this project will be documented in this file.
The format is based on `Keep a Changelog`_, and this project adheres to the
`Semantic Versioning`_ scheme.

0.9.1_ - 2020-02-08
===================
Fixed
-----
- Omit ``Header`` argument from request when its value is ``None``.
(`#167`_, `#169`_)
- Fix ``AttributeError`` raised on usage of ``uplink.Url``.
(`#164`_, `#165`_ by `@cognifloyd`_)

Changed
-------
- Exclude ``tests`` subpackages from wheel.
(`#188`_ by `@daa`_)

0.9.0_ - 2019-06-05
===================
Added
Expand All @@ -29,7 +43,7 @@ Fixed

Changed
-------
- Renamed ``uplink.retry.stop.DISABLE`` to ``uplink.retry.stop.NEVER``
- Rename ``uplink.retry.stop.DISABLE`` to ``uplink.retry.stop.NEVER``

0.8.0_ - 2019-02-16
===================
Expand Down Expand Up @@ -294,6 +308,7 @@ Added
.. _`Semantic Versioning`: https://packaging.python.org/tutorials/distributing-packages/#semantic-versioning-preferred

.. Releases
.. _0.9.1: https://github.com/prkumar/uplink/compare/v0.9.1...HEAD
.. _0.9.0: https://github.com/prkumar/uplink/compare/v0.8.0...v0.9.0
.. _0.8.0: https://github.com/prkumar/uplink/compare/v0.7.0...v0.8.0
.. _0.7.0: https://github.com/prkumar/uplink/compare/v0.6.1...v0.7.0
Expand Down Expand Up @@ -326,10 +341,16 @@ Added
.. _#154: https://github.com/prkumar/uplink/pull/154
.. _#155: https://github.com/prkumar/uplink/pull/155
.. _#159: https://github.com/prkumar/uplink/pull/159
.. _#164: https://github.com/prkumar/uplink/issues/164
.. _#165: https://github.com/prkumar/uplink/pull/165
.. _#167: https://github.com/prkumar/uplink/issues/167
.. _#169: https://github.com/prkumar/uplink/pull/169
.. _#188: https://github.com/prkumar/uplink/pull/188

.. Contributors
.. _@daa: https://github.com/daa
.. _@SakornW: https://github.com/SakornW
.. _@brandonio21: https://github.com/brandonio21
.. _@itstehkman: https://github.com/itstehkman
.. _@kadrach: https://github.com/kadrach
.. _@cognifloyd: https://github.com/cognifloyd
1 change: 0 additions & 1 deletion Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"


[dev-packages]
pre-commit = "*"
tox = "*"
Expand Down
4 changes: 2 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -180,8 +180,8 @@ Want to report a bug, request a feature, or contribute code to Uplink?
Checkout the `Contribution Guide`_ for where to start.
Thank you for taking the time to improve an open source project :purple_heart:

.. |Build Status| image:: https://travis-ci.org/prkumar/uplink.svg?branch=master
:target: https://travis-ci.org/prkumar/uplink
.. |Build Status| image:: https://travis-ci.com/prkumar/uplink.svg?branch=master
:target: https://travis-ci.com/prkumar/uplink
.. |Code Climate| image:: https://api.codeclimate.com/v1/badges/d5c5666134763ff1d6c0/maintainability
:target: https://codeclimate.com/github/prkumar/uplink/maintainability
:alt: Maintainability
Expand Down
15 changes: 9 additions & 6 deletions docs/source/user/quickstart.rst
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,8 @@ Requests for a different backing HTTP client, such as :ref:`aiohttp <sync_vs_asy

.. |aiohttp| replace:: ``aiohttp``

URL Manipulation
================
Path Parameters
===============

Resource endpoints can include `URI template parameters
<https://tools.ietf.org/html/rfc6570>`__ that depend on method
Expand All @@ -139,8 +139,11 @@ or use the :py:class:`~uplink.Path` annotation.
@get("users/{username}")
def get_user(self, name: Path("username")): pass
:py:class:`~uplink.Query` parameters can also be added dynamically
by method arguments.
Query Parameters
================

Query parameters can be added dynamically using the :py:class:`~uplink.Query`
argument annotation.

.. code-block:: python
Expand Down Expand Up @@ -193,8 +196,8 @@ parameters that need to be included with every request:
class GitHub(Consumer):
...
Header Manipulation
===================
Request Headers
===============

You can set static headers for a method using the :py:class:`@headers <uplink.headers>`
decorator.
Expand Down
9 changes: 6 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,13 @@ def read(filename):
"marshmallow": ["marshmallow>=2.15.0"],
"aiohttp:python_version <= '3.4'": [],
"aiohttp:python_version >= '3.4'": "aiohttp>=2.3.0",
"twisted:python_version != '3.3'": "twisted>=17.1.0",
"twisted:python_version != '3.3' and python_version != '3.4'": "twisted>=17.1.0",
# Twisted 18.4.0 dropped py3.3 support
"twisted:python_version == '3.3'": "twisted<=17.9.0",
# Twisted 19.7.0 dropped py3.4 support
"twisted:python_version == '3.4'": "twisted<=19.2.1",
"typing": ["typing>=3.6.4"],
"tests": ["pytest<4.1", "pytest-mock", "pytest-cov", "pytest-twisted"],
"tests": ["pytest==4.6.5", "pytest-mock", "pytest-cov", "pytest-twisted"],
}

metadata = {
Expand All @@ -50,7 +53,7 @@ def read(filename):
"Programming Language :: Python :: Implementation :: PyPy",
],
"keywords": "http api rest client retrofit",
"packages": find_packages(exclude=("tests",)),
"packages": find_packages(exclude=("tests", "tests.*")),
"install_requires": install_requires,
"extras_require": extras_require,
}
Expand Down
13 changes: 13 additions & 0 deletions tests/integration/test_basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ def list_repos(self, user):
def get_repo(self, user, repo):
pass

@uplink.get(args={"url": uplink.Url})
def forward(self, url):
pass


def test_list_repo(mock_client):
github = GitHubService(base_url=BASE_URL, client=mock_client)
Expand Down Expand Up @@ -51,6 +55,15 @@ def test_get_repo(mock_client, mock_response):
assert expected_json == actual_json


def test_forward(mock_client):
github = GitHubService(base_url=BASE_URL, client=mock_client)
github.forward("/users/prkumar/repos")
request = mock_client.history[0]
assert request.method == "GET"
assert request.has_base_url(BASE_URL)
assert request.has_endpoint("/users/prkumar/repos")


def test_handle_client_exceptions(mock_client):
# Setup: mock client exceptions

Expand Down
8 changes: 6 additions & 2 deletions tests/unit/test_arguments.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ def test_modify_request_definition(self, request_definition_builder):

def test_modify_request(self, request_builder):
arguments.Path("name").modify_request(request_builder, "value")
request_builder.url.set_variable.assert_called_with({"name": "value"})
request_builder.set_url_variable.assert_called_with({"name": "value"})


class TestQuery(ArgumentTestCase, FuncDecoratorTestCase):
Expand Down Expand Up @@ -327,6 +327,10 @@ def test_modify_request(self, request_builder):
arguments.Header("hello").modify_request(request_builder, "world")
assert request_builder.info["headers"] == {"hello": "world"}

def test_skip_none(self, request_builder):
arguments.Header("hello").modify_request(request_builder, None)
assert request_builder.info["headers"] == {}


class TestHeaderMap(ArgumentTestCase, FuncDecoratorTestCase):
type_cls = arguments.HeaderMap
Expand Down Expand Up @@ -421,7 +425,7 @@ def test_modify_request_definition_failure(

def test_modify_request(self, request_builder):
arguments.Url().modify_request(request_builder, "/some/path")
assert request_builder.url == "/some/path"
assert request_builder.relative_url == "/some/path"


class TestTimeout(ArgumentTestCase, FuncDecoratorTestCase):
Expand Down
4 changes: 2 additions & 2 deletions tests/unit/test_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def uplink_builder(http_client_mock):
class TestRequestPreparer(object):
def test_prepare_request(self, mocker, request_builder):
request_builder.method = "METHOD"
request_builder.url = "/example/path"
request_builder.relative_url = "/example/path"
request_builder.return_type = None
request_builder.transaction_hooks = ()
request_builder.request_template = "request_template"
Expand All @@ -45,7 +45,7 @@ def test_prepare_request_with_transaction_hook(
self, mocker, uplink_builder, request_builder, transaction_hook_mock
):
request_builder.method = "METHOD"
request_builder.url = "/example/path"
request_builder.relative_url = "/example/path"
request_builder.request_template = "request_template"
uplink_builder.base_url = "https://example.com"
request_builder.transaction_hooks = [transaction_hook_mock]
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/test_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ def test_define_request(self, request_builder, mocker):
)
definition.define_request(request_builder, (), {})
assert request_builder.method == method
assert request_builder.url == uri
assert request_builder.relative_url == uri
assert request_builder.return_type is str

def test_make_converter_registry(self, annotation_handler_mock):
Expand Down
39 changes: 30 additions & 9 deletions tests/unit/test_converters.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,23 +132,42 @@ def __new__(cls, *args, **kwargs):


class TestMarshmallowConverter(object):
for_marshmallow_2_and_3 = pytest.mark.parametrize(
"is_marshmallow_3", [True, False]
)

@staticmethod
def _mock_data(mocker, expected_result, is_marshmallow_3):
"""Mocks the result of Schema.dump() or Schema.load()"""

if is_marshmallow_3:
# After marshmallow 3.0, Schema.load() and Schema.dump() don't
# return a (data, errors) tuple any more. Only `data` is returned.
return expected_result

result = mocker.Mock()
result.data = expected_result
return result

def test_init_without_marshmallow(self):
old_marshmallow = converters.MarshmallowConverter.marshmallow
converters.MarshmallowConverter.marshmallow = None
with pytest.raises(ImportError):
converters.MarshmallowConverter()
converters.MarshmallowConverter.marshmallow = old_marshmallow

@for_marshmallow_2_and_3
def test_create_request_body_converter(
self, mocker, schema_mock_and_argument
self, mocker, schema_mock_and_argument, is_marshmallow_3
):
# Setup
schema_mock, argument = schema_mock_and_argument
expected_result = "data"
dump_result = mocker.Mock()
dump_result.data = expected_result
schema_mock.dump.return_value = dump_result
schema_mock.dump.return_value = self._mock_data(
mocker, expected_result, is_marshmallow_3
)
converter = converters.MarshmallowConverter()
converter.is_marshmallow_3 = is_marshmallow_3
request_body = {"id": 0}

# Run
Expand All @@ -169,16 +188,18 @@ def test_create_request_body_converter_without_schema(self):
# Verify
assert c is None

@for_marshmallow_2_and_3
def test_create_response_body_converter(
self, mocker, schema_mock_and_argument
self, mocker, schema_mock_and_argument, is_marshmallow_3
):
# Setup
schema_mock, argument = schema_mock_and_argument
expected_result = "data"
load_result = mocker.Mock()
load_result.data = expected_result
schema_mock.load.return_value = load_result
schema_mock.load.return_value = self._mock_data(
mocker, expected_result, is_marshmallow_3
)
converter = converters.MarshmallowConverter()
converter.is_marshmallow_3 = is_marshmallow_3
response = mocker.Mock(spec=["json"])
c = converter.create_response_body_converter(argument)

Expand Down Expand Up @@ -235,7 +256,7 @@ def test_create_string_converter(self, schema_mock_and_argument):
# Verify
assert c is None

def test_register(self, mocker):
def test_register(self):
# Setup
converter = converters.MarshmallowConverter
old_marshmallow = converter.marshmallow
Expand Down
22 changes: 22 additions & 0 deletions tests/unit/test_helpers.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import pytest

# Local imports
from uplink import helpers


Expand Down Expand Up @@ -53,3 +56,22 @@ def test_context(self):

# Verify
assert builder.context["key"] == "value"

def test_relative_url_template(self):
# Setup
builder = helpers.RequestBuilder(None, {}, "base_url")

# Run
builder.relative_url = "/v1/api/users/{username}/repos"
builder.set_url_variable({"username": "cognifloyd"})

# Verify
assert builder.relative_url == "/v1/api/users/cognifloyd/repos"

def test_relative_url_template_type_error(self):
# Setup
builder = helpers.RequestBuilder(None, {}, "base_url")

# Run
with pytest.raises(TypeError):
builder.relative_url = 1
2 changes: 1 addition & 1 deletion tests/unit/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,4 @@ def test_remaining_variables(self):
builder = utils.URIBuilder("{variable}")
assert builder.remaining_variables() == set(["variable"])
builder.set_variable(variable="resource")
assert builder.remaining_variables() == set()
assert len(builder.remaining_variables()) == 0
5 changes: 0 additions & 5 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
# Configuration file for Tox, a general virtualenv managment tool.
# Website (June 2016): http://tox.readthedocs.io/en/latest/

[tox]
# These are all "default" test environments provided by Tox.
# They are automatically created upon invoking the "tox" CLI.
envlist = py27, py36

[testenv]
deps = pipenv
commands = pipenv install --skip-lock
Expand Down
2 changes: 1 addition & 1 deletion uplink/__about__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
that is used both in distribution (i.e., setup.py) and within the
codebase.
"""
__version__ = "0.9.0"
__version__ = "0.10.0"
Loading

0 comments on commit d0ff443

Please sign in to comment.