cli2 3.3.26__tar.gz → 3.3.30__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. {cli2-3.3.26/cli2.egg-info → cli2-3.3.30}/PKG-INFO +1 -1
  2. {cli2-3.3.26 → cli2-3.3.30}/cli2/client.py +116 -59
  3. {cli2-3.3.26 → cli2-3.3.30}/cli2/test_client.py +70 -38
  4. {cli2-3.3.26 → cli2-3.3.30/cli2.egg-info}/PKG-INFO +1 -1
  5. {cli2-3.3.26 → cli2-3.3.30}/setup.py +1 -1
  6. {cli2-3.3.26 → cli2-3.3.30}/MANIFEST.in +0 -0
  7. {cli2-3.3.26 → cli2-3.3.30}/README.rst +0 -0
  8. {cli2-3.3.26 → cli2-3.3.30}/classifiers.txt +0 -0
  9. {cli2-3.3.26 → cli2-3.3.30}/cli2/__init__.py +0 -0
  10. {cli2-3.3.26 → cli2-3.3.30}/cli2/argument.py +0 -0
  11. {cli2-3.3.26 → cli2-3.3.30}/cli2/asyncio.py +0 -0
  12. {cli2-3.3.26 → cli2-3.3.30}/cli2/cli.py +0 -0
  13. {cli2-3.3.26 → cli2-3.3.30}/cli2/colors.py +0 -0
  14. {cli2-3.3.26 → cli2-3.3.30}/cli2/command.py +0 -0
  15. {cli2-3.3.26 → cli2-3.3.30}/cli2/configuration.py +0 -0
  16. {cli2-3.3.26 → cli2-3.3.30}/cli2/decorators.py +0 -0
  17. {cli2-3.3.26 → cli2-3.3.30}/cli2/display.py +0 -0
  18. {cli2-3.3.26 → cli2-3.3.30}/cli2/entry_point.py +0 -0
  19. {cli2-3.3.26 → cli2-3.3.30}/cli2/example_client.py +0 -0
  20. {cli2-3.3.26 → cli2-3.3.30}/cli2/example_client_complex.py +0 -0
  21. {cli2-3.3.26 → cli2-3.3.30}/cli2/example_nesting.py +0 -0
  22. {cli2-3.3.26 → cli2-3.3.30}/cli2/example_obj.py +0 -0
  23. {cli2-3.3.26 → cli2-3.3.30}/cli2/group.py +0 -0
  24. {cli2-3.3.26 → cli2-3.3.30}/cli2/logging.py +0 -0
  25. {cli2-3.3.26 → cli2-3.3.30}/cli2/node.py +0 -0
  26. {cli2-3.3.26 → cli2-3.3.30}/cli2/overrides.py +0 -0
  27. {cli2-3.3.26 → cli2-3.3.30}/cli2/sphinx.py +0 -0
  28. {cli2-3.3.26 → cli2-3.3.30}/cli2/table.py +0 -0
  29. {cli2-3.3.26 → cli2-3.3.30}/cli2/test.py +0 -0
  30. {cli2-3.3.26 → cli2-3.3.30}/cli2/test_cli.py +0 -0
  31. {cli2-3.3.26 → cli2-3.3.30}/cli2/test_command.py +0 -0
  32. {cli2-3.3.26 → cli2-3.3.30}/cli2/test_configuration.py +0 -0
  33. {cli2-3.3.26 → cli2-3.3.30}/cli2/test_decorators.py +0 -0
  34. {cli2-3.3.26 → cli2-3.3.30}/cli2/test_display.py +0 -0
  35. {cli2-3.3.26 → cli2-3.3.30}/cli2/test_entry_point.py +0 -0
  36. {cli2-3.3.26 → cli2-3.3.30}/cli2/test_group.py +0 -0
  37. {cli2-3.3.26 → cli2-3.3.30}/cli2/test_inject.py +0 -0
  38. {cli2-3.3.26 → cli2-3.3.30}/cli2/test_node.py +0 -0
  39. {cli2-3.3.26 → cli2-3.3.30}/cli2/test_table.py +0 -0
  40. {cli2-3.3.26 → cli2-3.3.30}/cli2.egg-info/SOURCES.txt +0 -0
  41. {cli2-3.3.26 → cli2-3.3.30}/cli2.egg-info/dependency_links.txt +0 -0
  42. {cli2-3.3.26 → cli2-3.3.30}/cli2.egg-info/entry_points.txt +0 -0
  43. {cli2-3.3.26 → cli2-3.3.30}/cli2.egg-info/requires.txt +0 -0
  44. {cli2-3.3.26 → cli2-3.3.30}/cli2.egg-info/top_level.txt +0 -0
  45. {cli2-3.3.26 → cli2-3.3.30}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cli2
3
- Version: 3.3.26
3
+ Version: 3.3.30
4
4
  Summary: image:: https://yourlabs.io/oss/cli2/badges/master/pipeline.svg
5
5
  Home-page: https://yourlabs.io/oss/cli2
6
6
  Author: James Pic
@@ -1032,12 +1032,13 @@ class Handler:
1032
1032
  self.tries = self.tries_default if tries is None else tries
1033
1033
  self.backoff = self.backoff_default if backoff is None else backoff
1034
1034
 
1035
- async def __call__(self, client, response, tries, mask):
1035
+ async def __call__(self, client, response, tries, mask, log):
1036
1036
  if isinstance(response, Exception):
1037
1037
  if tries >= self.tries:
1038
1038
  raise response
1039
1039
  # httpx session is rendered unusable after a TransportError
1040
1040
  if isinstance(response, httpx.TransportError):
1041
+ log.warn('reconnect', error=repr(response))
1041
1042
  await client.client_reset()
1042
1043
  return
1043
1044
 
@@ -1053,13 +1054,25 @@ class Handler:
1053
1054
  if tries >= self.tries:
1054
1055
  raise RetriesExceededError(client, response, tries, mask)
1055
1056
 
1057
+ seconds = tries * self.backoff
1058
+ kwargs = dict(
1059
+ status_code=response.status_code,
1060
+ tries=tries,
1061
+ sleep=seconds,
1062
+ )
1063
+ key, value = client.response_log_data(response, mask)
1064
+ if value:
1065
+ kwargs[key] = value
1066
+
1056
1067
  if response.status_code in self.retokens:
1057
1068
  if tries:
1058
1069
  # our authentication is just not working, no need to retry
1059
1070
  raise TokenGetError(client, response, tries, mask)
1071
+ log.warn('retoken', **kwargs)
1060
1072
  await client.token_reset()
1061
1073
 
1062
- await asyncio.sleep(tries * self.backoff)
1074
+ log.info('retry', **kwargs)
1075
+ await asyncio.sleep(seconds)
1063
1076
 
1064
1077
 
1065
1078
  class ClientError(Exception):
@@ -1084,27 +1097,31 @@ class ResponseError(ClientError):
1084
1097
  :param exc: httpx.HTTPStatusError
1085
1098
  """
1086
1099
  output = [msg]
1100
+ key, value = self.client.request_log_data(
1101
+ self.response.request,
1102
+ self.mask,
1103
+ )
1087
1104
  request_msg = ' '.join([
1088
- self.response.request.method,
1105
+ str(self.response.request.method),
1089
1106
  str(self.response.request.url),
1090
1107
  ])
1091
1108
 
1092
1109
  output.append(
1093
1110
  f'{colors.reset}{colors.bold}{request_msg}{colors.reset}',
1094
1111
  )
1095
- request = self.client.request_log_data(
1096
- self.response.request,
1097
- self.mask,
1098
- )
1099
- if request:
1100
- output.append(display.render(request))
1112
+ if value:
1113
+ output.append(display.render(value))
1101
1114
 
1115
+ key, value = self.client.response_log_data(self.response, self.mask)
1102
1116
  output.append(
1103
- f'{colors.bold}HTTP {self.response.status_code}{colors.reset}',
1117
+ ''.join([
1118
+ colors.bold,
1119
+ f'HTTP {self.response.status_code}',
1120
+ colors.reset,
1121
+ ])
1104
1122
  )
1105
- response = self.client.response_log_data(self.response, self.mask)
1106
- if response:
1107
- output.append(display.render(response))
1123
+ if value:
1124
+ output.append(display.render(value))
1108
1125
 
1109
1126
  return '\n'.join(output)
1110
1127
 
@@ -1222,7 +1239,10 @@ class Client(metaclass=ClientMetaclass):
1222
1239
  """
1223
1240
  client = httpx.AsyncClient(*self._client_args, **self._client_kwargs)
1224
1241
  if self.token and not self.token_getting:
1225
- self.client_token_apply(client)
1242
+ try:
1243
+ self.client_token_apply(client)
1244
+ except NotImplementedError:
1245
+ pass
1226
1246
  return client
1227
1247
 
1228
1248
  @client.setter
@@ -1233,27 +1253,34 @@ class Client(metaclass=ClientMetaclass):
1233
1253
  def client(self):
1234
1254
  self._client = None
1235
1255
 
1236
- async def request_safe(self, *args, handler, mask, retries=True,
1237
- semaphore=None, **kwargs):
1256
+ async def send(self, request, handler, mask, retries=True, semaphore=None,
1257
+ log=None, auth=None, follow_redirects=None):
1238
1258
  """
1239
1259
  Internal request method
1240
1260
  """
1241
1261
  semaphore = semaphore or self.semaphore
1242
1262
  tries = 0
1243
1263
 
1264
+ async def _send():
1265
+ return await self.client.send(
1266
+ request,
1267
+ auth=auth,
1268
+ follow_redirects=follow_redirects,
1269
+ )
1270
+
1244
1271
  async def _request():
1245
1272
  if semaphore:
1246
1273
  async with semaphore:
1247
- return await self.client.request(*args, **kwargs)
1248
- return await self.client.request(*args, **kwargs)
1274
+ return await _send()
1275
+ return await _send()
1249
1276
 
1250
1277
  while retries or tries > 1:
1251
1278
  try:
1252
1279
  response = await _request()
1253
1280
  except Exception as exc:
1254
- await handler(self, exc, tries, mask)
1281
+ await handler(self, exc, tries, mask, log)
1255
1282
  else:
1256
- if response := await handler(self, response, tries, mask):
1283
+ if response := await handler(self, response, tries, mask, log):
1257
1284
  return response
1258
1285
 
1259
1286
  tries += 1
@@ -1280,7 +1307,7 @@ class Client(metaclass=ClientMetaclass):
1280
1307
  pass
1281
1308
  self.token_getting = False
1282
1309
 
1283
- async def client_token_apply(self, client):
1310
+ def client_token_apply(self, client):
1284
1311
  """
1285
1312
  Actually provision self.client with self.token.
1286
1313
 
@@ -1310,21 +1337,36 @@ class Client(metaclass=ClientMetaclass):
1310
1337
  By default, this method does nothing. Implement it to your likings.
1311
1338
 
1312
1339
  This method is supposed to return the token, but doesn't do anything
1313
- with it by itself: it's up to you to call something like:
1340
+ with it by itself.
1341
+
1342
+ You also need to implement the :py:meth:`client_token_apply` which is
1343
+ in charge of updating the actual httpx client object with the said
1344
+ token.
1314
1345
 
1315
1346
  .. code-block::
1316
1347
 
1317
1348
  async def token_get(self):
1318
1349
  response = await self.post('/login', dict(...))
1319
- token = response.json()['token']
1320
- self.client.headers['token'] = f'Bearer {token}'
1321
- return token
1350
+ return response.json()['token']
1351
+
1352
+ def client_token_apply(self, client):
1353
+ client.headers['X-ApiKey'] = self.token
1322
1354
  """
1323
1355
  raise NotImplementedError()
1324
1356
 
1325
- async def request(self, method, url, handler=None, quiet=False,
1326
- accepts=None, refuses=None, tries=None, backoff=None,
1327
- retries=True, semaphore=None, mask=None, **kwargs):
1357
+ async def request(
1358
+ # base arguments
1359
+ self, method, url,
1360
+ *,
1361
+ # cli2 arguments
1362
+ handler=None, quiet=False, accepts=None, refuses=None, tries=None,
1363
+ backoff=None, retries=True, semaphore=None, mask=None,
1364
+ # httpx arguments
1365
+ content=None, data=None, files=None, json=None, params=None,
1366
+ headers=None, cookies=None, auth=httpx.USE_CLIENT_DEFAULT,
1367
+ follow_redirects=httpx.USE_CLIENT_DEFAULT,
1368
+ timeout=httpx.USE_CLIENT_DEFAULT, extensions=None,
1369
+ ):
1328
1370
  """
1329
1371
  Request method
1330
1372
 
@@ -1369,7 +1411,6 @@ class Client(metaclass=ClientMetaclass):
1369
1411
  the response, set to False if you want only 1 try.
1370
1412
  :param accepts: Override for :py:attr:`Handler.accepts`
1371
1413
  :param refuses: Override for :py:attr:`Handler.refuses`
1372
- :param retries: Override for :py:attr:`Handler.retries`
1373
1414
  :param tries: Override for :py:attr:`Handler.tries`
1374
1415
  :param backoff: Override for :py:attr:`Handler.backoff`
1375
1416
  :param semaphore: Override for :py:attr:`Client.semaphore`
@@ -1393,46 +1434,71 @@ class Client(metaclass=ClientMetaclass):
1393
1434
  else:
1394
1435
  handler = self.handler
1395
1436
 
1396
- log = self.logger.bind(method=method, url=url)
1397
- if not quiet or self.debug:
1398
- log.debug('request', **self.kwargs_log_data(kwargs, mask, quiet))
1437
+ request = self.client.build_request(
1438
+ method=method,
1439
+ url=url,
1440
+ content=content,
1441
+ data=data,
1442
+ files=files,
1443
+ json=json,
1444
+ params=params,
1445
+ headers=headers,
1446
+ cookies=cookies,
1447
+ timeout=timeout,
1448
+ extensions=extensions,
1449
+ )
1399
1450
 
1400
- response = await self.request_safe(
1401
- method,
1402
- url,
1451
+ log = self.logger.bind(method=method, url=str(request.url))
1452
+ if not quiet or self.debug:
1453
+ key, value = self.request_log_data(request, mask, quiet)
1454
+ kwargs = dict()
1455
+ if value:
1456
+ kwargs[key] = value
1457
+ log.debug('request', **kwargs)
1458
+
1459
+ response = await self.send(
1460
+ request,
1403
1461
  handler=handler,
1404
1462
  retries=retries,
1405
1463
  semaphore=semaphore,
1406
1464
  mask=mask,
1407
- **kwargs,
1465
+ log=log,
1466
+ auth=auth,
1467
+ follow_redirects=follow_redirects,
1408
1468
  )
1409
1469
 
1410
1470
  _log = dict(status_code=response.status_code)
1411
1471
  if not quiet or self.debug:
1412
- self.response_log_data(response, mask, _log)
1472
+ key, value = self.response_log_data(response, mask)
1473
+ if value:
1474
+ _log[key] = value
1413
1475
 
1414
1476
  log.info('response', **_log)
1415
1477
 
1416
1478
  return response
1417
1479
 
1418
- def response_log_data(self, response, mask, log=None):
1480
+ def response_log_data(self, response, mask):
1419
1481
  try:
1420
- data = self.mask_data(response.json(), mask)
1421
- key = 'json'
1482
+ data = response.json()
1422
1483
  except json.JSONDecodeError:
1423
- data = self.mask_content(response.content, mask)
1424
- key = 'content'
1425
-
1426
- if log:
1427
- log[key] = data
1428
- return data
1484
+ if response.content:
1485
+ return 'content', self.mask_content(response.content, mask)
1486
+ else:
1487
+ if data:
1488
+ return 'json', self.mask_data(data, mask)
1489
+ return None, None
1429
1490
 
1430
1491
  def request_log_data(self, request, mask, quiet=False):
1431
1492
  content = request.content.decode()
1493
+ if not content:
1494
+ return None, None
1495
+
1432
1496
  try:
1433
- return self.mask_data(json.loads(content), mask)
1497
+ data = json.loads(content)
1434
1498
  except json.JSONDecodeError:
1435
1499
  pass
1500
+ else:
1501
+ return 'json', self.mask_data(data, mask)
1436
1502
 
1437
1503
  parsed = parse_qs(content)
1438
1504
  if parsed:
@@ -1440,18 +1506,9 @@ class Client(metaclass=ClientMetaclass):
1440
1506
  key: value[0] if len(value) == 1 else value
1441
1507
  for key, value in parsed.items()
1442
1508
  }
1443
- return self.mask_data(data, mask)
1444
-
1445
- return self.mask_content(content, mask)
1446
-
1447
- def kwargs_log_data(self, kwargs, mask, quiet=False):
1448
- _log = kwargs.copy()
1449
- if 'content' in kwargs:
1450
- _log['content'] = self.mask_content(kwargs['content'], mask)
1451
- for key in ('json', 'data'):
1452
- if key in kwargs:
1453
- _log[key] = self.mask_data(kwargs[key], mask)
1454
- return _log
1509
+ return 'data', self.mask_data(data, mask)
1510
+
1511
+ return 'content', self.mask_content(content, mask)
1455
1512
 
1456
1513
  def mask_content(self, content, mask=None):
1457
1514
  """
@@ -15,9 +15,9 @@ class HandlerSentinel(cli2.Handler):
15
15
  super().__init__(*args, **kwargs)
16
16
  self.calls = []
17
17
 
18
- async def __call__(self, client, response, tries, mask):
18
+ async def __call__(self, client, response, tries, mask, log):
19
19
  self.calls.append((client, response.status_code, tries))
20
- return await super().__call__(client, response, tries, mask)
20
+ return await super().__call__(client, response, tries, mask, log)
21
21
 
22
22
 
23
23
  @pytest.fixture
@@ -154,7 +154,7 @@ async def test_error_remote(httpx_mock):
154
154
  global raised
155
155
  raised = True
156
156
  raise httpx.RemoteProtocolError('foo')
157
- client.client.request = raises
157
+ client.client.send = raises
158
158
  old_client = client.client
159
159
  response = await client.get('http://lol')
160
160
  assert client.client is not old_client
@@ -186,12 +186,14 @@ async def test_factory(httpx_mock, client_class):
186
186
  async def test_client_handler(httpx_mock, client_class):
187
187
  class Client(client_class):
188
188
  def client_factory(self):
189
- return mock.Mock()
189
+ client = super().client_factory()
190
+ client.send = mock.Mock()
191
+ return client
190
192
 
191
193
  client = Client(handler=HandlerSentinel())
192
194
 
193
195
  # test response retry
194
- client.client.request.side_effect = [
196
+ client.client.send.side_effect = [
195
197
  _response(status_code=500),
196
198
  _response(status_code=200),
197
199
  ]
@@ -203,7 +205,7 @@ async def test_client_handler(httpx_mock, client_class):
203
205
  ]
204
206
 
205
207
  # test TransportError retry
206
- client.client.request.side_effect = [
208
+ client.client.send.side_effect = [
207
209
  httpx.TransportError("foo"),
208
210
  _response(status_code=200),
209
211
  ]
@@ -216,23 +218,30 @@ async def test_client_handler(httpx_mock, client_class):
216
218
 
217
219
  @pytest.mark.asyncio
218
220
  async def test_handler(client_class):
221
+ log = mock.Mock()
219
222
  client = client_class()
220
223
  client.client_reset = mock.AsyncMock()
221
224
  client.token_reset = mock.AsyncMock()
222
225
  handler = cli2.Handler(accepts=[201], refuses=[218], retokens=[418])
223
226
 
224
227
  response = httpx.Response(status_code=201)
225
- result = await handler(client, response, 0, [])
228
+ result = await handler(client, response, 0, [], log)
226
229
  assert result == response
227
230
 
228
231
  response = httpx.Response(status_code=200)
229
- result = await handler(client, response, 0, [])
232
+ result = await handler(client, response, 0, [], log)
233
+ log.info.assert_called_once_with(
234
+ 'retry', status_code=200, tries=0, sleep=.0
235
+ )
230
236
  assert not result
231
237
 
232
238
  response = httpx.Response(status_code=200, content='[2]')
233
239
  response.request = httpx.Request('POST', '/', json=[1])
234
240
  with pytest.raises(cli2.RetriesExceededError) as exc:
235
- await handler(client, response, handler.tries + 1, [])
241
+ await handler(client, response, handler.tries + 1, [], log)
242
+ log.info.assert_called_once_with(
243
+ 'retry', status_code=200, tries=0, sleep=.0
244
+ )
236
245
 
237
246
  msg = 'Unacceptable response <Response [200 OK]> after 31 tries\n\x1b[0m\x1b[1mPOST /\x1b[0m\n-\x1b[37m \x1b[39;49;00m1\x1b[37m\x1b[39;49;00m\n\n\x1b[1mHTTP 200\x1b[0m\n-\x1b[37m \x1b[39;49;00m2\x1b[37m\x1b[39;49;00m\n' # noqa
238
247
  assert str(exc.value) == msg
@@ -240,7 +249,7 @@ async def test_handler(client_class):
240
249
  response = httpx.Response(status_code=200)
241
250
  response.request = httpx.Request('GET', '/')
242
251
  with pytest.raises(cli2.RetriesExceededError) as exc:
243
- await handler(client, response, handler.tries + 1, [])
252
+ await handler(client, response, handler.tries + 1, [], log)
244
253
 
245
254
  msg = 'Unacceptable response <Response [200 OK]> after 31 tries\n\x1b[0m\x1b[1mGET /\x1b[0m\n\x1b[1mHTTP 200\x1b[0m' # noqa
246
255
  assert str(exc.value) == msg
@@ -248,31 +257,41 @@ async def test_handler(client_class):
248
257
  response = httpx.Response(status_code=218)
249
258
  response.request = httpx.Request('POST', '/')
250
259
  with pytest.raises(cli2.RefusedResponseError):
251
- await handler(client, response, 1, [])
260
+ await handler(client, response, 1, [], log)
252
261
 
253
262
  response = httpx.Response(status_code=418)
254
263
  response.request = httpx.Request('POST', '/')
255
264
  with pytest.raises(cli2.TokenGetError):
256
- await handler(client, response, 1, [])
265
+ await handler(client, response, 1, [], log)
257
266
 
258
267
  assert not client.client_reset.await_count
259
- result = await handler(client, httpx.TransportError('foo'), 0, [])
268
+ result = await handler(client, httpx.TransportError('foo'), 0, [], log)
269
+ log.warn.assert_called_once_with(
270
+ 'reconnect',
271
+ error="TransportError('foo')",
272
+ )
260
273
  assert not result
261
274
  assert client.client_reset.await_count == 1
262
275
 
263
276
  with pytest.raises(httpx.TransportError) as exc:
264
- await handler(client, httpx.TransportError('x'), handler.tries + 1, [])
277
+ await handler(
278
+ client, httpx.TransportError('x'), handler.tries + 1, [], log
279
+ )
265
280
 
266
281
  response = httpx.Response(status_code=418)
267
282
  assert not client.token_reset.await_count
268
- result = await handler(client, response, 0, [])
283
+ log.warn.reset_mock()
284
+ result = await handler(client, response, 0, [], log)
285
+ log.warn.assert_called_once_with(
286
+ 'retoken', status_code=418, tries=0, sleep=.0
287
+ )
269
288
  assert not result
270
289
  assert client.token_reset.await_count == 1
271
290
 
272
291
  handler = cli2.Handler(accepts=[], refuses=[222])
273
292
 
274
293
  response = httpx.Response(status_code=123)
275
- result = await handler(client, response, 0, [])
294
+ result = await handler(client, response, 0, [], log)
276
295
  assert result == response
277
296
 
278
297
 
@@ -285,16 +304,14 @@ async def test_retry(httpx_mock, client_class):
285
304
  return self.return_token
286
305
 
287
306
  def client_factory(self):
288
- return mock.Mock()
307
+ client = super().client_factory()
308
+ client.send = mock.Mock()
309
+ return client
289
310
 
290
- client = Client(
291
- retry_request=[500],
292
- recreate_client=[400],
293
- backoff=0.1,
294
- )
311
+ client = Client()
295
312
 
296
313
  current_client = client.client
297
- client.client.request.side_effect = [
314
+ client.client.send.side_effect = [
298
315
  _response(status_code=500),
299
316
  _response(status_code=500),
300
317
  _response(status_code=200),
@@ -774,7 +791,7 @@ def test_datetime_default_fmt():
774
791
  )
775
792
  async def test_mask_logs(key):
776
793
  client = Client(mask=['scrt', 'password'])
777
- client.client = mock.AsyncMock()
794
+ client.client.send = mock.AsyncMock()
778
795
 
779
796
  client.logger = mock.Mock()
780
797
  response = httpx.Response(
@@ -783,9 +800,12 @@ async def test_mask_logs(key):
783
800
  )
784
801
  data = dict(foo='bar', password='secret')
785
802
  response.request = httpx.Request('POST', '/', **{key: data})
786
- client.client.request.return_value = response
803
+ client.client.send.return_value = response
787
804
  await client.post('/', **{key: data})
788
- client.logger.bind.assert_called_once_with(method='POST', url='/')
805
+ client.logger.bind.assert_called_once_with(
806
+ method='POST',
807
+ url='http://lol/',
808
+ )
789
809
  log = client.logger.bind.return_value
790
810
  log.debug.assert_called_once_with(
791
811
  'request',
@@ -822,7 +842,7 @@ async def test_mask_exceptions(client_class):
822
842
  @pytest.mark.asyncio
823
843
  async def test_request_mask():
824
844
  client = Client(mask=['password'])
825
- client.client = mock.AsyncMock()
845
+ client.client.send = mock.AsyncMock()
826
846
 
827
847
  client.logger = mock.Mock()
828
848
  response = httpx.Response(
@@ -831,9 +851,12 @@ async def test_request_mask():
831
851
  )
832
852
  data = dict(foo='bar', password='secret')
833
853
  response.request = httpx.Request('POST', '/', json=data)
834
- client.client.request.return_value = response
854
+ client.client.send.return_value = response
835
855
  await client.post('/', json=data, mask=['scrt'])
836
- client.logger.bind.assert_called_once_with(method='POST', url='/')
856
+ client.logger.bind.assert_called_once_with(
857
+ method='POST',
858
+ url='http://lol/'
859
+ )
837
860
  log = client.logger.bind.return_value
838
861
  log.debug.assert_called_once_with(
839
862
  'request',
@@ -849,13 +872,16 @@ async def test_request_mask():
849
872
  @pytest.mark.asyncio
850
873
  async def test_log_content():
851
874
  client = Client()
852
- client.client = mock.AsyncMock()
875
+ client.client.send = mock.AsyncMock()
853
876
  client.logger = mock.Mock()
854
877
  response = httpx.Response(status_code=200, content='lol:]bar')
855
878
  response.request = httpx.Request('POST', '/')
856
- client.client.request.return_value = response
879
+ client.client.send.return_value = response
857
880
  await client.post('/', content='lol:]foo')
858
- client.logger.bind.assert_called_once_with(method='POST', url='/')
881
+ client.logger.bind.assert_called_once_with(
882
+ method='POST',
883
+ url='http://lol/'
884
+ )
859
885
  log = client.logger.bind.return_value
860
886
  log.debug.assert_called_once_with('request', content='lol:]foo')
861
887
  log.info.assert_called_once_with(
@@ -866,14 +892,17 @@ async def test_log_content():
866
892
  @pytest.mark.asyncio
867
893
  async def test_log_quiet():
868
894
  client = Client()
869
- client.client = mock.AsyncMock()
895
+ client.client.send = mock.AsyncMock()
870
896
  client.logger = mock.Mock()
871
897
  response = httpx.Response(status_code=200, content='[1]')
872
898
  response.request = httpx.Request('GET', '/')
873
- client.client.request.return_value = response
899
+ client.client.send.return_value = response
874
900
  await client.get('/', json=[1], quiet=True)
875
901
  log = client.logger.bind.return_value
876
- client.logger.bind.assert_called_once_with(method='GET', url='/')
902
+ client.logger.bind.assert_called_once_with(
903
+ method='GET',
904
+ url='http://lol/',
905
+ )
877
906
  log = client.logger.bind.return_value
878
907
  assert not log.debug.call_args_list
879
908
  log.info.assert_called_once_with('response', status_code=200)
@@ -939,7 +968,7 @@ def test_id_value():
939
968
  @pytest.mark.asyncio
940
969
  async def test_debug():
941
970
  client = Client(mask=['scrt', 'password'], debug=True)
942
- client.client = mock.AsyncMock()
971
+ client.client.send = mock.AsyncMock()
943
972
 
944
973
  client.logger = mock.Mock()
945
974
  response = httpx.Response(
@@ -948,9 +977,12 @@ async def test_debug():
948
977
  )
949
978
  data = dict(foo='bar', password='secret')
950
979
  response.request = httpx.Request('POST', '/', json=data)
951
- client.client.request.return_value = response
980
+ client.client.send.return_value = response
952
981
  await client.post('/', json=data, quiet=True)
953
- client.logger.bind.assert_called_once_with(method='POST', url='/')
982
+ client.logger.bind.assert_called_once_with(
983
+ method='POST',
984
+ url='http://lol/',
985
+ )
954
986
  log = client.logger.bind.return_value
955
987
  log.debug.assert_called_once_with(
956
988
  'request',
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cli2
3
- Version: 3.3.26
3
+ Version: 3.3.30
4
4
  Summary: image:: https://yourlabs.io/oss/cli2/badges/master/pipeline.svg
5
5
  Home-page: https://yourlabs.io/oss/cli2
6
6
  Author: James Pic
@@ -3,7 +3,7 @@ from setuptools import setup
3
3
 
4
4
  setup(
5
5
  name='cli2',
6
- version='3.3.26',
6
+ version='3.3.30',
7
7
  setup_requires='setupmeta',
8
8
  install_requires=[
9
9
  'docstring_parser',
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes