auto close RequestUtils

This commit is contained in:
jxxghp
2025-06-27 08:30:57 +08:00
parent 9555ac6305
commit d8a53da8ee
2 changed files with 132 additions and 49 deletions

View File

@@ -13,6 +13,70 @@ from app.log import logger
urllib3.disable_warnings(InsecureRequestWarning)
class AutoCloseResponse:
"""
自动关闭连接的Response包装器
在访问常用属性后自动关闭连接
"""
def __init__(self, response: Response):
self._response = response
self._closed = False
def __getattr__(self, name):
"""
对于其他属性直接委托给原始response
"""
return getattr(self._response, name)
def _auto_close(self):
"""
自动关闭连接
"""
if not self._closed and self._response:
try:
self._response.close()
self._closed = True
except Exception as e:
logger.debug(f"自动关闭响应失败: {e}")
def json(self, **kwargs):
"""
获取JSON数据并自动关闭连接
"""
try:
data = self._response.json(**kwargs)
return data
finally:
self._auto_close()
@property
def text(self):
"""
获取文本内容并自动关闭连接
"""
try:
return self._response.text
finally:
self._auto_close()
@property
def content(self):
"""
获取二进制内容并自动关闭连接
"""
try:
return self._response.content
finally:
self._auto_close()
def close(self):
"""
手动关闭连接
"""
self._auto_close()
class RequestUtils:
def __init__(self,
@@ -125,7 +189,8 @@ class RequestUtils:
json: dict = None,
allow_redirects: bool = True,
raise_exception: bool = False,
**kwargs) -> Optional[Response]:
auto_close: bool = True,
**kwargs) -> Optional[AutoCloseResponse]:
"""
发送GET请求并返回响应对象
:param url: 请求的URL
@@ -134,18 +199,22 @@ class RequestUtils:
:param json: 请求的JSON数据
:param allow_redirects: 是否允许重定向
:param raise_exception: 是否在发生异常时抛出异常否则默认拦截异常返回None
:param auto_close: 是否自动关闭响应连接None时使用全局配置
:param kwargs: 其他请求参数如headers, cookies, proxies等
:return: HTTP响应对象若发生RequestException则返回None
:raises: requests.exceptions.RequestException 仅raise_exception为True时会抛出
"""
return self.request(method="get",
url=url,
params=params,
data=data,
json=json,
allow_redirects=allow_redirects,
raise_exception=raise_exception,
**kwargs)
response = self.request(method="get",
url=url,
params=params,
data=data,
json=json,
allow_redirects=allow_redirects,
raise_exception=raise_exception,
**kwargs)
if response is not None and auto_close:
return AutoCloseResponse(response)
return response
@contextmanager
def get_stream(self, url: str, params: dict = None, **kwargs):
@@ -171,7 +240,8 @@ class RequestUtils:
files: Any = None,
json: dict = None,
raise_exception: bool = False,
**kwargs) -> Optional[Response]:
auto_close: bool = True,
**kwargs) -> Optional[AutoCloseResponse]:
"""
发送POST请求并返回响应对象
:param url: 请求的URL
@@ -180,20 +250,24 @@ class RequestUtils:
:param allow_redirects: 是否允许重定向
:param files: 请求的文件
:param json: 请求的JSON数据
:param kwargs: 其他请求参数如headers, cookies, proxies等
:param raise_exception: 是否在发生异常时抛出异常否则默认拦截异常返回None
:param auto_close: 是否自动关闭响应连接None时使用全局配置
:param kwargs: 其他请求参数如headers, cookies, proxies等
:return: HTTP响应对象若发生RequestException则返回None
:raises: requests.exceptions.RequestException 仅raise_exception为True时会抛出
"""
return self.request(method="post",
url=url,
data=data,
params=params,
allow_redirects=allow_redirects,
files=files,
json=json,
raise_exception=raise_exception,
**kwargs)
response = self.request(method="post",
url=url,
data=data,
params=params,
allow_redirects=allow_redirects,
files=files,
json=json,
raise_exception=raise_exception,
**kwargs)
if response is not None and auto_close:
return AutoCloseResponse(response)
return response
def put_res(self,
url: str,
@@ -203,7 +277,8 @@ class RequestUtils:
files: Any = None,
json: dict = None,
raise_exception: bool = False,
**kwargs) -> Optional[Response]:
auto_close: bool = True,
**kwargs) -> Optional[AutoCloseResponse]:
"""
发送PUT请求并返回响应对象
:param url: 请求的URL
@@ -213,19 +288,23 @@ class RequestUtils:
:param files: 请求的文件
:param json: 请求的JSON数据
:param raise_exception: 是否在发生异常时抛出异常否则默认拦截异常返回None
:param auto_close: 是否自动关闭响应连接None时使用全局配置
:param kwargs: 其他请求参数如headers, cookies, proxies等
:return: HTTP响应对象若发生RequestException则返回None
:raises: requests.exceptions.RequestException 仅raise_exception为True时会抛出
"""
return self.request(method="put",
url=url,
data=data,
params=params,
allow_redirects=allow_redirects,
files=files,
json=json,
raise_exception=raise_exception,
**kwargs)
response = self.request(method="put",
url=url,
data=data,
params=params,
allow_redirects=allow_redirects,
files=files,
json=json,
raise_exception=raise_exception,
**kwargs)
if response is not None and auto_close:
return AutoCloseResponse(response)
return response
def delete_res(self,
url: str,
@@ -233,7 +312,8 @@ class RequestUtils:
params: dict = None,
allow_redirects: bool = True,
raise_exception: bool = False,
**kwargs) -> Optional[Response]:
auto_close: bool = True,
**kwargs) -> Optional[AutoCloseResponse]:
"""
发送DELETE请求并返回响应对象
:param url: 请求的URL
@@ -241,17 +321,21 @@ class RequestUtils:
:param params: 请求的参数
:param allow_redirects: 是否允许重定向
:param raise_exception: 是否在发生异常时抛出异常否则默认拦截异常返回None
:param auto_close: 是否自动关闭响应连接None时使用全局配置
:param kwargs: 其他请求参数如headers, cookies, proxies等
:return: HTTP响应对象若发生RequestException则返回None
:raises: requests.exceptions.RequestException 仅raise_exception为True时会抛出
"""
return self.request(method="delete",
url=url,
data=data,
params=params,
allow_redirects=allow_redirects,
raise_exception=raise_exception,
**kwargs)
response = self.request(method="delete",
url=url,
data=data,
params=params,
allow_redirects=allow_redirects,
raise_exception=raise_exception,
**kwargs)
if response is not None and auto_close:
return AutoCloseResponse(response)
return response
@staticmethod
def cookie_parse(cookies_str: str, array: bool = False) -> Union[list, dict]: