Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unasync'ed base dispatchers #742

Closed
wants to merge 2 commits into from
Closed
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ site/
*.egg-info/
venv*/
.python-version
_sync/
5 changes: 5 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@ matrix:
-
stage: check
python: 3.7
before_script: scripts/compile
script: scripts/check
- stage: docs
python: 3.7
before_script: scripts/compile
script: scripts/docs-build
- stage: test
os: windows
Expand All @@ -36,6 +38,7 @@ matrix:
- choco install python --version 3.7
- python -m pip install --upgrade pip
install: pip install -r requirements.txt
before_script: scripts/compile
script: scripts/test

fast_finish: true
Expand All @@ -44,6 +47,8 @@ matrix:
# Some tests not yet resolved for Windows. (In progress)
- os: windows

before_script: scripts/compile

script: scripts/test

after_script:
Expand Down
Empty file added httpx/_async/__init__.py
Empty file.
Empty file.
52 changes: 52 additions & 0 deletions httpx/_async/dispatch/base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import types
import typing

from ...config import Timeout
from ...models import (
HeaderTypes,
QueryParamTypes,
Request,
RequestData,
Response,
URLTypes,
)


class AsyncDispatcher:
"""
Base class for dispatcher classes, that handle sending the request.

Stubs out the interface, as well as providing a `.request()` convenience
implementation, to make it easy to use or test stand-alone dispatchers,
without requiring a complete client instance.
"""

async def request(
self,
method: str,
url: URLTypes,
*,
data: RequestData = b"",
params: QueryParamTypes = None,
headers: HeaderTypes = None,
timeout: Timeout = None,
) -> Response:
request = Request(method, url, data=data, params=params, headers=headers)
return await self.send(request, timeout=timeout)

async def send(self, request: Request, timeout: Timeout = None) -> Response:
raise NotImplementedError() # pragma: nocover

async def close(self) -> None:
pass # pragma: nocover

async def __aenter__(self) -> "AsyncDispatcher":
return self

async def __aexit__(
self,
exc_type: typing.Type[BaseException] = None,
exc_value: BaseException = None,
traceback: types.TracebackType = None,
) -> None:
await self.close()
66 changes: 3 additions & 63 deletions httpx/dispatch/base.py
Original file line number Diff line number Diff line change
@@ -1,64 +1,4 @@
import typing
from types import TracebackType
from .._async.dispatch.base import AsyncDispatcher
from .._sync.dispatch.base import SyncDispatcher

from ..config import Timeout
from ..models import (
HeaderTypes,
QueryParamTypes,
Request,
RequestData,
Response,
URLTypes,
)


class SyncDispatcher:
"""
Base class for Dispatcher classes, that handle sending the request.
"""

def send(self, request: Request, timeout: Timeout = None) -> Response:
raise NotImplementedError() # pragma: nocover

def close(self) -> None:
pass # pragma: nocover


class AsyncDispatcher:
"""
Base class for AsyncDispatcher classes, that handle sending the request.

Stubs out the interface, as well as providing a `.request()` convenience
implementation, to make it easy to use or test stand-alone AsyncDispatchers,
without requiring a complete `AsyncClient` instance.
"""

async def request(
self,
method: str,
url: URLTypes,
*,
data: RequestData = b"",
params: QueryParamTypes = None,
headers: HeaderTypes = None,
timeout: Timeout = None,
) -> Response:
request = Request(method, url, data=data, params=params, headers=headers)
return await self.send(request, timeout=timeout)

async def send(self, request: Request, timeout: Timeout = None) -> Response:
raise NotImplementedError() # pragma: nocover

async def close(self) -> None:
pass # pragma: nocover

async def __aenter__(self) -> "AsyncDispatcher":
return self

async def __aexit__(
self,
exc_type: typing.Type[BaseException] = None,
exc_value: BaseException = None,
traceback: TracebackType = None,
) -> None:
await self.close()
__all__ = ["AsyncDispatcher", "SyncDispatcher"]
7 changes: 7 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[build-system]
requires = [
"setuptools>=40.6.2",
"wheel",
"unasync==0.4.*",
]
build-backend = "setuptools.build_meta"
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ pytest-trio
pytest-cov
trio
trustme
unasync==0.4.*
Copy link
Member Author

@florimondmanca florimondmanca Jan 8, 2020

Choose a reason for hiding this comment

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

That's a bit funny, but listing unasync in the build-system.requires entry doesn't actually install it in a way that's available to the Python interpreter. I don't know when/where those dependencies are installed exactly — probably managed by pip in an opaque location…?

uvicorn
seed-isort-config
wheel

attrs>=19.2 # See: https://github.com/encode/httpx/pull/566#issuecomment-559862665
3 changes: 3 additions & 0 deletions scripts/clean
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
if [ -d 'dist' ] ; then
rm -r dist
fi
if [ -d 'build' ] ; then
rm -r build
fi
if [ -d 'site' ] ; then
rm -r site
fi
Expand Down
16 changes: 16 additions & 0 deletions scripts/compile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/bin/sh -e

export PREFIX=""
if [ -d "venv" ]; then
export PREFIX="venv/bin/"
fi

set -x

scripts/clean

${PREFIX}python setup.py bdist_wheel
rm -rf httpx/_sync
mv build/lib/httpx/_sync httpx

scripts/clean
6 changes: 0 additions & 6 deletions scripts/publish
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,6 @@ if ! command -v "${PREFIX}twine" &>/dev/null ; then
exit 1
fi

if ! ${PREFIX}pip show wheel &>/dev/null ; then
echo "Unable to find the 'wheel' command."
echo "Install from PyPI, using '${PREFIX}pip install wheel'."
exit 1
fi

if ! command -v "${PREFIX}mkdocs" &>/dev/null ; then
echo "Unable to find the 'mkdocs' command."
echo "Install from PyPI, using '${PREFIX}pip install mkdocs'."
Expand Down
2 changes: 2 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import re
from pathlib import Path

import unasync
from setuptools import setup


Expand Down Expand Up @@ -61,6 +62,7 @@ def get_packages(package):
"sniffio==1.*",
"urllib3==1.*",
],
cmdclass={"build_py": unasync.build_py},
classifiers=[
"Development Status :: 3 - Alpha",
"Environment :: Web Environment",
Expand Down