summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCoprDistGit <infra@openeuler.org>2023-04-10 16:20:43 +0000
committerCoprDistGit <infra@openeuler.org>2023-04-10 16:20:43 +0000
commit5ccf29a078c41a8cb05a790f39a4df34535db672 (patch)
tree0502dfeee7e6840a7f6d08edaba1c6f4cca91115
parent38e810336e22ef58ec8c2a53b9dd4645361f701a (diff)
automatic import of python-aiohttp-retry
-rw-r--r--.gitignore1
-rw-r--r--python-aiohttp-retry.spec802
-rw-r--r--sources1
3 files changed, 804 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index e69de29..2a384cd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -0,0 +1 @@
+/aiohttp_retry-2.8.3.tar.gz
diff --git a/python-aiohttp-retry.spec b/python-aiohttp-retry.spec
new file mode 100644
index 0000000..5f164eb
--- /dev/null
+++ b/python-aiohttp-retry.spec
@@ -0,0 +1,802 @@
+%global _empty_manifest_terminate_build 0
+Name: python-aiohttp-retry
+Version: 2.8.3
+Release: 1
+Summary: Simple retry client for aiohttp
+License: MIT
+URL: https://github.com/inyutin/aiohttp_retry
+Source0: https://mirrors.nju.edu.cn/pypi/web/packages/01/c1/d57818a0ed5b0313ad8c620638225ddd44094d0d606ee33f3df5105572cd/aiohttp_retry-2.8.3.tar.gz
+BuildArch: noarch
+
+Requires: python3-aiohttp
+
+%description
+# Simple aiohttp retry client
+
+[![codecov](https://codecov.io/gh/inyutin/aiohttp_retry/branch/master/graph/badge.svg?token=ZWGAXSF1SP)](https://codecov.io/gh/inyutin/aiohttp_retry)
+
+Python 3.7 or higher.
+
+**Install**: `pip install aiohttp-retry`.
+
+[!["Buy Me A Coffee"](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/inyutin)
+
+
+### Breaking API changes
+- Everything between [2.7.0 - 2.8.3) is yanked.
+There is a bug with evaluate_response_callback, it led to infinite retries
+
+- 2.8.0 is incorrect and yanked.
+https://github.com/inyutin/aiohttp_retry/issues/79
+
+- Since 2.5.6 this is a new parameter in ```get_timeout``` func called "response".
+If you have defined your own ```RetryOptions```, you should add this param into it.
+Issue about this: https://github.com/inyutin/aiohttp_retry/issues/59
+
+### Examples of usage:
+```python
+from aiohttp_retry import RetryClient, ExponentialRetry
+
+async def main():
+ retry_options = ExponentialRetry(attempts=1)
+ retry_client = RetryClient(raise_for_status=False, retry_options=retry_options)
+ async with retry_client.get('https://ya.ru') as response:
+ print(response.status)
+
+ await retry_client.close()
+```
+
+```python
+from aiohttp import ClientSession
+from aiohttp_retry import RetryClient
+
+async def main():
+ client_session = ClientSession()
+ retry_client = RetryClient(client_session=client_session)
+ async with retry_client.get('https://ya.ru') as response:
+ print(response.status)
+
+ await client_session.close()
+```
+
+```python
+from aiohttp_retry import RetryClient, RandomRetry
+
+async def main():
+ retry_options = RandomRetry(attempts=1)
+ retry_client = RetryClient(raise_for_status=False, retry_options=retry_options)
+
+ response = await retry_client.get('/ping')
+ print(response.status)
+
+ await retry_client.close()
+```
+
+```python
+from aiohttp_retry import RetryClient
+
+async def main():
+ async with RetryClient() as client:
+ async with client.get('https://ya.ru') as response:
+ print(response.status)
+```
+
+You can change parameters between attempts by passing multiple requests params:
+```python
+from aiohttp_retry import RetryClient, RequestParams, ExponentialRetry
+
+async def main():
+ retry_client = RetryClient(raise_for_status=False)
+
+ async with retry_client.requests(
+ params_list=[
+ RequestParams(
+ method='GET',
+ url='https://ya.ru',
+ ),
+ RequestParams(
+ method='GET',
+ url='https://ya.ru',
+ headers={'some_header': 'some_value'},
+ ),
+ ]
+ ) as response:
+ print(response.status)
+
+ await retry_client.close()
+```
+
+You can also add some logic, F.E. logging, on failures by using trace mechanic.
+```python
+import logging
+import sys
+from types import SimpleNamespace
+
+from aiohttp import ClientSession, TraceConfig, TraceRequestStartParams
+
+from aiohttp_retry import RetryClient, ExponentialRetry
+
+
+handler = logging.StreamHandler(sys.stdout)
+logging.basicConfig(handlers=[handler])
+logger = logging.getLogger(__name__)
+retry_options = ExponentialRetry(attempts=2)
+
+
+async def on_request_start(
+ session: ClientSession,
+ trace_config_ctx: SimpleNamespace,
+ params: TraceRequestStartParams,
+) -> None:
+ current_attempt = trace_config_ctx.trace_request_ctx['current_attempt']
+ if retry_options.attempts <= current_attempt:
+ logger.warning('Wow! We are in last attempt')
+
+
+async def main():
+ trace_config = TraceConfig()
+ trace_config.on_request_start.append(on_request_start)
+ retry_client = RetryClient(retry_options=retry_options, trace_configs=[trace_config])
+
+ response = await retry_client.get('https://httpstat.us/503', ssl=False)
+ print(response.status)
+
+ await retry_client.close()
+```
+Look tests for more examples. \
+**Be aware: last request returns as it is.**
+**If the last request ended with exception, that this exception will be raised from RetryClient request**
+
+### Documentation
+`RetryClient` takes the same arguments as ClientSession[[docs](https://docs.aiohttp.org/en/stable/client_reference.html)] \
+`RetryClient` has methods:
+- request
+- get
+- options
+- head
+- post
+- put
+- patch
+- put
+- delete
+
+They are same as for `ClientSession`, but take one possible additional argument:
+```python
+class RetryOptionsBase:
+ def __init__(
+ self,
+ attempts: int = 3, # How many times we should retry
+ statuses: Optional[Iterable[int]] = None, # On which statuses we should retry
+ exceptions: Optional[Iterable[Type[Exception]]] = None, # On which exceptions we should retry
+ retry_all_server_errors: bool = True, # If should retry all 500 errors or not
+ # a callback that will run on response to decide if retry
+ evaluate_response_callback: Optional[EvaluateResponseCallbackType] = None,
+ ):
+ ...
+
+ @abc.abstractmethod
+ def get_timeout(self, attempt: int, response: Optional[Response] = None) -> float:
+ raise NotImplementedError
+
+```
+You can specify `RetryOptions` both for `RetryClient` and it's methods.
+`RetryOptions` in methods override `RetryOptions` defined in `RetryClient` constructor.
+
+**Important**: by default all 5xx responses are retried + statuses you specified as ```statuses``` param
+If you will pass ```retry_all_server_errors=False``` than you can manually set what 5xx errors to retry.
+
+You can define your own timeouts logic or use:
+- ```ExponentialRetry``` with exponential backoff
+- ```RandomRetry``` for random backoff
+- ```ListRetry``` with backoff you predefine by list
+- ```FibonacciRetry``` with backoff that looks like fibonacci sequence
+- ```JitterRetry``` exponential retry with a bit of randomness
+
+**Important**: you can proceed server response as an parameter for calculating next timeout.
+However this response can be None, server didn't make a response or you have set up ```raise_for_status=True```
+Look here for an example: https://github.com/inyutin/aiohttp_retry/issues/59
+
+Additionally, you can specify ```evaluate_response_callback```. It receive a ```ClientResponse``` and decide to retry or not by returning a bool.
+It can be useful, if server API sometimes response with malformed data.
+
+#### Request Trace Context
+`RetryClient` add *current attempt number* to `request_trace_ctx` (see examples,
+for more info see [aiohttp doc](https://docs.aiohttp.org/en/stable/client_advanced.html#aiohttp-client-tracing)).
+
+### Change parameters between retries
+`RetryClient` also has a method called `requests`. This method should be used if you want to make requests with different params.
+```python
+@dataclass
+class RequestParams:
+ method: str
+ url: _RAW_URL_TYPE
+ trace_request_ctx: Optional[Dict[str, Any]] = None
+ kwargs: Optional[Dict[str, Any]] = None
+```
+
+```python
+def requests(
+ self,
+ params_list: List[RequestParams],
+ retry_options: Optional[RetryOptionsBase] = None,
+ raise_for_status: Optional[bool] = None,
+) -> _RequestContext:
+```
+
+You can find an example of usage above or in tests.
+But basically `RequestParams` is a structure to define params for `ClientSession.request` func.
+`method`, `url`, `headers` `trace_request_ctx` defined outside kwargs, because they are popular.
+
+There is also an old way to change URL between retries by specifying ```url``` as list of urls. Example:
+```python
+from aiohttp_retry import RetryClient
+
+retry_client = RetryClient()
+async with retry_client.get(url=['/internal_error', '/ping']) as response:
+ text = await response.text()
+ assert response.status == 200
+ assert text == 'Ok!'
+
+await retry_client.close()
+```
+
+In this example we request ```/interval_error```, fail and then successfully request ```/ping```.
+If you specify less urls than ```attempts``` number in ```RetryOptions```, ```RetryClient``` will request last url at last attempts.
+This means that in example above we would request ```/ping``` once again in case of failure.
+
+### Types
+
+`aiohttp_retry` is a typed project. It should be fully compatablie with mypy.
+
+It also introduce one special type:
+```
+ClientType = Union[ClientSession, RetryClient]
+```
+
+This type can be imported by ```from aiohttp_retry.types import ClientType```
+
+
+%package -n python3-aiohttp-retry
+Summary: Simple retry client for aiohttp
+Provides: python-aiohttp-retry
+BuildRequires: python3-devel
+BuildRequires: python3-setuptools
+BuildRequires: python3-pip
+%description -n python3-aiohttp-retry
+# Simple aiohttp retry client
+
+[![codecov](https://codecov.io/gh/inyutin/aiohttp_retry/branch/master/graph/badge.svg?token=ZWGAXSF1SP)](https://codecov.io/gh/inyutin/aiohttp_retry)
+
+Python 3.7 or higher.
+
+**Install**: `pip install aiohttp-retry`.
+
+[!["Buy Me A Coffee"](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/inyutin)
+
+
+### Breaking API changes
+- Everything between [2.7.0 - 2.8.3) is yanked.
+There is a bug with evaluate_response_callback, it led to infinite retries
+
+- 2.8.0 is incorrect and yanked.
+https://github.com/inyutin/aiohttp_retry/issues/79
+
+- Since 2.5.6 this is a new parameter in ```get_timeout``` func called "response".
+If you have defined your own ```RetryOptions```, you should add this param into it.
+Issue about this: https://github.com/inyutin/aiohttp_retry/issues/59
+
+### Examples of usage:
+```python
+from aiohttp_retry import RetryClient, ExponentialRetry
+
+async def main():
+ retry_options = ExponentialRetry(attempts=1)
+ retry_client = RetryClient(raise_for_status=False, retry_options=retry_options)
+ async with retry_client.get('https://ya.ru') as response:
+ print(response.status)
+
+ await retry_client.close()
+```
+
+```python
+from aiohttp import ClientSession
+from aiohttp_retry import RetryClient
+
+async def main():
+ client_session = ClientSession()
+ retry_client = RetryClient(client_session=client_session)
+ async with retry_client.get('https://ya.ru') as response:
+ print(response.status)
+
+ await client_session.close()
+```
+
+```python
+from aiohttp_retry import RetryClient, RandomRetry
+
+async def main():
+ retry_options = RandomRetry(attempts=1)
+ retry_client = RetryClient(raise_for_status=False, retry_options=retry_options)
+
+ response = await retry_client.get('/ping')
+ print(response.status)
+
+ await retry_client.close()
+```
+
+```python
+from aiohttp_retry import RetryClient
+
+async def main():
+ async with RetryClient() as client:
+ async with client.get('https://ya.ru') as response:
+ print(response.status)
+```
+
+You can change parameters between attempts by passing multiple requests params:
+```python
+from aiohttp_retry import RetryClient, RequestParams, ExponentialRetry
+
+async def main():
+ retry_client = RetryClient(raise_for_status=False)
+
+ async with retry_client.requests(
+ params_list=[
+ RequestParams(
+ method='GET',
+ url='https://ya.ru',
+ ),
+ RequestParams(
+ method='GET',
+ url='https://ya.ru',
+ headers={'some_header': 'some_value'},
+ ),
+ ]
+ ) as response:
+ print(response.status)
+
+ await retry_client.close()
+```
+
+You can also add some logic, F.E. logging, on failures by using trace mechanic.
+```python
+import logging
+import sys
+from types import SimpleNamespace
+
+from aiohttp import ClientSession, TraceConfig, TraceRequestStartParams
+
+from aiohttp_retry import RetryClient, ExponentialRetry
+
+
+handler = logging.StreamHandler(sys.stdout)
+logging.basicConfig(handlers=[handler])
+logger = logging.getLogger(__name__)
+retry_options = ExponentialRetry(attempts=2)
+
+
+async def on_request_start(
+ session: ClientSession,
+ trace_config_ctx: SimpleNamespace,
+ params: TraceRequestStartParams,
+) -> None:
+ current_attempt = trace_config_ctx.trace_request_ctx['current_attempt']
+ if retry_options.attempts <= current_attempt:
+ logger.warning('Wow! We are in last attempt')
+
+
+async def main():
+ trace_config = TraceConfig()
+ trace_config.on_request_start.append(on_request_start)
+ retry_client = RetryClient(retry_options=retry_options, trace_configs=[trace_config])
+
+ response = await retry_client.get('https://httpstat.us/503', ssl=False)
+ print(response.status)
+
+ await retry_client.close()
+```
+Look tests for more examples. \
+**Be aware: last request returns as it is.**
+**If the last request ended with exception, that this exception will be raised from RetryClient request**
+
+### Documentation
+`RetryClient` takes the same arguments as ClientSession[[docs](https://docs.aiohttp.org/en/stable/client_reference.html)] \
+`RetryClient` has methods:
+- request
+- get
+- options
+- head
+- post
+- put
+- patch
+- put
+- delete
+
+They are same as for `ClientSession`, but take one possible additional argument:
+```python
+class RetryOptionsBase:
+ def __init__(
+ self,
+ attempts: int = 3, # How many times we should retry
+ statuses: Optional[Iterable[int]] = None, # On which statuses we should retry
+ exceptions: Optional[Iterable[Type[Exception]]] = None, # On which exceptions we should retry
+ retry_all_server_errors: bool = True, # If should retry all 500 errors or not
+ # a callback that will run on response to decide if retry
+ evaluate_response_callback: Optional[EvaluateResponseCallbackType] = None,
+ ):
+ ...
+
+ @abc.abstractmethod
+ def get_timeout(self, attempt: int, response: Optional[Response] = None) -> float:
+ raise NotImplementedError
+
+```
+You can specify `RetryOptions` both for `RetryClient` and it's methods.
+`RetryOptions` in methods override `RetryOptions` defined in `RetryClient` constructor.
+
+**Important**: by default all 5xx responses are retried + statuses you specified as ```statuses``` param
+If you will pass ```retry_all_server_errors=False``` than you can manually set what 5xx errors to retry.
+
+You can define your own timeouts logic or use:
+- ```ExponentialRetry``` with exponential backoff
+- ```RandomRetry``` for random backoff
+- ```ListRetry``` with backoff you predefine by list
+- ```FibonacciRetry``` with backoff that looks like fibonacci sequence
+- ```JitterRetry``` exponential retry with a bit of randomness
+
+**Important**: you can proceed server response as an parameter for calculating next timeout.
+However this response can be None, server didn't make a response or you have set up ```raise_for_status=True```
+Look here for an example: https://github.com/inyutin/aiohttp_retry/issues/59
+
+Additionally, you can specify ```evaluate_response_callback```. It receive a ```ClientResponse``` and decide to retry or not by returning a bool.
+It can be useful, if server API sometimes response with malformed data.
+
+#### Request Trace Context
+`RetryClient` add *current attempt number* to `request_trace_ctx` (see examples,
+for more info see [aiohttp doc](https://docs.aiohttp.org/en/stable/client_advanced.html#aiohttp-client-tracing)).
+
+### Change parameters between retries
+`RetryClient` also has a method called `requests`. This method should be used if you want to make requests with different params.
+```python
+@dataclass
+class RequestParams:
+ method: str
+ url: _RAW_URL_TYPE
+ trace_request_ctx: Optional[Dict[str, Any]] = None
+ kwargs: Optional[Dict[str, Any]] = None
+```
+
+```python
+def requests(
+ self,
+ params_list: List[RequestParams],
+ retry_options: Optional[RetryOptionsBase] = None,
+ raise_for_status: Optional[bool] = None,
+) -> _RequestContext:
+```
+
+You can find an example of usage above or in tests.
+But basically `RequestParams` is a structure to define params for `ClientSession.request` func.
+`method`, `url`, `headers` `trace_request_ctx` defined outside kwargs, because they are popular.
+
+There is also an old way to change URL between retries by specifying ```url``` as list of urls. Example:
+```python
+from aiohttp_retry import RetryClient
+
+retry_client = RetryClient()
+async with retry_client.get(url=['/internal_error', '/ping']) as response:
+ text = await response.text()
+ assert response.status == 200
+ assert text == 'Ok!'
+
+await retry_client.close()
+```
+
+In this example we request ```/interval_error```, fail and then successfully request ```/ping```.
+If you specify less urls than ```attempts``` number in ```RetryOptions```, ```RetryClient``` will request last url at last attempts.
+This means that in example above we would request ```/ping``` once again in case of failure.
+
+### Types
+
+`aiohttp_retry` is a typed project. It should be fully compatablie with mypy.
+
+It also introduce one special type:
+```
+ClientType = Union[ClientSession, RetryClient]
+```
+
+This type can be imported by ```from aiohttp_retry.types import ClientType```
+
+
+%package help
+Summary: Development documents and examples for aiohttp-retry
+Provides: python3-aiohttp-retry-doc
+%description help
+# Simple aiohttp retry client
+
+[![codecov](https://codecov.io/gh/inyutin/aiohttp_retry/branch/master/graph/badge.svg?token=ZWGAXSF1SP)](https://codecov.io/gh/inyutin/aiohttp_retry)
+
+Python 3.7 or higher.
+
+**Install**: `pip install aiohttp-retry`.
+
+[!["Buy Me A Coffee"](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/inyutin)
+
+
+### Breaking API changes
+- Everything between [2.7.0 - 2.8.3) is yanked.
+There is a bug with evaluate_response_callback, it led to infinite retries
+
+- 2.8.0 is incorrect and yanked.
+https://github.com/inyutin/aiohttp_retry/issues/79
+
+- Since 2.5.6 this is a new parameter in ```get_timeout``` func called "response".
+If you have defined your own ```RetryOptions```, you should add this param into it.
+Issue about this: https://github.com/inyutin/aiohttp_retry/issues/59
+
+### Examples of usage:
+```python
+from aiohttp_retry import RetryClient, ExponentialRetry
+
+async def main():
+ retry_options = ExponentialRetry(attempts=1)
+ retry_client = RetryClient(raise_for_status=False, retry_options=retry_options)
+ async with retry_client.get('https://ya.ru') as response:
+ print(response.status)
+
+ await retry_client.close()
+```
+
+```python
+from aiohttp import ClientSession
+from aiohttp_retry import RetryClient
+
+async def main():
+ client_session = ClientSession()
+ retry_client = RetryClient(client_session=client_session)
+ async with retry_client.get('https://ya.ru') as response:
+ print(response.status)
+
+ await client_session.close()
+```
+
+```python
+from aiohttp_retry import RetryClient, RandomRetry
+
+async def main():
+ retry_options = RandomRetry(attempts=1)
+ retry_client = RetryClient(raise_for_status=False, retry_options=retry_options)
+
+ response = await retry_client.get('/ping')
+ print(response.status)
+
+ await retry_client.close()
+```
+
+```python
+from aiohttp_retry import RetryClient
+
+async def main():
+ async with RetryClient() as client:
+ async with client.get('https://ya.ru') as response:
+ print(response.status)
+```
+
+You can change parameters between attempts by passing multiple requests params:
+```python
+from aiohttp_retry import RetryClient, RequestParams, ExponentialRetry
+
+async def main():
+ retry_client = RetryClient(raise_for_status=False)
+
+ async with retry_client.requests(
+ params_list=[
+ RequestParams(
+ method='GET',
+ url='https://ya.ru',
+ ),
+ RequestParams(
+ method='GET',
+ url='https://ya.ru',
+ headers={'some_header': 'some_value'},
+ ),
+ ]
+ ) as response:
+ print(response.status)
+
+ await retry_client.close()
+```
+
+You can also add some logic, F.E. logging, on failures by using trace mechanic.
+```python
+import logging
+import sys
+from types import SimpleNamespace
+
+from aiohttp import ClientSession, TraceConfig, TraceRequestStartParams
+
+from aiohttp_retry import RetryClient, ExponentialRetry
+
+
+handler = logging.StreamHandler(sys.stdout)
+logging.basicConfig(handlers=[handler])
+logger = logging.getLogger(__name__)
+retry_options = ExponentialRetry(attempts=2)
+
+
+async def on_request_start(
+ session: ClientSession,
+ trace_config_ctx: SimpleNamespace,
+ params: TraceRequestStartParams,
+) -> None:
+ current_attempt = trace_config_ctx.trace_request_ctx['current_attempt']
+ if retry_options.attempts <= current_attempt:
+ logger.warning('Wow! We are in last attempt')
+
+
+async def main():
+ trace_config = TraceConfig()
+ trace_config.on_request_start.append(on_request_start)
+ retry_client = RetryClient(retry_options=retry_options, trace_configs=[trace_config])
+
+ response = await retry_client.get('https://httpstat.us/503', ssl=False)
+ print(response.status)
+
+ await retry_client.close()
+```
+Look tests for more examples. \
+**Be aware: last request returns as it is.**
+**If the last request ended with exception, that this exception will be raised from RetryClient request**
+
+### Documentation
+`RetryClient` takes the same arguments as ClientSession[[docs](https://docs.aiohttp.org/en/stable/client_reference.html)] \
+`RetryClient` has methods:
+- request
+- get
+- options
+- head
+- post
+- put
+- patch
+- put
+- delete
+
+They are same as for `ClientSession`, but take one possible additional argument:
+```python
+class RetryOptionsBase:
+ def __init__(
+ self,
+ attempts: int = 3, # How many times we should retry
+ statuses: Optional[Iterable[int]] = None, # On which statuses we should retry
+ exceptions: Optional[Iterable[Type[Exception]]] = None, # On which exceptions we should retry
+ retry_all_server_errors: bool = True, # If should retry all 500 errors or not
+ # a callback that will run on response to decide if retry
+ evaluate_response_callback: Optional[EvaluateResponseCallbackType] = None,
+ ):
+ ...
+
+ @abc.abstractmethod
+ def get_timeout(self, attempt: int, response: Optional[Response] = None) -> float:
+ raise NotImplementedError
+
+```
+You can specify `RetryOptions` both for `RetryClient` and it's methods.
+`RetryOptions` in methods override `RetryOptions` defined in `RetryClient` constructor.
+
+**Important**: by default all 5xx responses are retried + statuses you specified as ```statuses``` param
+If you will pass ```retry_all_server_errors=False``` than you can manually set what 5xx errors to retry.
+
+You can define your own timeouts logic or use:
+- ```ExponentialRetry``` with exponential backoff
+- ```RandomRetry``` for random backoff
+- ```ListRetry``` with backoff you predefine by list
+- ```FibonacciRetry``` with backoff that looks like fibonacci sequence
+- ```JitterRetry``` exponential retry with a bit of randomness
+
+**Important**: you can proceed server response as an parameter for calculating next timeout.
+However this response can be None, server didn't make a response or you have set up ```raise_for_status=True```
+Look here for an example: https://github.com/inyutin/aiohttp_retry/issues/59
+
+Additionally, you can specify ```evaluate_response_callback```. It receive a ```ClientResponse``` and decide to retry or not by returning a bool.
+It can be useful, if server API sometimes response with malformed data.
+
+#### Request Trace Context
+`RetryClient` add *current attempt number* to `request_trace_ctx` (see examples,
+for more info see [aiohttp doc](https://docs.aiohttp.org/en/stable/client_advanced.html#aiohttp-client-tracing)).
+
+### Change parameters between retries
+`RetryClient` also has a method called `requests`. This method should be used if you want to make requests with different params.
+```python
+@dataclass
+class RequestParams:
+ method: str
+ url: _RAW_URL_TYPE
+ trace_request_ctx: Optional[Dict[str, Any]] = None
+ kwargs: Optional[Dict[str, Any]] = None
+```
+
+```python
+def requests(
+ self,
+ params_list: List[RequestParams],
+ retry_options: Optional[RetryOptionsBase] = None,
+ raise_for_status: Optional[bool] = None,
+) -> _RequestContext:
+```
+
+You can find an example of usage above or in tests.
+But basically `RequestParams` is a structure to define params for `ClientSession.request` func.
+`method`, `url`, `headers` `trace_request_ctx` defined outside kwargs, because they are popular.
+
+There is also an old way to change URL between retries by specifying ```url``` as list of urls. Example:
+```python
+from aiohttp_retry import RetryClient
+
+retry_client = RetryClient()
+async with retry_client.get(url=['/internal_error', '/ping']) as response:
+ text = await response.text()
+ assert response.status == 200
+ assert text == 'Ok!'
+
+await retry_client.close()
+```
+
+In this example we request ```/interval_error```, fail and then successfully request ```/ping```.
+If you specify less urls than ```attempts``` number in ```RetryOptions```, ```RetryClient``` will request last url at last attempts.
+This means that in example above we would request ```/ping``` once again in case of failure.
+
+### Types
+
+`aiohttp_retry` is a typed project. It should be fully compatablie with mypy.
+
+It also introduce one special type:
+```
+ClientType = Union[ClientSession, RetryClient]
+```
+
+This type can be imported by ```from aiohttp_retry.types import ClientType```
+
+
+%prep
+%autosetup -n aiohttp-retry-2.8.3
+
+%build
+%py3_build
+
+%install
+%py3_install
+install -d -m755 %{buildroot}/%{_pkgdocdir}
+if [ -d doc ]; then cp -arf doc %{buildroot}/%{_pkgdocdir}; fi
+if [ -d docs ]; then cp -arf docs %{buildroot}/%{_pkgdocdir}; fi
+if [ -d example ]; then cp -arf example %{buildroot}/%{_pkgdocdir}; fi
+if [ -d examples ]; then cp -arf examples %{buildroot}/%{_pkgdocdir}; fi
+pushd %{buildroot}
+if [ -d usr/lib ]; then
+ find usr/lib -type f -printf "/%h/%f\n" >> filelist.lst
+fi
+if [ -d usr/lib64 ]; then
+ find usr/lib64 -type f -printf "/%h/%f\n" >> filelist.lst
+fi
+if [ -d usr/bin ]; then
+ find usr/bin -type f -printf "/%h/%f\n" >> filelist.lst
+fi
+if [ -d usr/sbin ]; then
+ find usr/sbin -type f -printf "/%h/%f\n" >> filelist.lst
+fi
+touch doclist.lst
+if [ -d usr/share/man ]; then
+ find usr/share/man -type f -printf "/%h/%f.gz\n" >> doclist.lst
+fi
+popd
+mv %{buildroot}/filelist.lst .
+mv %{buildroot}/doclist.lst .
+
+%files -n python3-aiohttp-retry -f filelist.lst
+%dir %{python3_sitelib}/*
+
+%files help -f doclist.lst
+%{_docdir}/*
+
+%changelog
+* Mon Apr 10 2023 Python_Bot <Python_Bot@openeuler.org> - 2.8.3-1
+- Package Spec generated
diff --git a/sources b/sources
new file mode 100644
index 0000000..d558bad
--- /dev/null
+++ b/sources
@@ -0,0 +1 @@
+bc17db5d56a609515765dcfae616758a aiohttp_retry-2.8.3.tar.gz