Skip to content

Commit

Permalink
Merge pull request #48 from unmade/certifi-for-aiohttp
Browse files Browse the repository at this point in the history
Certifi for aiohttp
  • Loading branch information
unmade authored Mar 10, 2020
2 parents 793e7be + 46eef13 commit 8138f4f
Show file tree
Hide file tree
Showing 9 changed files with 29 additions and 25 deletions.
5 changes: 2 additions & 3 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,9 @@ Installation

.. code-block:: bash
pip install apiwrappers[requests,aiohttp]
pip install 'apiwrappers[aiohttp,requests]'
*Note: extras are optional and mainly needed for the final
user of your future API wrapper*
*Note: extras are mainly needed for the final user of your API client*

QuickStart
==========
Expand Down
4 changes: 2 additions & 2 deletions docs/drivers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,8 @@ SSL Verification
================

You can enable/disable SSL verification or provide custom SSL certs
when creating a driver. Note that default trusted CAs depends on a
driver you're using.
upon driver instantiation. Default CA bundle provided by
`certifi <https://github.com/certifi/python-certifi>`_ library.

By default SSL verification is enabled.

Expand Down
5 changes: 2 additions & 3 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,9 @@ Installation

.. code-block:: bash
pip install apiwrappers[requests,aiohttp]
pip install 'apiwrappers[aiohttp,requests]'
*Note: extras are optional and mainly needed for the final
user of your future API wrapper*
*Note: extras are mainly needed for the final user of your API client*

Getting Started
===============
Expand Down
5 changes: 3 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "apiwrappers"
version = "0.2.0"
version = "0.3.0"
description = "apiwrappers is a library for building API clients that work both with regular and async code"
keywords = ["api", "wrapper", "http", "client"]
readme = "README.rst"
Expand All @@ -22,14 +22,15 @@ classifiers = [
[tool.poetry.dependencies]
python = "^3.7"
aiohttp = {version = "^3.6.2", optional = true}
certifi = {version = ">= 2017.4.17", optional = true}
requests = {version = "^2.22.0", optional = true}
typing-extensions = {version = "^3.7.4", python = "~3.7"}

[tool.poetry.dev-dependencies]
tox = "^3.14.3"

[tool.poetry.extras]
aiohttp = ["aiohttp"]
aiohttp = ["aiohttp", "certifi"]
requests = ["requests"]

[build-system]
Expand Down
3 changes: 2 additions & 1 deletion src/apiwrappers/drivers/aiohttp.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from typing import Iterable, List, Optional, Tuple, Type, Union, cast

import aiohttp
import certifi
from aiohttp import FormData

from apiwrappers import exceptions
Expand Down Expand Up @@ -127,7 +128,7 @@ def _prepare_data(request: Request) -> Optional[Union[Data, FormData]]:

def _prepare_ssl(self) -> SSLContext:
if self.verify is True:
context = ssl.create_default_context()
context = ssl.create_default_context(cafile=certifi.where())
elif self.verify is False:
context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
else:
Expand Down
8 changes: 4 additions & 4 deletions tests/test_drivers/httpbin_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,12 @@ def bearer_auth(self, token):
request = Request(Method.GET, self.url("/bearer"), auth=TokenAuth(token))
return self.driver.fetch(request)

def complex_auth_flow(self):
"""Gets a UUID4 and uses it for bearer authentication."""
def complex_auth_flow(self, token: str):
"""Echoes passed token and uses it for bearer authentication."""

def auth_flow():
response = yield Request(Method.GET, self.url("/uuid"))
return TokenAuth(response.json()["uuid"])()
response = yield Request(Method.POST, self.url("/anything"), data=token)
return TokenAuth(response.json()["data"])()

request = Request(Method.GET, self.url("/bearer"), auth=auth_flow)
return self.driver.fetch(request)
6 changes: 4 additions & 2 deletions tests/test_drivers/httpbin_client.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ class HttpBin(Generic[T]):
@overload
def bearer_auth(self: HttpBin[AsyncDriver], token: str) -> Awaitable[Response]: ...
@overload
def complex_auth_flow(self: HttpBin[Driver]) -> Response: ...
def complex_auth_flow(self: HttpBin[Driver], token: str) -> Response: ...
@overload
def complex_auth_flow(self: HttpBin[AsyncDriver]) -> Awaitable[Response]: ...
def complex_auth_flow(
self: HttpBin[AsyncDriver], token: str
) -> Awaitable[Response]: ...
9 changes: 5 additions & 4 deletions tests/test_drivers/test_aiohttp.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

import json
import ssl
import uuid
from http.cookies import SimpleCookie
from pathlib import Path
from typing import TYPE_CHECKING, Type
Expand Down Expand Up @@ -350,6 +349,8 @@ async def test_token_auth(httpbin) -> None:

async def test_complex_auth_flow(httpbin) -> None:
client = HttpBin(httpbin.url, driver=aiohttp_driver())
response = await client.complex_auth_flow()
assert response.json()["authenticated"] is True # type: ignore
assert uuid.UUID(response.json()["token"]) # type: ignore
response = await client.complex_auth_flow("vF9dft4qmT")
assert response.json() == { # type: ignore
"authenticated": True,
"token": "vF9dft4qmT",
}
9 changes: 5 additions & 4 deletions tests/test_drivers/test_requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

import json
import ssl
import uuid
from http.cookies import SimpleCookie
from pathlib import Path
from typing import TYPE_CHECKING, Type
Expand Down Expand Up @@ -337,6 +336,8 @@ def test_token_auth(httpbin) -> None:

def test_complex_auth_flow(httpbin) -> None:
client = HttpBin(httpbin.url, driver=requests_driver())
response = client.complex_auth_flow()
assert response.json()["authenticated"] is True # type: ignore
assert uuid.UUID(response.json()["token"]) # type: ignore
response = client.complex_auth_flow("vF9dft4qmT")
assert response.json() == { # type: ignore
"authenticated": True,
"token": "vF9dft4qmT",
}

0 comments on commit 8138f4f

Please sign in to comment.