bb_api 0.5.0__tar.gz → 0.5.1__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bb_api
3
- Version: 0.5.0
3
+ Version: 0.5.1
4
4
  Summary: Wrapper da API do Banco do Brasil.
5
5
  Requires-Python: >=3.13
6
6
  Description-Content-Type: text/markdown
@@ -4,11 +4,18 @@ from importlib.metadata import PackageNotFoundError, version
4
4
  try:
5
5
  __version__ = version("bb_api")
6
6
  except PackageNotFoundError:
7
- __version__ = "0.5.0"
7
+ __version__ = "0.5.1"
8
8
 
9
9
 
10
10
  from .common import Ambiente
11
- from .accountability import AccountabilityV3RepasseAPI, AccountabilityV3ControleAPI
11
+ from .accountability import (
12
+ MAX_DIAS_EXTRATO,
13
+ AccountabilityV3RepasseAPI,
14
+ AccountabilityV3ControleAPI,
15
+ ExtratoError,
16
+ IntervaloLongoDemaisError,
17
+ SemLancamentosError,
18
+ )
12
19
  from .sia import (
13
20
  BBSiaAPI,
14
21
  CredenciaisNecessariasError,
@@ -21,11 +28,15 @@ from .gestao_agil import (
21
28
  )
22
29
 
23
30
  __all__ = [
31
+ "MAX_DIAS_EXTRATO",
24
32
  "Ambiente",
25
33
  "AccountabilityV3RepasseAPI",
26
34
  "AccountabilityV3ControleAPI",
27
35
  "BBSiaAPI",
28
36
  "CredenciaisNecessariasError",
37
+ "ExtratoError",
38
+ "IntervaloLongoDemaisError",
39
+ "SemLancamentosError",
29
40
  "FalhaDownload",
30
41
  "ResultadoDownloads",
31
42
  "parse_retorno_abertura_massificada",
@@ -9,6 +9,74 @@ import requests
9
9
  import bb_api.common as common
10
10
 
11
11
 
12
+ MAX_DIAS_EXTRATO = 31
13
+ """Maior intervalo, em dias corridos, aceito numa consulta de extrato.
14
+
15
+ ``startDate`` e ``endDate`` podem distar no máximo esse tanto: 31 dias passam,
16
+ 32 devolvem ``400``. Períodos maiores precisam ser fatiados pelo chamador.
17
+ """
18
+
19
+ _ERRO_SEM_LANCAMENTOS = "não existem lançamentos"
20
+ _ERRO_INTERVALO_LONGO = "maior do que 31 dias"
21
+
22
+
23
+ class ExtratoError(Exception):
24
+ """Erro devolvido pela API ao consultar o extrato do órgão repassador.
25
+
26
+ Carrega o status HTTP e a mensagem originais do Banco do Brasil, porque a
27
+ API usa ``400`` tanto para falha de verdade quanto para situações normais.
28
+ """
29
+
30
+ status_code: int
31
+ mensagem: str
32
+
33
+ def __init__(self, status_code: int, mensagem: str) -> None:
34
+ detalhe = f"(HTTP {status_code}): {mensagem}"
35
+ super().__init__(f"Não foi possível reaver o extrato do órgão repassador {detalhe}")
36
+ self.status_code = status_code
37
+ self.mensagem = mensagem
38
+
39
+
40
+ class SemLancamentosError(ExtratoError):
41
+ """A conta não tem lançamento nenhum no período consultado.
42
+
43
+ A API responde ``400`` nesse caso, e não ``200`` com uma lista vazia, então
44
+ esse resultado normal chega como erro e precisa ser separado de uma falha —
45
+ senão uma conta parada vira indistinguível de uma consulta quebrada.
46
+ """
47
+
48
+
49
+ class IntervaloLongoDemaisError(ExtratoError):
50
+ """O intervalo pedido passa dos ``MAX_DIAS_EXTRATO`` dias corridos."""
51
+
52
+
53
+ def _mensagem_de_erro(res: requests.Response) -> str:
54
+ try:
55
+ corpo = cast("object", res.json())
56
+ except ValueError:
57
+ return res.text.strip()
58
+
59
+ if not isinstance(corpo, dict):
60
+ return res.text.strip()
61
+
62
+ campos = cast("dict[str, object]", corpo)
63
+ for chave in ("error", "message", "mensagem", "erro"):
64
+ valor = campos.get(chave)
65
+ if isinstance(valor, str) and valor:
66
+ return valor
67
+ return res.text.strip()
68
+
69
+
70
+ def _erro_extrato(res: requests.Response) -> ExtratoError:
71
+ mensagem = _mensagem_de_erro(res)
72
+ normalizada = mensagem.casefold()
73
+ if _ERRO_SEM_LANCAMENTOS in normalizada:
74
+ return SemLancamentosError(res.status_code, mensagem)
75
+ if _ERRO_INTERVALO_LONGO in normalizada:
76
+ return IntervaloLongoDemaisError(res.status_code, mensagem)
77
+ return ExtratoError(res.status_code, mensagem)
78
+
79
+
12
80
  class _AccountabilityV3BaseAPI:
13
81
  _app_key: str
14
82
  _client_id: str
@@ -224,7 +292,7 @@ class AccountabilityV3RepasseAPI(_AccountabilityV3BaseAPI):
224
292
  )
225
293
 
226
294
  if res.status_code != 200:
227
- raise Exception("Não foi possível reaver o extrato do órgão repassador.")
295
+ raise _erro_extrato(res)
228
296
 
229
297
  res = common.parse_json_object(res)
230
298
 
@@ -1233,7 +1301,7 @@ class AccountabilityV3ControleAPI(_AccountabilityV3BaseAPI):
1233
1301
  )
1234
1302
 
1235
1303
  if res.status_code != 200:
1236
- raise Exception("Não foi possível reaver o extrato do órgão repassador.")
1304
+ raise _erro_extrato(res)
1237
1305
 
1238
1306
  res = common.parse_json_object(res)
1239
1307
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bb_api
3
- Version: 0.5.0
3
+ Version: 0.5.1
4
4
  Summary: Wrapper da API do Banco do Brasil.
5
5
  Requires-Python: >=3.13
6
6
  Description-Content-Type: text/markdown
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "bb_api"
3
- version = "0.5.0"
3
+ version = "0.5.1"
4
4
  description = "Wrapper da API do Banco do Brasil."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.13"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes