Fetch and return a tuple of (headers, content) at `url`. Return content as a text string if `as_text` is True. Otherwise return the content as bytes. If `header_only` is True, return only (headers, None). Headers is a mapping of HTTP headers. Retries multiple times to fetch if
(
url,
as_text=True,
headers_only=False,
headers=None,
_delay=0,
)
| 1904 | |
| 1905 | |
| 1906 | def get_remote_file_content( |
| 1907 | url, |
| 1908 | as_text=True, |
| 1909 | headers_only=False, |
| 1910 | headers=None, |
| 1911 | _delay=0, |
| 1912 | ): |
| 1913 | """ |
| 1914 | Fetch and return a tuple of (headers, content) at `url`. Return content as a |
| 1915 | text string if `as_text` is True. Otherwise return the content as bytes. |
| 1916 | |
| 1917 | If `header_only` is True, return only (headers, None). Headers is a mapping |
| 1918 | of HTTP headers. |
| 1919 | Retries multiple times to fetch if there is a HTTP 429 throttling response |
| 1920 | and this with an increasing delay. |
| 1921 | """ |
| 1922 | time.sleep(_delay) |
| 1923 | headers = headers or {} |
| 1924 | # using a GET with stream=True ensure we get the the final header from |
| 1925 | # several redirects and that we can ignore content there. A HEAD request may |
| 1926 | # not get us this last header |
| 1927 | print(f" DOWNLOADING: {url}") |
| 1928 | with requests.get(url, allow_redirects=True, stream=True, headers=headers) as response: |
| 1929 | status = response.status_code |
| 1930 | if status != requests.codes.ok: # NOQA |
| 1931 | if status == 429 and _delay < 20: |
| 1932 | # too many requests: start some exponential delay |
| 1933 | increased_delay = (_delay * 2) or 1 |
| 1934 | |
| 1935 | return get_remote_file_content( |
| 1936 | url, |
| 1937 | as_text=as_text, |
| 1938 | headers_only=headers_only, |
| 1939 | _delay=increased_delay, |
| 1940 | ) |
| 1941 | |
| 1942 | else: |
| 1943 | raise RemoteNotFetchedException(f"Failed HTTP request from {url} with {status}") |
| 1944 | |
| 1945 | if headers_only: |
| 1946 | return response.headers, None |
| 1947 | |
| 1948 | return response.headers, response.text if as_text else response.content |
| 1949 | |
| 1950 | |
| 1951 | def fetch_and_save( |
no test coverage detected