diff --git a/sendgrid/__init__.py b/sendgrid/__init__.py index cd994dd2..37413b58 100644 --- a/sendgrid/__init__.py +++ b/sendgrid/__init__.py @@ -18,7 +18,6 @@ from .helpers.endpoints import * # noqa from .helpers.mail import * # noqa from .helpers.stats import * # noqa -from .helpers.eventwebhook import * # noqa +from .helpers.eventwebhook import * # noqa from .sendgrid import SendGridAPIClient # noqa from .twilio_email import TwilioEmailAPIClient # noqa -from .version import __version__ diff --git a/sendgrid/base/__init__.py b/sendgrid/base/__init__.py index 5a4589bb..143f486c 100644 --- a/sendgrid/base/__init__.py +++ b/sendgrid/base/__init__.py @@ -1,5 +1 @@ -import os -import platform - # __init__.py - diff --git a/sendgrid/base/auth_strategy.py b/sendgrid/base/auth_strategy.py index 1a443b78..bf23ebdb 100644 --- a/sendgrid/base/auth_strategy.py +++ b/sendgrid/base/auth_strategy.py @@ -1,14 +1,12 @@ - - - # Handle different of authentications, Currently sendgrid authenticate using apikey. +# Handle different of authentications, Currently sendgrid authenticate using apikey. # class AuthStrategy: # def authenticate(self): # print('Not yet implemented') -# -# +# +# # class ApiKeyAuthStrategy(AuthStrategy): # def __init__(self, api_key): # self.api_key = api_key # print('init ApiKeyAuthStrategy') # def authenticate(self, api_key): -# print(f"Authenticating {api_key} using Token Authentication.") \ No newline at end of file +# print(f"Authenticating {api_key} using Token Authentication.") diff --git a/sendgrid/base/client_base.py b/sendgrid/base/client_base.py index 75f45449..387fba9b 100644 --- a/sendgrid/base/client_base.py +++ b/sendgrid/base/client_base.py @@ -1,9 +1,7 @@ class ClientBase: def __init__(self): - print('Creating ClientBase class') + print("Creating ClientBase class") def request(self): - print('Making request') - - \ No newline at end of file + print("Making request") diff --git a/sendgrid/base/url_builder.py b/sendgrid/base/url_builder.py new file mode 100644 index 00000000..49f682a6 --- /dev/null +++ b/sendgrid/base/url_builder.py @@ -0,0 +1,16 @@ +def build_url(url: str, region: str) -> str: + base_url = "https://api.sendgrid.com" + + if region and isinstance(region, str): + new_url = f"https://api.{region}.sendgrid.com" + else: + new_url = base_url + + # Ensure that there's a '/' before appending the url + if not new_url.endswith('/'): + new_url += '/' + + new_url += url.lstrip('/') + + return new_url + diff --git a/sendgrid/client.py b/sendgrid/client.py index b0885f6a..a04ec889 100644 --- a/sendgrid/client.py +++ b/sendgrid/client.py @@ -1,37 +1,33 @@ -import os -import platform -from typing import Dict, List, MutableMapping, Optional, Tuple -from urllib.parse import urlparse, urlunparse -import json +from typing import List, Optional from sendgrid.http.http_client import SendgridHttpClient, HttpClient from sendgrid.http.request import Request - - +from sendgrid.base.url_builder import build_url # class AuthStrategy: # def authenticate(self): # pass -# -# +# +# # class ApiKeyAuthStrategy(AuthStrategy): # def __init__(self, api_key): # self.api_key = api_key -# +# # def authenticate( # self, # headers: Optional[Dict[str, str]] = None # ): # headers["Authorization"] = f"Bearer {self.api_key}" -# +# + class Client: def __init__( - self, - api_key: str, - region: Optional[str] = None, - edge: Optional[str] = None, - http_client: Optional[HttpClient] = None, - user_agent_extensions: Optional[List[str]] = None + self, + api_key: str, + region: Optional[str] = None, + edge: Optional[str] = None, + http_client: Optional[HttpClient] = None, + user_agent_extensions: Optional[List[str]] = None, ): self.api_key = api_key self.region = region @@ -40,7 +36,12 @@ def __init__( self.http_client: SendgridHttpClient = SendgridHttpClient() def send(self, request: Request): + url = build_url(request.url, self.region) response = self.http_client.request( - method='POST', url=request.url, data=request.data, headers=request.headers, api_key=self.api_key + method=request.method, + url=url, + data=request.data, + headers=request.headers, + api_key=self.api_key, ) - return response + return response \ No newline at end of file diff --git a/sendgrid/converters/serialize.py b/sendgrid/converters/serialize.py index 7a5a808b..57e36069 100644 --- a/sendgrid/converters/serialize.py +++ b/sendgrid/converters/serialize.py @@ -5,14 +5,19 @@ def to_serializable(obj): if isinstance(obj, list): - return [to_serializable(item) for item in obj if item is not None] # Remove None from lists + return [ + to_serializable(item) for item in obj if item is not None + ] # Remove None from lists elif isinstance(obj, dict): - return {key: to_serializable(value) for key, value in obj.items() if - value is not None} # Remove None from dicts - elif hasattr(obj, 'to_dict'): + return { + key: to_serializable(value) + for key, value in obj.items() + if value is not None + } # Remove None from dicts + elif hasattr(obj, "to_dict"): return obj.to_dict() elif isinstance(obj, Enum): - return obj.name + return obj.value else: return obj @@ -23,12 +28,16 @@ def from_serializable(data, cls=None): If `cls` is provided, it will instantiate the class using the dictionary values. """ if isinstance(data, list): - return [from_serializable(item, cls) for item in data] # Recursively handle lists + return [ + from_serializable(item, cls) for item in data + ] # Recursively handle lists elif isinstance(data, dict): if cls: # If a class is provided, instantiate it using the dictionary return cls(**{key: from_serializable(value) for key, value in data.items()}) else: - return {key: from_serializable(value) for key, value in data.items()} # Recursively handle dicts + return { + key: from_serializable(value) for key, value in data.items() + } # Recursively handle dicts else: return data # Return primitive types as is diff --git a/sendgrid/http/__init__.py b/sendgrid/http/__init__.py index 504eb219..8b137891 100644 --- a/sendgrid/http/__init__.py +++ b/sendgrid/http/__init__.py @@ -1,5 +1 @@ -from logging import Logger -from typing import Any, Dict, Optional, Tuple -from urllib.parse import urlencode - diff --git a/sendgrid/http/http_client.py b/sendgrid/http/http_client.py index af2e7167..5e802fca 100644 --- a/sendgrid/http/http_client.py +++ b/sendgrid/http/http_client.py @@ -30,15 +30,15 @@ def __init__(self, logger: Logger, is_async: bool, timeout: Optional[float] = No """ def request( - self, - method: str, - uri: str, - params: Optional[Dict[str, object]] = None, - data: Optional[Dict[str, object]] = None, - headers: Optional[Dict[str, str]] = None, - auth: Optional[Tuple[str, str]] = None, - timeout: Optional[float] = None, - allow_redirects: bool = False, + self, + method: str, + uri: str, + params: Optional[Dict[str, object]] = None, + data: Optional[Dict[str, object]] = None, + headers: Optional[Dict[str, str]] = None, + auth: Optional[Tuple[str, str]] = None, + timeout: Optional[float] = None, + allow_redirects: bool = False, ) -> Response: """ Make an HTTP request. @@ -84,15 +84,15 @@ class AsyncHttpClient(HttpClient): """ async def request( - self, - method: str, - uri: str, - params: Optional[Dict[str, object]] = None, - data: Optional[Dict[str, object]] = None, - headers: Optional[Dict[str, str]] = None, - auth: Optional[Tuple[str, str]] = None, - timeout: Optional[float] = None, - allow_redirects: bool = False, + self, + method: str, + uri: str, + params: Optional[Dict[str, object]] = None, + data: Optional[Dict[str, object]] = None, + headers: Optional[Dict[str, str]] = None, + auth: Optional[Tuple[str, str]] = None, + timeout: Optional[float] = None, + allow_redirects: bool = False, ) -> Response: """ Make an asynchronous HTTP request. @@ -106,13 +106,13 @@ class SendgridHttpClient(HttpClient): """ def __init__( - self, - pool_connections: bool = True, - request_hooks: Optional[Dict[str, object]] = None, - timeout: Optional[float] = None, - logger: logging.Logger = _logger, - proxy: Optional[Dict[str, str]] = None, - max_retries: Optional[int] = None, + self, + pool_connections: bool = True, + request_hooks: Optional[Dict[str, object]] = None, + timeout: Optional[float] = None, + logger: logging.Logger = _logger, + proxy: Optional[Dict[str, str]] = None, + max_retries: Optional[int] = None, ): """ Constructor for the TwilioHttpClient @@ -136,20 +136,20 @@ def __init__( self.proxy = proxy if proxy else {} def request( - self, - method: str, - url: str, - api_key: str = None, - params: Optional[Dict[str, object]] = None, - data: Optional[Dict[str, object]] = None, - headers: Optional[Dict[str, str]] = None, - timeout: Optional[float] = None, - allow_redirects: bool = False, + self, + method: str, + url: str, + api_key: str = None, + params: Optional[Dict[str, object]] = None, + data: Optional[Dict[str, object]] = None, + headers: Optional[Dict[str, str]] = None, + timeout: Optional[float] = None, + allow_redirects: bool = False, ) -> Response: """ Make an HTTP Request with parameters provided. - :param api_key: + :param api_key: :param method: The HTTP method to use :param url: The URL to request :param params: Query parameters to append to the URL @@ -167,7 +167,9 @@ def request( raise ValueError(timeout) headers["Authorization"] = f"Bearer {api_key}" - #auth.authenticate() + # Currently supporting 'application/json' content type + headers["Content-Type"] = "application/json" + # auth.authenticate() kwargs = { "method": method.upper(), "url": url, @@ -185,7 +187,7 @@ def request( session = self.session or Session() request = Request(**kwargs) self._test_only_last_request = Request(**kwargs) - + prepped_request = session.prepare_request(request) settings = session.merge_environment_settings( @@ -196,7 +198,7 @@ def request( prepped_request, allow_redirects=allow_redirects, timeout=timeout, - **settings + **settings, ) print(response) print(response.status_code) diff --git a/sendgrid/http/request.py b/sendgrid/http/request.py index 7279243b..d157d2ef 100644 --- a/sendgrid/http/request.py +++ b/sendgrid/http/request.py @@ -9,14 +9,14 @@ class Match(Enum): class Request(object): def __init__( - self, - method: Union[str, Match] = Match.ANY, - url: Union[str, Match] = Match.ANY, - auth: Union[Tuple[str, str], Match] = Match.ANY, - params: Union[Dict[str, str], Match] = Match.ANY, - data: Union[Dict[str, str], Match] = Match.ANY, - headers: Union[Dict[str, str], Match] = Match.ANY, - **kwargs: Any + self, + method: Union[str, Match] = Match.ANY, + url: Union[str, Match] = Match.ANY, + auth: Union[Tuple[str, str], Match] = Match.ANY, + params: Union[Dict[str, str], Match] = Match.ANY, + data: Union[Dict[str, str], Match] = Match.ANY, + headers: Union[Dict[str, str], Match] = Match.ANY, + **kwargs: Any ): self.method = method if method and method is not Match.ANY: @@ -43,12 +43,12 @@ def __eq__(self, other) -> bool: return False return ( - self.attribute_equal(self.method, other.method) - and self.attribute_equal(self.url, other.url) - and self.attribute_equal(self.auth, other.auth) - and self.attribute_equal(self.params, other.params) - and self.attribute_equal(self.data, other.data) - and self.attribute_equal(self.headers, other.headers) + self.attribute_equal(self.method, other.method) + and self.attribute_equal(self.url, other.url) + and self.attribute_equal(self.auth, other.auth) + and self.attribute_equal(self.params, other.params) + and self.attribute_equal(self.data, other.data) + and self.attribute_equal(self.headers, other.headers) ) def __str__(self) -> str: diff --git a/sendgrid/http/response.py b/sendgrid/http/response.py index 8c947516..5cb61a1d 100644 --- a/sendgrid/http/response.py +++ b/sendgrid/http/response.py @@ -9,10 +9,10 @@ class HTTPStatus: class Response(object): def __init__( - self, - status_code: int, - text: str, - headers: Optional[Any] = None, + self, + status_code: int, + text: str, + headers: Optional[Any] = None, ): self.content = text self.headers = headers @@ -32,12 +32,7 @@ def __str__(self) -> str: class ApiResponse(object): - def __init__( - self, - status_code, - model, - headers - ): + def __init__(self, status_code, model, headers): self.status_code = status_code self.model = model self.headers = headers diff --git a/sendgrid/utility/__init__.py b/sendgrid/utility/__init__.py index b423c836..638e153c 100644 --- a/sendgrid/utility/__init__.py +++ b/sendgrid/utility/__init__.py @@ -10,4 +10,3 @@ def parse_response(self, response: Response) -> Any: raise self.exception(response, "Unable to create record") return json.loads(response.text) -