]> git.ipfire.org Git - thirdparty/httpx.git/commitdiff
Add top-level API (#75)
authorTom Christie <tom@tomchristie.com>
Mon, 20 May 2019 13:30:52 +0000 (14:30 +0100)
committerGitHub <noreply@github.com>
Mon, 20 May 2019 13:30:52 +0000 (14:30 +0100)
* Add top-level API

* Add tests for top-level API

README.md
httpcore/__init__.py
httpcore/api.py [new file with mode: 0644]
tests/test_api.py [new file with mode: 0644]

index d5333ba77f25b05dbcc5e002537361aeff19a3fd..eda4162f82554d0425b98bc4ff86c9692ea5b04b 100644 (file)
--- a/README.md
+++ b/README.md
@@ -29,7 +29,7 @@ Plus all the standard features of requests...
 * Automatic Decompression
 * Automatic Content Decoding
 * Unicode Response Bodies
-* Multipart File Uploads *TODO - Request content currently supports URL encoded data, bytes, or async byte iterators.*
+* Multipart File Uploads *TODO - Request content currently supports URL encoded data, JSON, bytes, or async byte iterators.*
 * HTTP(S) Proxy Support *TODO*
 * Connection Timeouts
 * Streaming Downloads
index fddb2cff955aa4afa3d18059205fcc7425e3f87f..6d83e16f20b9ea4051bbd7ed1662a64b94657029 100644 (file)
@@ -1,3 +1,4 @@
+from .api import delete, get, head, options, patch, post, put, request
 from .client import AsyncClient, Client
 from .concurrency import AsyncioBackend
 from .config import PoolLimits, SSLConfig, TimeoutConfig
diff --git a/httpcore/api.py b/httpcore/api.py
new file mode 100644 (file)
index 0000000..8e242c7
--- /dev/null
@@ -0,0 +1,236 @@
+import typing
+
+from .client import Client
+from .config import SSLConfig, TimeoutConfig
+from .models import (
+    AuthTypes,
+    CookieTypes,
+    HeaderTypes,
+    QueryParamTypes,
+    RequestData,
+    SyncResponse,
+    URLTypes,
+)
+
+
+def request(
+    method: str,
+    url: URLTypes,
+    *,
+    data: RequestData = b"",
+    json: typing.Any = None,
+    params: QueryParamTypes = None,
+    headers: HeaderTypes = None,
+    cookies: CookieTypes = None,
+    stream: bool = False,
+    auth: AuthTypes = None,
+    allow_redirects: bool = True,
+    ssl: SSLConfig = None,
+    timeout: TimeoutConfig = None,
+) -> SyncResponse:
+    with Client() as client:
+        return client.request(
+            method=method,
+            url=url,
+            data=data,
+            json=json,
+            params=params,
+            headers=headers,
+            cookies=cookies,
+            stream=stream,
+            auth=auth,
+            allow_redirects=allow_redirects,
+            ssl=ssl,
+            timeout=timeout,
+        )
+
+
+def get(
+    url: URLTypes,
+    *,
+    params: QueryParamTypes = None,
+    headers: HeaderTypes = None,
+    cookies: CookieTypes = None,
+    stream: bool = False,
+    auth: AuthTypes = None,
+    allow_redirects: bool = True,
+    ssl: SSLConfig = None,
+    timeout: TimeoutConfig = None,
+) -> SyncResponse:
+    return request(
+        "GET",
+        url,
+        headers=headers,
+        cookies=cookies,
+        stream=stream,
+        auth=auth,
+        allow_redirects=allow_redirects,
+        ssl=ssl,
+        timeout=timeout,
+    )
+
+
+def options(
+    url: URLTypes,
+    *,
+    params: QueryParamTypes = None,
+    headers: HeaderTypes = None,
+    cookies: CookieTypes = None,
+    stream: bool = False,
+    auth: AuthTypes = None,
+    allow_redirects: bool = True,
+    ssl: SSLConfig = None,
+    timeout: TimeoutConfig = None,
+) -> SyncResponse:
+    return request(
+        "OPTIONS",
+        url,
+        headers=headers,
+        cookies=cookies,
+        stream=stream,
+        auth=auth,
+        allow_redirects=allow_redirects,
+        ssl=ssl,
+        timeout=timeout,
+    )
+
+
+def head(
+    url: URLTypes,
+    *,
+    params: QueryParamTypes = None,
+    headers: HeaderTypes = None,
+    cookies: CookieTypes = None,
+    stream: bool = False,
+    auth: AuthTypes = None,
+    allow_redirects: bool = False,  #  Note: Differs to usual default.
+    ssl: SSLConfig = None,
+    timeout: TimeoutConfig = None,
+) -> SyncResponse:
+    return request(
+        "HEAD",
+        url,
+        headers=headers,
+        cookies=cookies,
+        stream=stream,
+        auth=auth,
+        allow_redirects=allow_redirects,
+        ssl=ssl,
+        timeout=timeout,
+    )
+
+
+def post(
+    url: URLTypes,
+    *,
+    data: RequestData = b"",
+    json: typing.Any = None,
+    params: QueryParamTypes = None,
+    headers: HeaderTypes = None,
+    cookies: CookieTypes = None,
+    stream: bool = False,
+    auth: AuthTypes = None,
+    allow_redirects: bool = True,
+    ssl: SSLConfig = None,
+    timeout: TimeoutConfig = None,
+) -> SyncResponse:
+    return request(
+        "POST",
+        url,
+        data=data,
+        json=json,
+        headers=headers,
+        cookies=cookies,
+        stream=stream,
+        auth=auth,
+        allow_redirects=allow_redirects,
+        ssl=ssl,
+        timeout=timeout,
+    )
+
+
+def put(
+    url: URLTypes,
+    *,
+    data: RequestData = b"",
+    json: typing.Any = None,
+    params: QueryParamTypes = None,
+    headers: HeaderTypes = None,
+    cookies: CookieTypes = None,
+    stream: bool = False,
+    auth: AuthTypes = None,
+    allow_redirects: bool = True,
+    ssl: SSLConfig = None,
+    timeout: TimeoutConfig = None,
+) -> SyncResponse:
+    return request(
+        "PUT",
+        url,
+        data=data,
+        json=json,
+        headers=headers,
+        cookies=cookies,
+        stream=stream,
+        auth=auth,
+        allow_redirects=allow_redirects,
+        ssl=ssl,
+        timeout=timeout,
+    )
+
+
+def patch(
+    url: URLTypes,
+    *,
+    data: RequestData = b"",
+    json: typing.Any = None,
+    params: QueryParamTypes = None,
+    headers: HeaderTypes = None,
+    cookies: CookieTypes = None,
+    stream: bool = False,
+    auth: AuthTypes = None,
+    allow_redirects: bool = True,
+    ssl: SSLConfig = None,
+    timeout: TimeoutConfig = None,
+) -> SyncResponse:
+    return request(
+        "PATCH",
+        url,
+        data=data,
+        json=json,
+        headers=headers,
+        cookies=cookies,
+        stream=stream,
+        auth=auth,
+        allow_redirects=allow_redirects,
+        ssl=ssl,
+        timeout=timeout,
+    )
+
+
+def delete(
+    url: URLTypes,
+    *,
+    data: RequestData = b"",
+    json: typing.Any = None,
+    params: QueryParamTypes = None,
+    headers: HeaderTypes = None,
+    cookies: CookieTypes = None,
+    stream: bool = False,
+    auth: AuthTypes = None,
+    allow_redirects: bool = True,
+    ssl: SSLConfig = None,
+    timeout: TimeoutConfig = None,
+) -> SyncResponse:
+    return request(
+        "DELETE",
+        url,
+        data=data,
+        json=json,
+        headers=headers,
+        cookies=cookies,
+        stream=stream,
+        auth=auth,
+        allow_redirects=allow_redirects,
+        ssl=ssl,
+        timeout=timeout,
+    )
diff --git a/tests/test_api.py b/tests/test_api.py
new file mode 100644 (file)
index 0000000..6a62359
--- /dev/null
@@ -0,0 +1,73 @@
+import asyncio
+import functools
+
+import pytest
+
+import httpcore
+
+
+def threadpool(func):
+    """
+    Our sync tests should run in seperate thread to the uvicorn server.
+    """
+
+    @functools.wraps(func)
+    async def wrapped(*args, **kwargs):
+        nonlocal func
+
+        loop = asyncio.get_event_loop()
+        if kwargs:
+            func = functools.partial(func, **kwargs)
+        await loop.run_in_executor(None, func, *args)
+
+    return pytest.mark.asyncio(wrapped)
+
+
+@threadpool
+def test_get(server):
+    response = httpcore.get("http://127.0.0.1:8000/")
+    assert response.status_code == 200
+    assert response.reason_phrase == "OK"
+    assert response.text == "Hello, world!"
+
+
+@threadpool
+def test_post(server):
+    response = httpcore.post("http://127.0.0.1:8000/", data=b"Hello, world!")
+    assert response.status_code == 200
+    assert response.reason_phrase == "OK"
+
+
+@threadpool
+def test_options(server):
+    response = httpcore.options("http://127.0.0.1:8000/")
+    assert response.status_code == 200
+    assert response.reason_phrase == "OK"
+
+
+@threadpool
+def test_head(server):
+    response = httpcore.head("http://127.0.0.1:8000/")
+    assert response.status_code == 200
+    assert response.reason_phrase == "OK"
+
+
+@threadpool
+def test_put(server):
+    response = httpcore.put("http://127.0.0.1:8000/", data=b"Hello, world!")
+    assert response.status_code == 200
+    assert response.reason_phrase == "OK"
+
+
+@threadpool
+def test_patch(server):
+    response = httpcore.patch("http://127.0.0.1:8000/", data=b"Hello, world!")
+    assert response.status_code == 200
+    assert response.reason_phrase == "OK"
+
+
+@threadpool
+def test_delete(server):
+    response = httpcore.delete("http://127.0.0.1:8000/")
+    assert response.status_code == 200
+    assert response.reason_phrase == "OK"