Skip to content

Commit d1eb522

Browse files
Merge branch 'main' into #4-implement-logger
2 parents 41d4c92 + 00c29ea commit d1eb522

File tree

13 files changed

+360
-27
lines changed

13 files changed

+360
-27
lines changed

.vscode/settings.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"python.testing.pytestArgs": [
3+
"tests"
4+
],
5+
"python.testing.unittestEnabled": false,
6+
"python.testing.pytestEnabled": true
7+
}

README.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,16 @@ Simple reusable python resources for digital publishing.
44

55
## Installation
66

7-
**TODO**
7+
Follow these steps to install the package on your local machine:
8+
9+
1. **Install the package**
10+
11+
Open your terminal and run the following command:
12+
13+
```bash
14+
pip install git+https://github.com/GSS-Cogs/dp-python-tools.git
15+
```
16+
817

918
## Usage
1019

dpytools/config/config.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
from typing import Dict
22

3-
from properties.base import BaseProperty
4-
3+
from .properties.base import BaseProperty
54

65
class Config:
76

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
from string import StringProperty
1+
from .string import StringProperty

dpytools/config/properties/base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from typing import Any, Union, Tuple, Optional
44

55
@dataclass
6-
class BaseProperty(meta=ABCMeta):
6+
class BaseProperty(metaclass=ABCMeta):
77
name: str
88
value: Any
99

dpytools/config/properties/string.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from typing import Optional
22

3-
from base import BaseProperty
3+
from .base import BaseProperty
44

55

66
class StringProperty(BaseProperty):

dpytools/http/http.py

Lines changed: 0 additions & 18 deletions
This file was deleted.
File renamed without changes.

dpytools/http_clients/base.py

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import backoff
2+
import requests
3+
from requests.exceptions import HTTPError
4+
import logging
5+
6+
7+
# Function to log retry attempts
8+
def log_retry(details):
9+
logging.error(f"Request failed, retrying... Attempt #{details['tries']}")
10+
11+
12+
class BaseHttpClient:
13+
# Initialize HttpClient with a backoff_max value
14+
def __init__(self, backoff_max=30):
15+
self.backoff_max = backoff_max
16+
17+
# GET request method with exponential backoff
18+
@backoff.on_exception(
19+
backoff.expo,
20+
HTTPError,
21+
max_time=30,
22+
on_backoff=log_retry
23+
)
24+
def get(self, url, *args, **kwargs):
25+
"""
26+
Sends a GET request to the specified URL with optional extra arguments.
27+
28+
This method is a thin wrapper around `requests.get()`. Any additional arguments
29+
are passed directly to `requests.get()`. For more information on the available
30+
arguments, refer to the `requests.get()` documentation:
31+
https://docs.python-requests.org/en/latest/api/#requests.get
32+
33+
Args:
34+
url (str): The URL to send the GET request to.
35+
*args: Optional positional arguments passed to `requests.get()`.
36+
**kwargs: Optional keyword arguments passed to `requests.get()`.
37+
38+
Returns:
39+
Response: The Response object from `requests.get()`.
40+
Raises:
41+
HTTPError: If the request fails for a network-related reason.
42+
"""
43+
return self._handle_request('GET', url, *args, **kwargs)
44+
45+
# POST request method with exponential backoff
46+
@backoff.on_exception(
47+
backoff.expo,
48+
HTTPError,
49+
max_time=30,
50+
on_backoff=log_retry,
51+
)
52+
def post(self, url, *args, **kwargs):
53+
"""
54+
Sends a POST request to the specified URL with optional extra arguments.
55+
56+
This method is a thin wrapper around `requests.post()`. Any additional arguments
57+
are passed directly to `requests.post()`. For more information on the available
58+
arguments, refer to the `requests.post()` documentation:
59+
https://docs.python-requests.org/en/latest/api/#requests.post
60+
61+
Args:
62+
url (str): The URL to send the POST request to.
63+
*args: Optional positional arguments passed to `requests.post()`.
64+
**kwargs: Optional keyword arguments passed to `requests.post()`.
65+
66+
Returns:
67+
Response: The Response object from `requests.post()`.
68+
69+
Raises:
70+
HTTPError: If the request fails for a network-related reason.
71+
"""
72+
return self._handle_request('POST', url, *args, **kwargs)
73+
74+
# Method to handle requests for GET and POST
75+
def _handle_request(self, method, url, *args, **kwargs):
76+
logging.info(f"Sending {method} request to {url}")
77+
try:
78+
response = requests.request(method, url, *args, **kwargs)
79+
response.raise_for_status()
80+
return response
81+
82+
except HTTPError as http_err:
83+
logging.error(f"HTTP error occurred: {http_err} when sending a {method} to {url} with headers {kwargs.get('headers')}")
84+
raise http_err
85+
except Exception as err:
86+
logging.error(f"Other error occurred: {err} when sending a {method} to {url} with headers {kwargs.get('headers')}")
87+
raise err

0 commit comments

Comments
 (0)