cli2 3.3.25__tar.gz → 3.3.29__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.25/cli2.egg-info → cli2-3.3.29}/PKG-INFO +1 -1
  2. {cli2-3.3.25 → cli2-3.3.29}/cli2/client.py +112 -54
  3. {cli2-3.3.25 → cli2-3.3.29}/cli2/test_client.py +73 -38
  4. {cli2-3.3.25 → cli2-3.3.29/cli2.egg-info}/PKG-INFO +1 -1
  5. {cli2-3.3.25 → cli2-3.3.29}/setup.py +1 -1
  6. {cli2-3.3.25 → cli2-3.3.29}/MANIFEST.in +0 -0
  7. {cli2-3.3.25 → cli2-3.3.29}/README.rst +0 -0
  8. {cli2-3.3.25 → cli2-3.3.29}/classifiers.txt +0 -0
  9. {cli2-3.3.25 → cli2-3.3.29}/cli2/__init__.py +0 -0
  10. {cli2-3.3.25 → cli2-3.3.29}/cli2/argument.py +0 -0
  11. {cli2-3.3.25 → cli2-3.3.29}/cli2/asyncio.py +0 -0
  12. {cli2-3.3.25 → cli2-3.3.29}/cli2/cli.py +0 -0
  13. {cli2-3.3.25 → cli2-3.3.29}/cli2/colors.py +0 -0
  14. {cli2-3.3.25 → cli2-3.3.29}/cli2/command.py +0 -0
  15. {cli2-3.3.25 → cli2-3.3.29}/cli2/configuration.py +0 -0
  16. {cli2-3.3.25 → cli2-3.3.29}/cli2/decorators.py +0 -0
  17. {cli2-3.3.25 → cli2-3.3.29}/cli2/display.py +0 -0
  18. {cli2-3.3.25 → cli2-3.3.29}/cli2/entry_point.py +0 -0
  19. {cli2-3.3.25 → cli2-3.3.29}/cli2/example_client.py +0 -0
  20. {cli2-3.3.25 → cli2-3.3.29}/cli2/example_client_complex.py +0 -0
  21. {cli2-3.3.25 → cli2-3.3.29}/cli2/example_nesting.py +0 -0
  22. {cli2-3.3.25 → cli2-3.3.29}/cli2/example_obj.py +0 -0
  23. {cli2-3.3.25 → cli2-3.3.29}/cli2/group.py +0 -0
  24. {cli2-3.3.25 → cli2-3.3.29}/cli2/logging.py +0 -0
  25. {cli2-3.3.25 → cli2-3.3.29}/cli2/node.py +0 -0
  26. {cli2-3.3.25 → cli2-3.3.29}/cli2/overrides.py +0 -0
  27. {cli2-3.3.25 → cli2-3.3.29}/cli2/sphinx.py +0 -0
  28. {cli2-3.3.25 → cli2-3.3.29}/cli2/table.py +0 -0
  29. {cli2-3.3.25 → cli2-3.3.29}/cli2/test.py +0 -0
  30. {cli2-3.3.25 → cli2-3.3.29}/cli2/test_cli.py +0 -0
  31. {cli2-3.3.25 → cli2-3.3.29}/cli2/test_command.py +0 -0
  32. {cli2-3.3.25 → cli2-3.3.29}/cli2/test_configuration.py +0 -0
  33. {cli2-3.3.25 → cli2-3.3.29}/cli2/test_decorators.py +0 -0
  34. {cli2-3.3.25 → cli2-3.3.29}/cli2/test_display.py +0 -0
  35. {cli2-3.3.25 → cli2-3.3.29}/cli2/test_entry_point.py +0 -0
  36. {cli2-3.3.25 → cli2-3.3.29}/cli2/test_group.py +0 -0
  37. {cli2-3.3.25 → cli2-3.3.29}/cli2/test_inject.py +0 -0
  38. {cli2-3.3.25 → cli2-3.3.29}/cli2/test_node.py +0 -0
  39. {cli2-3.3.25 → cli2-3.3.29}/cli2/test_table.py +0 -0
  40. {cli2-3.3.25 → cli2-3.3.29}/cli2.egg-info/SOURCES.txt +0 -0
  41. {cli2-3.3.25 → cli2-3.3.29}/cli2.egg-info/dependency_links.txt +0 -0
  42. {cli2-3.3.25 → cli2-3.3.29}/cli2.egg-info/entry_points.txt +0 -0
  43. {cli2-3.3.25 → cli2-3.3.29}/cli2.egg-info/requires.txt +0 -0
  44. {cli2-3.3.25 → cli2-3.3.29}/cli2.egg-info/top_level.txt +0 -0
  45. {cli2-3.3.25 → cli2-3.3.29}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cli2
3
- Version: 3.3.25
3
+ Version: 3.3.29
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
@@ -305,6 +305,11 @@ class Paginator:
305
305
  break
306
306
  page += 1
307
307
 
308
+ async def first(self):
309
+ """ Return first item """
310
+ async for item in self:
311
+ return item
312
+
308
313
 
309
314
  class Field:
310
315
  """
@@ -1027,12 +1032,13 @@ class Handler:
1027
1032
  self.tries = self.tries_default if tries is None else tries
1028
1033
  self.backoff = self.backoff_default if backoff is None else backoff
1029
1034
 
1030
- async def __call__(self, client, response, tries, mask):
1035
+ async def __call__(self, client, response, tries, mask, log):
1031
1036
  if isinstance(response, Exception):
1032
1037
  if tries >= self.tries:
1033
1038
  raise response
1034
1039
  # httpx session is rendered unusable after a TransportError
1035
1040
  if isinstance(response, httpx.TransportError):
1041
+ log.warn('reconnect', exception=str(response))
1036
1042
  await client.client_reset()
1037
1043
  return
1038
1044
 
@@ -1048,13 +1054,25 @@ class Handler:
1048
1054
  if tries >= self.tries:
1049
1055
  raise RetriesExceededError(client, response, tries, mask)
1050
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
+
1051
1067
  if response.status_code in self.retokens:
1052
1068
  if tries:
1053
1069
  # our authentication is just not working, no need to retry
1054
1070
  raise TokenGetError(client, response, tries, mask)
1071
+ log.warn('retoken', **kwargs)
1055
1072
  await client.token_reset()
1056
1073
 
1057
- await asyncio.sleep(tries * self.backoff)
1074
+ log.info('retry', **kwargs)
1075
+ await asyncio.sleep(seconds)
1058
1076
 
1059
1077
 
1060
1078
  class ClientError(Exception):
@@ -1079,27 +1097,31 @@ class ResponseError(ClientError):
1079
1097
  :param exc: httpx.HTTPStatusError
1080
1098
  """
1081
1099
  output = [msg]
1100
+ key, value = self.client.request_log_data(
1101
+ self.response.request,
1102
+ self.mask,
1103
+ )
1082
1104
  request_msg = ' '.join([
1083
- self.response.request.method,
1105
+ str(self.response.request.method),
1084
1106
  str(self.response.request.url),
1085
1107
  ])
1086
1108
 
1087
1109
  output.append(
1088
1110
  f'{colors.reset}{colors.bold}{request_msg}{colors.reset}',
1089
1111
  )
1090
- request = self.client.request_log_data(
1091
- self.response.request,
1092
- self.mask,
1093
- )
1094
- if request:
1095
- output.append(display.render(request))
1112
+ if value:
1113
+ output.append(display.render(value))
1096
1114
 
1115
+ key, value = self.client.response_log_data(self.response, self.mask)
1097
1116
  output.append(
1098
- 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
+ ])
1099
1122
  )
1100
- response = self.client.response_log_data(self.response, self.mask)
1101
- if response:
1102
- output.append(display.render(response))
1123
+ if value:
1124
+ output.append(display.render(value))
1103
1125
 
1104
1126
  return '\n'.join(output)
1105
1127
 
@@ -1217,7 +1239,10 @@ class Client(metaclass=ClientMetaclass):
1217
1239
  """
1218
1240
  client = httpx.AsyncClient(*self._client_args, **self._client_kwargs)
1219
1241
  if self.token and not self.token_getting:
1220
- self.client_token_apply(client)
1242
+ try:
1243
+ self.client_token_apply(client)
1244
+ except NotImplementedError:
1245
+ pass
1221
1246
  return client
1222
1247
 
1223
1248
  @client.setter
@@ -1228,27 +1253,34 @@ class Client(metaclass=ClientMetaclass):
1228
1253
  def client(self):
1229
1254
  self._client = None
1230
1255
 
1231
- async def request_safe(self, *args, handler, mask, retries=True,
1232
- semaphore=None, **kwargs):
1256
+ async def send(self, request, handler, mask, retries=True, semaphore=None,
1257
+ log=None, auth=None, follow_redirects=None):
1233
1258
  """
1234
1259
  Internal request method
1235
1260
  """
1236
1261
  semaphore = semaphore or self.semaphore
1237
1262
  tries = 0
1238
1263
 
1264
+ async def _send():
1265
+ return await self.client.send(
1266
+ request,
1267
+ auth=auth,
1268
+ follow_redirects=follow_redirects,
1269
+ )
1270
+
1239
1271
  async def _request():
1240
1272
  if semaphore:
1241
1273
  async with semaphore:
1242
- return await self.client.request(*args, **kwargs)
1243
- return await self.client.request(*args, **kwargs)
1274
+ return await _send()
1275
+ return await _send()
1244
1276
 
1245
1277
  while retries or tries > 1:
1246
1278
  try:
1247
1279
  response = await _request()
1248
1280
  except Exception as exc:
1249
- await handler(self, exc, tries, mask)
1281
+ await handler(self, exc, tries, mask, log)
1250
1282
  else:
1251
- if response := await handler(self, response, tries, mask):
1283
+ if response := await handler(self, response, tries, mask, log):
1252
1284
  return response
1253
1285
 
1254
1286
  tries += 1
@@ -1275,7 +1307,7 @@ class Client(metaclass=ClientMetaclass):
1275
1307
  pass
1276
1308
  self.token_getting = False
1277
1309
 
1278
- async def client_token_apply(self, client):
1310
+ def client_token_apply(self, client):
1279
1311
  """
1280
1312
  Actually provision self.client with self.token.
1281
1313
 
@@ -1317,9 +1349,19 @@ class Client(metaclass=ClientMetaclass):
1317
1349
  """
1318
1350
  raise NotImplementedError()
1319
1351
 
1320
- async def request(self, method, url, handler=None, quiet=False,
1321
- accepts=None, refuses=None, tries=None, backoff=None,
1322
- retries=True, semaphore=None, mask=None, **kwargs):
1352
+ async def request(
1353
+ # base arguments
1354
+ self, method, url,
1355
+ *,
1356
+ # cli2 arguments
1357
+ handler=None, quiet=False, accepts=None, refuses=None, tries=None,
1358
+ backoff=None, retries=True, semaphore=None, mask=None,
1359
+ # httpx arguments
1360
+ content=None, data=None, files=None, json=None, params=None,
1361
+ headers=None, cookies=None, auth=httpx.USE_CLIENT_DEFAULT,
1362
+ follow_redirects=httpx.USE_CLIENT_DEFAULT,
1363
+ timeout=httpx.USE_CLIENT_DEFAULT, extensions=None,
1364
+ ):
1323
1365
  """
1324
1366
  Request method
1325
1367
 
@@ -1388,46 +1430,71 @@ class Client(metaclass=ClientMetaclass):
1388
1430
  else:
1389
1431
  handler = self.handler
1390
1432
 
1391
- log = self.logger.bind(method=method, url=url)
1392
- if not quiet or self.debug:
1393
- log.debug('request', **self.kwargs_log_data(kwargs, mask, quiet))
1433
+ request = self.client.build_request(
1434
+ method=method,
1435
+ url=url,
1436
+ content=content,
1437
+ data=data,
1438
+ files=files,
1439
+ json=json,
1440
+ params=params,
1441
+ headers=headers,
1442
+ cookies=cookies,
1443
+ timeout=timeout,
1444
+ extensions=extensions,
1445
+ )
1394
1446
 
1395
- response = await self.request_safe(
1396
- method,
1397
- url,
1447
+ log = self.logger.bind(method=method, url=str(request.url))
1448
+ if not quiet or self.debug:
1449
+ key, value = self.request_log_data(request, mask, quiet)
1450
+ kwargs = dict()
1451
+ if value:
1452
+ kwargs[key] = value
1453
+ log.debug('request', **kwargs)
1454
+
1455
+ response = await self.send(
1456
+ request,
1398
1457
  handler=handler,
1399
1458
  retries=retries,
1400
1459
  semaphore=semaphore,
1401
1460
  mask=mask,
1402
- **kwargs,
1461
+ log=log,
1462
+ auth=auth,
1463
+ follow_redirects=follow_redirects,
1403
1464
  )
1404
1465
 
1405
1466
  _log = dict(status_code=response.status_code)
1406
1467
  if not quiet or self.debug:
1407
- self.response_log_data(response, mask, _log)
1468
+ key, value = self.response_log_data(response, mask)
1469
+ if value:
1470
+ _log[key] = value
1408
1471
 
1409
1472
  log.info('response', **_log)
1410
1473
 
1411
1474
  return response
1412
1475
 
1413
- def response_log_data(self, response, mask, log=None):
1476
+ def response_log_data(self, response, mask):
1414
1477
  try:
1415
- data = self.mask_data(response.json(), mask)
1416
- key = 'json'
1478
+ data = response.json()
1417
1479
  except json.JSONDecodeError:
1418
- data = self.mask_content(response.content, mask)
1419
- key = 'content'
1420
-
1421
- if log:
1422
- log[key] = data
1423
- return data
1480
+ if response.content:
1481
+ return 'content', self.mask_content(response.content, mask)
1482
+ else:
1483
+ if data:
1484
+ return 'json', self.mask_data(data, mask)
1485
+ return None, None
1424
1486
 
1425
1487
  def request_log_data(self, request, mask, quiet=False):
1426
1488
  content = request.content.decode()
1489
+ if not content:
1490
+ return None, None
1491
+
1427
1492
  try:
1428
- return self.mask_data(json.loads(content), mask)
1493
+ data = json.loads(content)
1429
1494
  except json.JSONDecodeError:
1430
1495
  pass
1496
+ else:
1497
+ return 'json', self.mask_data(data, mask)
1431
1498
 
1432
1499
  parsed = parse_qs(content)
1433
1500
  if parsed:
@@ -1435,18 +1502,9 @@ class Client(metaclass=ClientMetaclass):
1435
1502
  key: value[0] if len(value) == 1 else value
1436
1503
  for key, value in parsed.items()
1437
1504
  }
1438
- return self.mask_data(data, mask)
1439
-
1440
- return self.mask_content(content, mask)
1441
-
1442
- def kwargs_log_data(self, kwargs, mask, quiet=False):
1443
- _log = kwargs.copy()
1444
- if 'content' in kwargs:
1445
- _log['content'] = self.mask_content(kwargs['content'], mask)
1446
- for key in ('json', 'data'):
1447
- if key in kwargs:
1448
- _log[key] = self.mask_data(kwargs[key], mask)
1449
- return _log
1505
+ return 'data', self.mask_data(data, mask)
1506
+
1507
+ return 'content', self.mask_content(content, mask)
1450
1508
 
1451
1509
  def mask_content(self, content, mask=None):
1452
1510
  """
@@ -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,38 @@ 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('reconnect', exception='foo')
260
270
  assert not result
261
271
  assert client.client_reset.await_count == 1
262
272
 
263
273
  with pytest.raises(httpx.TransportError) as exc:
264
- await handler(client, httpx.TransportError('x'), handler.tries + 1, [])
274
+ await handler(
275
+ client, httpx.TransportError('x'), handler.tries + 1, [], log
276
+ )
265
277
 
266
278
  response = httpx.Response(status_code=418)
267
279
  assert not client.token_reset.await_count
268
- result = await handler(client, response, 0, [])
280
+ log.warn.reset_mock()
281
+ result = await handler(client, response, 0, [], log)
282
+ log.warn.assert_called_once_with(
283
+ 'retoken', status_code=418, tries=0, sleep=.0
284
+ )
269
285
  assert not result
270
286
  assert client.token_reset.await_count == 1
271
287
 
272
288
  handler = cli2.Handler(accepts=[], refuses=[222])
273
289
 
274
290
  response = httpx.Response(status_code=123)
275
- result = await handler(client, response, 0, [])
291
+ result = await handler(client, response, 0, [], log)
276
292
  assert result == response
277
293
 
278
294
 
@@ -285,16 +301,14 @@ async def test_retry(httpx_mock, client_class):
285
301
  return self.return_token
286
302
 
287
303
  def client_factory(self):
288
- return mock.Mock()
304
+ client = super().client_factory()
305
+ client.send = mock.Mock()
306
+ return client
289
307
 
290
- client = Client(
291
- retry_request=[500],
292
- recreate_client=[400],
293
- backoff=0.1,
294
- )
308
+ client = Client()
295
309
 
296
310
  current_client = client.client
297
- client.client.request.side_effect = [
311
+ client.client.send.side_effect = [
298
312
  _response(status_code=500),
299
313
  _response(status_code=500),
300
314
  _response(status_code=200),
@@ -348,6 +362,12 @@ async def test_pagination_initialize(httpx_mock):
348
362
  client = PaginatedClient(base_url='http://lol')
349
363
  assert await client.paginate('/').list() == [dict(a=1), dict(a=2)]
350
364
 
365
+ httpx_mock.add_response(url='http://lol/?page=1', json=dict(
366
+ total_pages=2,
367
+ items=[dict(a=1)],
368
+ ))
369
+ assert await client.paginate('/').first() == dict(a=1)
370
+
351
371
 
352
372
  @pytest.mark.asyncio
353
373
  async def test_token_get(httpx_mock):
@@ -768,7 +788,7 @@ def test_datetime_default_fmt():
768
788
  )
769
789
  async def test_mask_logs(key):
770
790
  client = Client(mask=['scrt', 'password'])
771
- client.client = mock.AsyncMock()
791
+ client.client.send = mock.AsyncMock()
772
792
 
773
793
  client.logger = mock.Mock()
774
794
  response = httpx.Response(
@@ -777,9 +797,12 @@ async def test_mask_logs(key):
777
797
  )
778
798
  data = dict(foo='bar', password='secret')
779
799
  response.request = httpx.Request('POST', '/', **{key: data})
780
- client.client.request.return_value = response
800
+ client.client.send.return_value = response
781
801
  await client.post('/', **{key: data})
782
- client.logger.bind.assert_called_once_with(method='POST', url='/')
802
+ client.logger.bind.assert_called_once_with(
803
+ method='POST',
804
+ url='http://lol/',
805
+ )
783
806
  log = client.logger.bind.return_value
784
807
  log.debug.assert_called_once_with(
785
808
  'request',
@@ -816,7 +839,7 @@ async def test_mask_exceptions(client_class):
816
839
  @pytest.mark.asyncio
817
840
  async def test_request_mask():
818
841
  client = Client(mask=['password'])
819
- client.client = mock.AsyncMock()
842
+ client.client.send = mock.AsyncMock()
820
843
 
821
844
  client.logger = mock.Mock()
822
845
  response = httpx.Response(
@@ -825,9 +848,12 @@ async def test_request_mask():
825
848
  )
826
849
  data = dict(foo='bar', password='secret')
827
850
  response.request = httpx.Request('POST', '/', json=data)
828
- client.client.request.return_value = response
851
+ client.client.send.return_value = response
829
852
  await client.post('/', json=data, mask=['scrt'])
830
- client.logger.bind.assert_called_once_with(method='POST', url='/')
853
+ client.logger.bind.assert_called_once_with(
854
+ method='POST',
855
+ url='http://lol/'
856
+ )
831
857
  log = client.logger.bind.return_value
832
858
  log.debug.assert_called_once_with(
833
859
  'request',
@@ -843,13 +869,16 @@ async def test_request_mask():
843
869
  @pytest.mark.asyncio
844
870
  async def test_log_content():
845
871
  client = Client()
846
- client.client = mock.AsyncMock()
872
+ client.client.send = mock.AsyncMock()
847
873
  client.logger = mock.Mock()
848
874
  response = httpx.Response(status_code=200, content='lol:]bar')
849
875
  response.request = httpx.Request('POST', '/')
850
- client.client.request.return_value = response
876
+ client.client.send.return_value = response
851
877
  await client.post('/', content='lol:]foo')
852
- client.logger.bind.assert_called_once_with(method='POST', url='/')
878
+ client.logger.bind.assert_called_once_with(
879
+ method='POST',
880
+ url='http://lol/'
881
+ )
853
882
  log = client.logger.bind.return_value
854
883
  log.debug.assert_called_once_with('request', content='lol:]foo')
855
884
  log.info.assert_called_once_with(
@@ -860,14 +889,17 @@ async def test_log_content():
860
889
  @pytest.mark.asyncio
861
890
  async def test_log_quiet():
862
891
  client = Client()
863
- client.client = mock.AsyncMock()
892
+ client.client.send = mock.AsyncMock()
864
893
  client.logger = mock.Mock()
865
894
  response = httpx.Response(status_code=200, content='[1]')
866
895
  response.request = httpx.Request('GET', '/')
867
- client.client.request.return_value = response
896
+ client.client.send.return_value = response
868
897
  await client.get('/', json=[1], quiet=True)
869
898
  log = client.logger.bind.return_value
870
- client.logger.bind.assert_called_once_with(method='GET', url='/')
899
+ client.logger.bind.assert_called_once_with(
900
+ method='GET',
901
+ url='http://lol/',
902
+ )
871
903
  log = client.logger.bind.return_value
872
904
  assert not log.debug.call_args_list
873
905
  log.info.assert_called_once_with('response', status_code=200)
@@ -933,7 +965,7 @@ def test_id_value():
933
965
  @pytest.mark.asyncio
934
966
  async def test_debug():
935
967
  client = Client(mask=['scrt', 'password'], debug=True)
936
- client.client = mock.AsyncMock()
968
+ client.client.send = mock.AsyncMock()
937
969
 
938
970
  client.logger = mock.Mock()
939
971
  response = httpx.Response(
@@ -942,9 +974,12 @@ async def test_debug():
942
974
  )
943
975
  data = dict(foo='bar', password='secret')
944
976
  response.request = httpx.Request('POST', '/', json=data)
945
- client.client.request.return_value = response
977
+ client.client.send.return_value = response
946
978
  await client.post('/', json=data, quiet=True)
947
- client.logger.bind.assert_called_once_with(method='POST', url='/')
979
+ client.logger.bind.assert_called_once_with(
980
+ method='POST',
981
+ url='http://lol/',
982
+ )
948
983
  log = client.logger.bind.return_value
949
984
  log.debug.assert_called_once_with(
950
985
  'request',
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cli2
3
- Version: 3.3.25
3
+ Version: 3.3.29
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.25',
6
+ version='3.3.29',
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