Skip to content

Commit d9cdc6c

Browse files
authored
docs: document that path can also be a URL (#2099)
1 parent c283cee commit d9cdc6c

File tree

3 files changed

+32
-7
lines changed

3 files changed

+32
-7
lines changed

dlt/sources/helpers/rest_client/client.py

+8-6
Original file line numberDiff line numberDiff line change
@@ -96,18 +96,18 @@ def __init__(
9696

9797
def _create_request(
9898
self,
99-
path: str,
99+
path_or_url: str,
100100
method: HTTPMethod,
101101
params: Optional[Dict[str, Any]] = None,
102102
json: Optional[Dict[str, Any]] = None,
103103
auth: Optional[AuthBase] = None,
104104
hooks: Optional[Hooks] = None,
105105
) -> Request:
106-
parsed_url = urlparse(path)
106+
parsed_url = urlparse(path_or_url)
107107
if parsed_url.scheme in ("http", "https"):
108-
url = path
108+
url = path_or_url
109109
else:
110-
url = join_url(self.base_url, path)
110+
url = join_url(self.base_url, path_or_url)
111111

112112
return Request(
113113
method=method,
@@ -140,7 +140,7 @@ def _send_request(self, request: Request, **kwargs: Any) -> Response:
140140

141141
def request(self, path: str = "", method: HTTPMethod = "GET", **kwargs: Any) -> Response:
142142
prepared_request = self._create_request(
143-
path=path,
143+
path_or_url=path,
144144
method=method,
145145
params=kwargs.pop("params", None),
146146
json=kwargs.pop("json", None),
@@ -171,6 +171,8 @@ def paginate(
171171
172172
Args:
173173
path (str): Endpoint path for the request, relative to `base_url`.
174+
Can also be a fully qualified URL; if starting with http(s) it will
175+
be used instead of the base_url + path.
174176
method (HTTPMethodBasic): HTTP method for the request, defaults to 'get'.
175177
params (Optional[Dict[str, Any]]): URL parameters for the request.
176178
json (Optional[Dict[str, Any]]): JSON payload for the request.
@@ -210,7 +212,7 @@ def paginate(
210212
hooks["response"] = [raise_for_status]
211213

212214
request = self._create_request(
213-
path=path, method=method, params=params, json=json, auth=auth, hooks=hooks
215+
path_or_url=path, method=method, params=params, json=json, auth=auth, hooks=hooks
214216
)
215217

216218
if paginator:

docs/website/docs/dlt-ecosystem/verified-sources/rest_api/basic.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,8 @@ The endpoint configuration defines how to query the API endpoint. Quick example:
335335

336336
The fields in the endpoint configuration are:
337337

338-
- `path`: The path to the API endpoint.
338+
- `path`: The path to the API endpoint. By default this path is appended to the given `base_url`. If this is a fully qualified URL starting with `http:` or `https:` it will be
339+
used as-is and `base_url` will be ignored.
339340
- `method`: The HTTP method to be used. The default is `GET`.
340341
- `params`: Query parameters to be sent with each request. For example, `sort` to order the results or `since` to specify [incremental loading](#incremental-loading). This is also used to define [resource relationships](#define-resource-relationships).
341342
- `json`: The JSON payload to be sent with the request (for POST and PUT requests).

tests/sources/helpers/rest_client/test_client.py

+22
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from requests import PreparedRequest, Request, Response
88
from requests.auth import AuthBase
99
from requests.exceptions import HTTPError
10+
import requests_mock
1011

1112
from dlt.common import logger
1213
from dlt.common.typing import TSecretStrValue
@@ -512,3 +513,24 @@ def test_request_kwargs(self, mocker) -> None:
512513
"timeout": 432,
513514
"allow_redirects": False,
514515
}
516+
517+
@requests_mock.Mocker(kw="mock")
518+
def test_overwrite_path(self, mocker, **kwargs) -> None:
519+
expected = {"foo": "bar"}
520+
kwargs["mock"].get("https://completely.different/endpoint", json=expected)
521+
rest_client = RESTClient(
522+
base_url="https://api.example.com",
523+
)
524+
response = rest_client.get("https://completely.different/endpoint")
525+
assert response.json() == expected
526+
527+
@requests_mock.Mocker(kw="mock")
528+
def test_overwrite_path_ignores_different_protocol(self, mocker, **kwargs) -> None:
529+
expected = {"foo": "bar"}
530+
base_url = "https://api.example.com"
531+
kwargs["mock"].get(f"{base_url}/my://protocol", json=expected)
532+
rest_client = RESTClient(
533+
base_url=base_url,
534+
)
535+
response = rest_client.get("my://protocol")
536+
assert response.json() == expected

0 commit comments

Comments
 (0)