biatoolkit 1.2.3__tar.gz → 1.2.4__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: biatoolkit
3
- Version: 1.2.3
3
+ Version: 1.2.4
4
4
  Summary: Biblioteca para desenvolvedores que utilizam o BiaAgentBuilder
5
5
  Author: Bia Platform Team
6
6
  Author-email: data.platform@sankhya.com.br
@@ -37,7 +37,6 @@ A classe `BiaClient` encapsula um cliente HTTP assíncrono para comunicação co
37
37
  (Model Context Protocol).
38
38
 
39
39
  Ela esconde toda a complexidade de:
40
- - Conexão HTTP streamable
41
40
  - Inicialização de sessões MCP
42
41
  - Execução de tools
43
42
 
@@ -49,7 +48,6 @@ Ela esconde toda a complexidade de:
49
48
  - **call_tool(tool_name, params=None)**
50
49
  - Executa uma ferramenta específica disponível no servidor MCP.
51
50
 
52
- ---
53
51
 
54
52
  ### BiaUtil
55
53
 
@@ -64,7 +62,6 @@ permitindo acesso fácil a:
64
62
  - Recebe uma instância de `FastMCP` para acessar o contexto da requisição atual.
65
63
 
66
64
  - **get_header()**
67
- - Extrai e retorna os headers customizados do runtime.
68
65
  - Retorna um objeto `Header` com os campos:
69
66
  - `current_host`: Host do ERP no qual o copilot está em execução.
70
67
  - `user_email`: Email do usuário autenticado.
@@ -75,7 +72,6 @@ permitindo acesso fácil a:
75
72
  - `iam_user_id`: ID do usuário do BIA IAM.
76
73
  - `gateway_token`: Token primário do Sankhya API Gateway.
77
74
 
78
- - **get_parameter(parameter_name)**
79
75
  - Recupera parâmetros sensíveis seguindo a ordem:
80
76
  1. Variáveis de ambiente do sistema
81
77
  2. AWS SSM Parameter Store (fallback)
@@ -84,7 +80,6 @@ permitindo acesso fácil a:
84
80
  - O SSM só é consultado se o parâmetro **não existir** nas variáveis de ambiente.
85
81
  - Em produção, a busca no SSM depende do header
86
82
  `X-Amzn-Bedrock-AgentCore-Runtime-Custom-prefix`.
87
- - Se esse header não estiver presente, o método retorna `None`.
88
83
 
89
84
  ---
90
85
 
@@ -95,7 +90,6 @@ Nesta seção você encontrará uma breve descrição de como utilizar os princi
95
90
  ### **Criando um MCP Server**
96
91
 
97
92
  Primeiro, instale os pacotes **MCP** e **Bia Toolkit**.
98
-
99
93
  ```bash
100
94
  pip install mcp biatoolkit
101
95
  ```
@@ -108,9 +102,107 @@ import json
108
102
 
109
103
  mcp = FastMCP(host="0.0.0.0", stateless_http=True)
110
104
 
111
- @mcp.tool()
112
105
  def listar() -> str:
113
- """Retorna uma lista de exemplo"""
106
+
107
+ O Bia Toolkit oferece integração pronta para consumo de serviços HTTP da plataforma Sankhya (ou gateway), com autenticação via JSESSIONID e configuração de timeouts/retries via variáveis de ambiente.
108
+
109
+ ### Objetivo
110
+
111
+ - Facilitar chamadas autenticadas a serviços Sankhya sem que o desenvolvedor precise lidar com autenticação, headers ou gerenciamento de sessão HTTP.
112
+ - Fornecer métodos prontos para chamadas genéricas (`call_json`) e para consultas a views (`load_view`).
113
+ - Permitir uso estático compatível com scaffolds legados via `Sankhya.Call(...)`.
114
+
115
+ ### Configuração
116
+
117
+ - O caminho do serviço (`/mge/service.sbr`) é fixo no toolkit.
118
+ - O parâmetro `base_url` é obrigatório e pode ser passado explicitamente ou extraído automaticamente do header do runtime (`current_host` via `BiaUtil`).
119
+ - Não existe mais configuração via variável de ambiente para base_url ou service_path.
120
+ - As variáveis de ambiente opcionais são apenas para timeout, retries e SSL:
121
+ - `SANKHYA_TIMEOUT_CONNECT`: timeout de conexão (default: 3.05)
122
+ - `SANKHYA_TIMEOUT_READ`: timeout de leitura (default: 12)
123
+ - `SANKHYA_RETRIES_TOTAL`: número de tentativas em falha (default: 3)
124
+ - `SANKHYA_RETRY_BACKOFF`: backoff entre tentativas (default: 0.5)
125
+ - `SANKHYA_VERIFY_SSL`: se valida SSL (default: "1")
126
+
127
+ ### Principais classes e métodos
128
+
129
+ - **SankhyaSettings**: Dataclass de configuração de timeouts/retries/SSL. Use `SankhyaSettings.from_env()` para obter as configurações do ambiente.
130
+ - **Sankhya**: Classe principal de integração. Permite instanciar com contexto MCP (`FastMCP`) ou usar métodos estáticos.
131
+ - `call_json(...)`: Realiza chamada HTTP autenticada, retorna JSON. Veja detalhes dos parâmetros abaixo.
132
+ - `load_view(...)`: Helper para consultas a views Sankhya (`CRUDServiceProvider.loadView`). Veja detalhes dos parâmetros abaixo.
133
+ - `Call(...)`: Método estático compatível com scaffolds legados. Veja detalhes dos parâmetros abaixo.
134
+ ### Parâmetros dos métodos principais
135
+
136
+ #### `call_json`
137
+
138
+ | Parâmetro | Obrigatório | Descrição |
139
+ |-------------------|-------------|-----------|
140
+ | payload | Não | Dicionário enviado como corpo da requisição (POST). Pode ser None. |
141
+ | jsessionid | Não | Token de sessão JSESSIONID. Se não informado, tenta extrair do header do runtime (via MCP/BiaUtil). |
142
+ | url | Não | URL completa para chamada. Se informado, ignora base_url. |
143
+ | base_url | Sim* | Base URL do serviço Sankhya (ex: https://meu.sankhya.com.br). Obrigatório se não estiver em contexto MCP (header). |
144
+ | query | Não | Querystring adicional (ex: serviceName=...&outputType=json). |
145
+ | method | Não | "POST" (default) ou "GET". |
146
+ | extra_headers | Não | Dicionário de headers adicionais. |
147
+ | timeout | Não | Tupla (connect, read) para sobrescrever timeout padrão. |
148
+ | raise_for_http_error | Não | Se True (default), lança SankhyaHTTPError em erro HTTP. |
149
+
150
+ *Se não passar base_url, o método tentará extrair automaticamente do header do runtime (MCP) se disponível. Caso contrário, será obrigatório.
151
+
152
+ #### `load_view`
153
+
154
+ | Parâmetro | Obrigatório | Descrição |
155
+ |-------------------|-------------|-----------|
156
+ | view_name | Sim | Nome da view no Sankhya. |
157
+ | where_sql | Sim | Cláusula WHERE (string). |
158
+ | fields | Não | Campos a retornar (string). Default: "*". |
159
+ | jsessionid | Não | Token de sessão JSESSIONID. Se não informado, tenta extrair do header do runtime (via MCP/BiaUtil). |
160
+ | url | Não | URL completa opcional (override). |
161
+ | base_url | Não* | Base URL do serviço Sankhya. Se não informado, tenta extrair do header do runtime (current_host). |
162
+ | output_type | Não | "json" (default). |
163
+ | extra_headers | Não | Dicionário de headers adicionais. |
164
+
165
+ *Se não passar base_url, o método tentará extrair automaticamente do header do runtime (MCP) via BiaUtil. Caso não consiga, lança erro.
166
+
167
+ #### `Call`
168
+
169
+ | Parâmetro | Obrigatório | Descrição |
170
+ |-------------------|-------------|-----------|
171
+ | jsessionID | Não | Token de sessão JSESSIONID. Se não informado, tenta extrair do header do runtime (via MCP/BiaUtil). |
172
+ | payload | Não | Dicionário enviado como corpo da requisição. |
173
+ | mcp | Não | Instância opcional do FastMCP para contexto do runtime. |
174
+ | url | Não | URL completa (opcional). |
175
+ | base_url | Sim* | Base URL do serviço Sankhya. Obrigatório se não estiver em contexto MCP (header). |
176
+ | query | Não | Querystring adicional (opcional). |
177
+ | method | Não | "POST" (default) ou "GET". |
178
+ | extra_headers | Não | Dicionário de headers adicionais. |
179
+
180
+ *Se não passar base_url, o método tentará extrair automaticamente do header do runtime (MCP) se disponível. Caso contrário, será obrigatório.
181
+
182
+ **Resumo:** Sempre que possível, o toolkit resolve automaticamente base_url e jsessionid do contexto MCP (headers). Se não estiver rodando em MCP, passe base_url explicitamente.
183
+ - **SankhyaHTTPError**: Exceção lançada em caso de erro HTTP (status != 200), contendo status_code e response_text.
184
+
185
+ ### Exemplo de uso (instanciado)
186
+
187
+ ```python
188
+ from biatoolkit.sankhya_call import Sankhya
189
+ sk = Sankhya(mcp=mcp)
190
+ result = sk.load_view("BIA_VW_MB_RULES", "CODPROD_A = 123", fields="*")
191
+ # O base_url será extraído automaticamente do header do runtime (current_host)
192
+ ```
193
+
194
+ ### Exemplo de uso (estático)
195
+
196
+ ```python
197
+ from biatoolkit.sankhya_call import Sankhya
198
+ result = Sankhya.Call(jsessionID="...", payload={...}, base_url="https://meu.sankhya.com.br", query="serviceName=...&outputType=json")
199
+ ```
200
+
201
+ ### Observações
202
+
203
+ - O JSESSIONID pode ser passado explicitamente ou extraído automaticamente do header do runtime (se rodando em MCP Server).
204
+ - O método `load_view` facilita consultas a views Sankhya, montando o payload e a querystring automaticamente, e resolve o base_url do header se não for passado.
205
+ - O método `call_json` permite chamadas genéricas a qualquer serviço Sankhya, com controle total sobre headers, método HTTP, payload e querystring, mas exige base_url explícito se não estiver em contexto MCP.
114
206
  exemplo = {
115
207
  "itens": [
116
208
  {"id": 1, "nome": "Item 1"},
@@ -348,91 +440,6 @@ O método `get_parameter(parameter_name: str)` busca o parâmetro informado em d
348
440
  - Um arquivo `.env` para testes locais.
349
441
  - No cofre de segredos do Bia Agent Builder para usar em ambiente produtivo.
350
442
 
351
-
352
- ---
353
-
354
- ## Validação e Coerção de Dados
355
-
356
- O Bia Toolkit oferece funções utilitárias para normalização, sanitização e coerção de dados, facilitando o consumo seguro de entradas vindas de APIs, headers, payloads e integrações legadas.
357
-
358
-
359
- ### Validação de Dados (`biatoolkit.validation.validation`)
360
-
361
- Utilize a classe **BiaValidation** para acessar as funções de validação de forma padronizada:
362
-
363
- - **BiaValidation.parse_int_list(value, dedupe=True, keep_order=True)**
364
- - Normaliza um valor arbitrário em uma lista de inteiros.
365
- - Suporta: None, int, str (extrai números), list/tuple (recursivo).
366
- - Ignora valores inválidos.
367
- - Deduplica e mantém ordem por padrão.
368
- - Exemplo:
369
- ```python
370
- from biatoolkit.validation.validation import BiaValidation
371
- BiaValidation.parse_int_list("SKU=300231 x2") # [300231, 2]
372
- BiaValidation.parse_int_list([1, 2, 1, 3], dedupe=False) # [1, 2, 1, 3]
373
- ```
374
-
375
- - **BiaValidation.sanitize_like(value, max_len=80, upper=True)**
376
- - Sanitiza texto para uso seguro em filtros LIKE/search SQL.
377
- - Remove caracteres fora da allowlist, limita tamanho, escapa aspas simples, %, _ e normaliza espaços.
378
- - Converte para maiúsculas por padrão.
379
- - Exemplo:
380
- ```python
381
- from biatoolkit.validation.validation import BiaValidation
382
- BiaValidation.sanitize_like("O'Reilly") # "O''REILLY"
383
- BiaValidation.sanitize_like("100%_OK") # "100\\%\\_OK"
384
- ```
385
-
386
-
387
- ### Coerção de Dados (`biatoolkit.validation.coercion`)
388
-
389
- Utilize a classe **BiaCoercion** para acessar as funções de coerção de forma padronizada:
390
-
391
- - **BiaCoercion.ensure_list(value)**
392
- - Garante que o valor seja retornado como lista.
393
- - None → [], list → list, tuple/set → list, dict → [dict], outro → [valor].
394
- - Exemplo:
395
- ```python
396
- from biatoolkit.validation.coercion import BiaCoercion
397
- BiaCoercion.ensure_list(None) # []
398
- BiaCoercion.ensure_list({"a": 1}) # [{"a": 1}]
399
- BiaCoercion.ensure_list(5) # [5]
400
- ```
401
-
402
- - **BiaCoercion.unwrap_dollar_value(value)**
403
- - Desembrulha valores no formato {"$": ...} (comum em integrações legadas).
404
- - Exemplo:
405
- ```python
406
- from biatoolkit.validation.coercion import BiaCoercion
407
- BiaCoercion.unwrap_dollar_value({"$": 123}) # 123
408
- BiaCoercion.unwrap_dollar_value("abc") # "abc"
409
- ```
410
-
411
- - **BiaCoercion.to_int(value, default=0)**
412
- - Converte valor para int de forma segura.
413
- - None, "", bool, NaN/inf → default.
414
- - Aceita strings numéricas, floats (trunca), etc.
415
- - Exemplo:
416
- ```python
417
- from biatoolkit.validation.coercion import BiaCoercion
418
- BiaCoercion.to_int(" 42 ") # 42
419
- BiaCoercion.to_int(None, default=-1) # -1
420
- ```
421
-
422
- - **BiaCoercion.to_float(value, default=0.0)**
423
- - Converte valor para float de forma segura.
424
- - None, "", bool, NaN/inf → default.
425
- - Aceita strings com vírgula decimal.
426
- - Exemplo:
427
- ```python
428
- from biatoolkit.validation.coercion import BiaCoercion
429
- BiaCoercion.to_float("12,34") # 12.34
430
- BiaCoercion.to_float("abc", default=-1.0) # -1.0
431
- ```
432
-
433
-
434
- Essas funções são úteis para garantir robustez e previsibilidade ao tratar dados vindos de múltiplas fontes, reduzindo erros e if/else espalhados pelo código.
435
-
436
443
  ---
437
444
 
438
445
  ## Integração com Sankhya (`biatoolkit.sankhya_call`)
@@ -271,6 +271,7 @@ class Sankhya:
271
271
 
272
272
  # Resolve o token de sessão (JSESSIONID)
273
273
  sid = self._resolve_jsessionid(jsessionid)
274
+
274
275
  # Para mgeSession na query, usar só a primeira parte antes do ponto
275
276
  sid_query = sid.split(".", 1)[0] if "." in sid else sid
276
277
 
@@ -281,6 +282,7 @@ class Sankhya:
281
282
  query_parts.append(f"mgeSession={sid_query}")
282
283
  final_query = "&".join(query_parts)
283
284
 
285
+
284
286
  # Monta a URL final da requisição
285
287
  final_url = build_url(url=url, query=final_query, base_url=base_url)
286
288
  print("FINAL URL:", final_url)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: biatoolkit
3
- Version: 1.2.3
3
+ Version: 1.2.4
4
4
  Summary: Biblioteca para desenvolvedores que utilizam o BiaAgentBuilder
5
5
  Author: Bia Platform Team
6
6
  Author-email: data.platform@sankhya.com.br
@@ -37,7 +37,6 @@ A classe `BiaClient` encapsula um cliente HTTP assíncrono para comunicação co
37
37
  (Model Context Protocol).
38
38
 
39
39
  Ela esconde toda a complexidade de:
40
- - Conexão HTTP streamable
41
40
  - Inicialização de sessões MCP
42
41
  - Execução de tools
43
42
 
@@ -49,7 +48,6 @@ Ela esconde toda a complexidade de:
49
48
  - **call_tool(tool_name, params=None)**
50
49
  - Executa uma ferramenta específica disponível no servidor MCP.
51
50
 
52
- ---
53
51
 
54
52
  ### BiaUtil
55
53
 
@@ -64,7 +62,6 @@ permitindo acesso fácil a:
64
62
  - Recebe uma instância de `FastMCP` para acessar o contexto da requisição atual.
65
63
 
66
64
  - **get_header()**
67
- - Extrai e retorna os headers customizados do runtime.
68
65
  - Retorna um objeto `Header` com os campos:
69
66
  - `current_host`: Host do ERP no qual o copilot está em execução.
70
67
  - `user_email`: Email do usuário autenticado.
@@ -75,7 +72,6 @@ permitindo acesso fácil a:
75
72
  - `iam_user_id`: ID do usuário do BIA IAM.
76
73
  - `gateway_token`: Token primário do Sankhya API Gateway.
77
74
 
78
- - **get_parameter(parameter_name)**
79
75
  - Recupera parâmetros sensíveis seguindo a ordem:
80
76
  1. Variáveis de ambiente do sistema
81
77
  2. AWS SSM Parameter Store (fallback)
@@ -84,7 +80,6 @@ permitindo acesso fácil a:
84
80
  - O SSM só é consultado se o parâmetro **não existir** nas variáveis de ambiente.
85
81
  - Em produção, a busca no SSM depende do header
86
82
  `X-Amzn-Bedrock-AgentCore-Runtime-Custom-prefix`.
87
- - Se esse header não estiver presente, o método retorna `None`.
88
83
 
89
84
  ---
90
85
 
@@ -95,7 +90,6 @@ Nesta seção você encontrará uma breve descrição de como utilizar os princi
95
90
  ### **Criando um MCP Server**
96
91
 
97
92
  Primeiro, instale os pacotes **MCP** e **Bia Toolkit**.
98
-
99
93
  ```bash
100
94
  pip install mcp biatoolkit
101
95
  ```
@@ -108,9 +102,107 @@ import json
108
102
 
109
103
  mcp = FastMCP(host="0.0.0.0", stateless_http=True)
110
104
 
111
- @mcp.tool()
112
105
  def listar() -> str:
113
- """Retorna uma lista de exemplo"""
106
+
107
+ O Bia Toolkit oferece integração pronta para consumo de serviços HTTP da plataforma Sankhya (ou gateway), com autenticação via JSESSIONID e configuração de timeouts/retries via variáveis de ambiente.
108
+
109
+ ### Objetivo
110
+
111
+ - Facilitar chamadas autenticadas a serviços Sankhya sem que o desenvolvedor precise lidar com autenticação, headers ou gerenciamento de sessão HTTP.
112
+ - Fornecer métodos prontos para chamadas genéricas (`call_json`) e para consultas a views (`load_view`).
113
+ - Permitir uso estático compatível com scaffolds legados via `Sankhya.Call(...)`.
114
+
115
+ ### Configuração
116
+
117
+ - O caminho do serviço (`/mge/service.sbr`) é fixo no toolkit.
118
+ - O parâmetro `base_url` é obrigatório e pode ser passado explicitamente ou extraído automaticamente do header do runtime (`current_host` via `BiaUtil`).
119
+ - Não existe mais configuração via variável de ambiente para base_url ou service_path.
120
+ - As variáveis de ambiente opcionais são apenas para timeout, retries e SSL:
121
+ - `SANKHYA_TIMEOUT_CONNECT`: timeout de conexão (default: 3.05)
122
+ - `SANKHYA_TIMEOUT_READ`: timeout de leitura (default: 12)
123
+ - `SANKHYA_RETRIES_TOTAL`: número de tentativas em falha (default: 3)
124
+ - `SANKHYA_RETRY_BACKOFF`: backoff entre tentativas (default: 0.5)
125
+ - `SANKHYA_VERIFY_SSL`: se valida SSL (default: "1")
126
+
127
+ ### Principais classes e métodos
128
+
129
+ - **SankhyaSettings**: Dataclass de configuração de timeouts/retries/SSL. Use `SankhyaSettings.from_env()` para obter as configurações do ambiente.
130
+ - **Sankhya**: Classe principal de integração. Permite instanciar com contexto MCP (`FastMCP`) ou usar métodos estáticos.
131
+ - `call_json(...)`: Realiza chamada HTTP autenticada, retorna JSON. Veja detalhes dos parâmetros abaixo.
132
+ - `load_view(...)`: Helper para consultas a views Sankhya (`CRUDServiceProvider.loadView`). Veja detalhes dos parâmetros abaixo.
133
+ - `Call(...)`: Método estático compatível com scaffolds legados. Veja detalhes dos parâmetros abaixo.
134
+ ### Parâmetros dos métodos principais
135
+
136
+ #### `call_json`
137
+
138
+ | Parâmetro | Obrigatório | Descrição |
139
+ |-------------------|-------------|-----------|
140
+ | payload | Não | Dicionário enviado como corpo da requisição (POST). Pode ser None. |
141
+ | jsessionid | Não | Token de sessão JSESSIONID. Se não informado, tenta extrair do header do runtime (via MCP/BiaUtil). |
142
+ | url | Não | URL completa para chamada. Se informado, ignora base_url. |
143
+ | base_url | Sim* | Base URL do serviço Sankhya (ex: https://meu.sankhya.com.br). Obrigatório se não estiver em contexto MCP (header). |
144
+ | query | Não | Querystring adicional (ex: serviceName=...&outputType=json). |
145
+ | method | Não | "POST" (default) ou "GET". |
146
+ | extra_headers | Não | Dicionário de headers adicionais. |
147
+ | timeout | Não | Tupla (connect, read) para sobrescrever timeout padrão. |
148
+ | raise_for_http_error | Não | Se True (default), lança SankhyaHTTPError em erro HTTP. |
149
+
150
+ *Se não passar base_url, o método tentará extrair automaticamente do header do runtime (MCP) se disponível. Caso contrário, será obrigatório.
151
+
152
+ #### `load_view`
153
+
154
+ | Parâmetro | Obrigatório | Descrição |
155
+ |-------------------|-------------|-----------|
156
+ | view_name | Sim | Nome da view no Sankhya. |
157
+ | where_sql | Sim | Cláusula WHERE (string). |
158
+ | fields | Não | Campos a retornar (string). Default: "*". |
159
+ | jsessionid | Não | Token de sessão JSESSIONID. Se não informado, tenta extrair do header do runtime (via MCP/BiaUtil). |
160
+ | url | Não | URL completa opcional (override). |
161
+ | base_url | Não* | Base URL do serviço Sankhya. Se não informado, tenta extrair do header do runtime (current_host). |
162
+ | output_type | Não | "json" (default). |
163
+ | extra_headers | Não | Dicionário de headers adicionais. |
164
+
165
+ *Se não passar base_url, o método tentará extrair automaticamente do header do runtime (MCP) via BiaUtil. Caso não consiga, lança erro.
166
+
167
+ #### `Call`
168
+
169
+ | Parâmetro | Obrigatório | Descrição |
170
+ |-------------------|-------------|-----------|
171
+ | jsessionID | Não | Token de sessão JSESSIONID. Se não informado, tenta extrair do header do runtime (via MCP/BiaUtil). |
172
+ | payload | Não | Dicionário enviado como corpo da requisição. |
173
+ | mcp | Não | Instância opcional do FastMCP para contexto do runtime. |
174
+ | url | Não | URL completa (opcional). |
175
+ | base_url | Sim* | Base URL do serviço Sankhya. Obrigatório se não estiver em contexto MCP (header). |
176
+ | query | Não | Querystring adicional (opcional). |
177
+ | method | Não | "POST" (default) ou "GET". |
178
+ | extra_headers | Não | Dicionário de headers adicionais. |
179
+
180
+ *Se não passar base_url, o método tentará extrair automaticamente do header do runtime (MCP) se disponível. Caso contrário, será obrigatório.
181
+
182
+ **Resumo:** Sempre que possível, o toolkit resolve automaticamente base_url e jsessionid do contexto MCP (headers). Se não estiver rodando em MCP, passe base_url explicitamente.
183
+ - **SankhyaHTTPError**: Exceção lançada em caso de erro HTTP (status != 200), contendo status_code e response_text.
184
+
185
+ ### Exemplo de uso (instanciado)
186
+
187
+ ```python
188
+ from biatoolkit.sankhya_call import Sankhya
189
+ sk = Sankhya(mcp=mcp)
190
+ result = sk.load_view("BIA_VW_MB_RULES", "CODPROD_A = 123", fields="*")
191
+ # O base_url será extraído automaticamente do header do runtime (current_host)
192
+ ```
193
+
194
+ ### Exemplo de uso (estático)
195
+
196
+ ```python
197
+ from biatoolkit.sankhya_call import Sankhya
198
+ result = Sankhya.Call(jsessionID="...", payload={...}, base_url="https://meu.sankhya.com.br", query="serviceName=...&outputType=json")
199
+ ```
200
+
201
+ ### Observações
202
+
203
+ - O JSESSIONID pode ser passado explicitamente ou extraído automaticamente do header do runtime (se rodando em MCP Server).
204
+ - O método `load_view` facilita consultas a views Sankhya, montando o payload e a querystring automaticamente, e resolve o base_url do header se não for passado.
205
+ - O método `call_json` permite chamadas genéricas a qualquer serviço Sankhya, com controle total sobre headers, método HTTP, payload e querystring, mas exige base_url explícito se não estiver em contexto MCP.
114
206
  exemplo = {
115
207
  "itens": [
116
208
  {"id": 1, "nome": "Item 1"},
@@ -348,91 +440,6 @@ O método `get_parameter(parameter_name: str)` busca o parâmetro informado em d
348
440
  - Um arquivo `.env` para testes locais.
349
441
  - No cofre de segredos do Bia Agent Builder para usar em ambiente produtivo.
350
442
 
351
-
352
- ---
353
-
354
- ## Validação e Coerção de Dados
355
-
356
- O Bia Toolkit oferece funções utilitárias para normalização, sanitização e coerção de dados, facilitando o consumo seguro de entradas vindas de APIs, headers, payloads e integrações legadas.
357
-
358
-
359
- ### Validação de Dados (`biatoolkit.validation.validation`)
360
-
361
- Utilize a classe **BiaValidation** para acessar as funções de validação de forma padronizada:
362
-
363
- - **BiaValidation.parse_int_list(value, dedupe=True, keep_order=True)**
364
- - Normaliza um valor arbitrário em uma lista de inteiros.
365
- - Suporta: None, int, str (extrai números), list/tuple (recursivo).
366
- - Ignora valores inválidos.
367
- - Deduplica e mantém ordem por padrão.
368
- - Exemplo:
369
- ```python
370
- from biatoolkit.validation.validation import BiaValidation
371
- BiaValidation.parse_int_list("SKU=300231 x2") # [300231, 2]
372
- BiaValidation.parse_int_list([1, 2, 1, 3], dedupe=False) # [1, 2, 1, 3]
373
- ```
374
-
375
- - **BiaValidation.sanitize_like(value, max_len=80, upper=True)**
376
- - Sanitiza texto para uso seguro em filtros LIKE/search SQL.
377
- - Remove caracteres fora da allowlist, limita tamanho, escapa aspas simples, %, _ e normaliza espaços.
378
- - Converte para maiúsculas por padrão.
379
- - Exemplo:
380
- ```python
381
- from biatoolkit.validation.validation import BiaValidation
382
- BiaValidation.sanitize_like("O'Reilly") # "O''REILLY"
383
- BiaValidation.sanitize_like("100%_OK") # "100\\%\\_OK"
384
- ```
385
-
386
-
387
- ### Coerção de Dados (`biatoolkit.validation.coercion`)
388
-
389
- Utilize a classe **BiaCoercion** para acessar as funções de coerção de forma padronizada:
390
-
391
- - **BiaCoercion.ensure_list(value)**
392
- - Garante que o valor seja retornado como lista.
393
- - None → [], list → list, tuple/set → list, dict → [dict], outro → [valor].
394
- - Exemplo:
395
- ```python
396
- from biatoolkit.validation.coercion import BiaCoercion
397
- BiaCoercion.ensure_list(None) # []
398
- BiaCoercion.ensure_list({"a": 1}) # [{"a": 1}]
399
- BiaCoercion.ensure_list(5) # [5]
400
- ```
401
-
402
- - **BiaCoercion.unwrap_dollar_value(value)**
403
- - Desembrulha valores no formato {"$": ...} (comum em integrações legadas).
404
- - Exemplo:
405
- ```python
406
- from biatoolkit.validation.coercion import BiaCoercion
407
- BiaCoercion.unwrap_dollar_value({"$": 123}) # 123
408
- BiaCoercion.unwrap_dollar_value("abc") # "abc"
409
- ```
410
-
411
- - **BiaCoercion.to_int(value, default=0)**
412
- - Converte valor para int de forma segura.
413
- - None, "", bool, NaN/inf → default.
414
- - Aceita strings numéricas, floats (trunca), etc.
415
- - Exemplo:
416
- ```python
417
- from biatoolkit.validation.coercion import BiaCoercion
418
- BiaCoercion.to_int(" 42 ") # 42
419
- BiaCoercion.to_int(None, default=-1) # -1
420
- ```
421
-
422
- - **BiaCoercion.to_float(value, default=0.0)**
423
- - Converte valor para float de forma segura.
424
- - None, "", bool, NaN/inf → default.
425
- - Aceita strings com vírgula decimal.
426
- - Exemplo:
427
- ```python
428
- from biatoolkit.validation.coercion import BiaCoercion
429
- BiaCoercion.to_float("12,34") # 12.34
430
- BiaCoercion.to_float("abc", default=-1.0) # -1.0
431
- ```
432
-
433
-
434
- Essas funções são úteis para garantir robustez e previsibilidade ao tratar dados vindos de múltiplas fontes, reduzindo erros e if/else espalhados pelo código.
435
-
436
443
  ---
437
444
 
438
445
  ## Integração com Sankhya (`biatoolkit.sankhya_call`)
@@ -11,7 +11,4 @@ biatoolkit.egg-info/SOURCES.txt
11
11
  biatoolkit.egg-info/dependency_links.txt
12
12
  biatoolkit.egg-info/top_level.txt
13
13
  biatoolkit/schema/__init__.py
14
- biatoolkit/schema/header.py
15
- biatoolkit/validation/__init__.py
16
- biatoolkit/validation/coercion.py
17
- biatoolkit/validation/validation.py
14
+ biatoolkit/schema/header.py
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
2
2
 
3
3
  setup(
4
4
  name='biatoolkit',
5
- version='1.2.3',
5
+ version='1.2.4',
6
6
  packages=find_packages(),
7
7
  install_requires=[],
8
8
  author='Bia Platform Team',
File without changes
@@ -1,175 +0,0 @@
1
- # biatoolkit/validation/coercion.py
2
-
3
- from __future__ import annotations
4
-
5
- from typing import Any, Iterable, Mapping, Optional
6
- import math
7
-
8
-
9
- def ensure_list(value: Any) -> list:
10
- """
11
- Normaliza um valor para sempre retornar uma lista.
12
-
13
- Regras:
14
- - None -> []
15
- - list -> a própria lista
16
- - tuple/set -> list(value)
17
- - dict (ou Mapping) -> [value] (não "explode" dict em chaves)
18
- - qualquer outro -> [value]
19
-
20
- Por que existe:
21
- - Muitas APIs retornam ora um item único (dict), ora uma lista.
22
- - Este helper padroniza o consumo e reduz if/else espalhado.
23
-
24
- Args:
25
- value: qualquer valor.
26
-
27
- Returns:
28
- list: lista normalizada.
29
- """
30
- if value is None:
31
- return []
32
-
33
- if isinstance(value, list):
34
- return value
35
-
36
- if isinstance(value, (tuple, set)):
37
- return list(value)
38
-
39
- # Dict/Mapping deve ser tratado como item único, não iterável de chaves.
40
- if isinstance(value, Mapping):
41
- return [value]
42
-
43
- return [value]
44
-
45
-
46
- def unwrap_dollar_value(value: Any) -> Any:
47
- """
48
- "Desembrulha" valores no formato {"$": "..."} (comum em integrações legadas).
49
-
50
- Exemplo:
51
- {"$": "123"} -> "123"
52
- {"$": 123} -> 123
53
-
54
- Se não for dict com a chave "$", retorna o valor original.
55
-
56
- Args:
57
- value: valor de entrada.
58
-
59
- Returns:
60
- Any: valor desembrulhado ou original.
61
- """
62
- if isinstance(value, dict) and "$" in value:
63
- return value.get("$")
64
- return value
65
-
66
-
67
- def to_int(value: Any, default: int = 0) -> int:
68
- """
69
- Converte um valor para int de forma segura.
70
-
71
- Regras:
72
- - None / "" -> default
73
- - strings com espaços são aceitas (" 12 ")
74
- - strings numéricas com sinal são aceitas ("-3")
75
- - floats numéricos -> int(value) (trunca)
76
- - NaN/inf -> default
77
-
78
- Obs:
79
- - Não tenta "extrair número do meio do texto" (isso é responsabilidade
80
- de parse específico, ex: parse_int_list).
81
-
82
- Args:
83
- value: valor a converter.
84
- default: fallback.
85
-
86
- Returns:
87
- int: convertido ou default.
88
- """
89
- try:
90
- if value is None:
91
- return default
92
-
93
- if isinstance(value, bool):
94
- # Evita True->1 / False->0 de forma "surpresa"
95
- return default
96
-
97
- if isinstance(value, str):
98
- s = value.strip()
99
- if s == "":
100
- return default
101
- return int(s)
102
-
103
- if isinstance(value, float):
104
- if math.isnan(value) or math.isinf(value):
105
- return default
106
- return int(value)
107
-
108
- return int(value)
109
- except (TypeError, ValueError):
110
- return default
111
-
112
-
113
- def to_float(value: Any, default: float = 0.0) -> float:
114
- """
115
- Converte um valor para float de forma segura.
116
-
117
- Regras:
118
- - None / "" -> default
119
- - aceita strings com vírgula decimal ("12,34")
120
- - NaN/inf -> default
121
-
122
- Args:
123
- value: valor a converter.
124
- default: fallback.
125
-
126
- Returns:
127
- float: convertido ou default.
128
- """
129
- try:
130
- if value is None:
131
- return default
132
-
133
- if isinstance(value, bool):
134
- return default
135
-
136
- if isinstance(value, str):
137
- s = value.strip()
138
- if s == "":
139
- return default
140
- s = s.replace(",", ".")
141
- v = float(s)
142
- else:
143
- v = float(value)
144
-
145
- if math.isnan(v) or math.isinf(v):
146
- return default
147
-
148
- return v
149
- except (TypeError, ValueError):
150
- return default
151
-
152
-
153
-
154
-
155
- # Classe fachada para coerção
156
- class BiaCoercion:
157
- """
158
- Fachada estática para funções de coerção do Bia Toolkit.
159
- Permite referenciar e utilizar as utilidades de coerção de forma padronizada.
160
- """
161
- @staticmethod
162
- def ensure_list(*args, **kwargs):
163
- return ensure_list(*args, **kwargs)
164
-
165
- @staticmethod
166
- def unwrap_dollar_value(*args, **kwargs):
167
- return unwrap_dollar_value(*args, **kwargs)
168
-
169
- @staticmethod
170
- def to_int(*args, **kwargs):
171
- return to_int(*args, **kwargs)
172
-
173
- @staticmethod
174
- def to_float(*args, **kwargs):
175
- return to_float(*args, **kwargs)
@@ -1,135 +0,0 @@
1
- # biatoolkit/validation.py
2
-
3
- from typing import Any, Iterable
4
- import re
5
-
6
-
7
- def parse_int_list(
8
- value: Any,
9
- *,
10
- dedupe: bool = True,
11
- keep_order: bool = True,
12
- ) -> list[int]:
13
- """
14
- Normaliza um valor arbitrário em uma lista de inteiros.
15
-
16
- Casos suportados:
17
- - None -> []
18
- - int -> [int]
19
- - str -> extrai números (ex: "100, 200" / "SKU=300231 x2")
20
- - list/tuple -> processa cada item recursivamente
21
-
22
- Comportamento:
23
- - Ignora valores inválidos
24
- - Deduplica por padrão
25
- - Mantém a ordem de aparição por padrão
26
-
27
- Args:
28
- value: Valor de entrada (None, int, str, list, etc.)
29
- dedupe: Remove valores duplicados.
30
- keep_order: Mantém a ordem original dos valores.
31
-
32
- Returns:
33
- list[int]: Lista normalizada de inteiros.
34
- """
35
- if value is None:
36
- return []
37
-
38
- # Normaliza para iterável
39
- if isinstance(value, (list, tuple, set)):
40
- raw: Iterable[Any] = value
41
- else:
42
- raw = [value]
43
-
44
- numbers: list[int] = []
45
-
46
- for item in raw:
47
- if item is None:
48
- continue
49
-
50
- # Inteiro direto
51
- if isinstance(item, int):
52
- numbers.append(item)
53
- continue
54
-
55
- # String ou outros tipos
56
- text = str(item)
57
- matches = re.findall(r"\d+", text)
58
- for m in matches:
59
- try:
60
- numbers.append(int(m))
61
- except ValueError:
62
- continue
63
-
64
- if not dedupe:
65
- return numbers
66
-
67
- if keep_order:
68
- seen = set()
69
- ordered: list[int] = []
70
- for n in numbers:
71
- if n not in seen:
72
- seen.add(n)
73
- ordered.append(n)
74
- return ordered
75
-
76
- return list(set(numbers))
77
-
78
- def sanitize_like(
79
- value: str,
80
- *,
81
- max_len: int = 80,
82
- upper: bool = True,
83
- ) -> str:
84
- """
85
- Sanitiza um texto para uso seguro em filtros do tipo LIKE/search.
86
-
87
- Regras aplicadas:
88
- - Remove caracteres fora de uma allowlist básica
89
- - Limita o tamanho do texto
90
- - Escapa aspas simples
91
- - Escapa curingas comuns (% e _)
92
- - Converte para UPPER por padrão
93
-
94
- Args:
95
- value: Texto de entrada.
96
- max_len: Tamanho máximo permitido.
97
- upper: Converte o texto final para maiúsculas.
98
-
99
- Returns:
100
- str: Texto sanitizado.
101
- """
102
- if not value:
103
- return ""
104
-
105
- # Normaliza e corta tamanho
106
- text = str(value).strip()[:max_len]
107
-
108
- # Allowlist simples (letras, números, acentos, espaço e alguns símbolos, incluindo ', %, _)
109
- # Mantém ', %, _ para escapá-los depois
110
- text = re.sub(r"[^0-9A-Za-zÀ-ÿ\s\-\(\)\./'_%]", " ", text)
111
-
112
- # Escapes básicos
113
- text = text.replace("'", "''")
114
- text = text.replace("%", r"\%" ).replace("_", r"\_")
115
-
116
- # Normaliza espaços
117
- text = re.sub(r"\s+", " ", text).strip()
118
-
119
-
120
- return text.upper() if upper else text
121
-
122
-
123
- # Classe fachada para validação
124
- class BiaValidation:
125
- """
126
- Fachada estática para funções de validação do Bia Toolkit.
127
- Permite referenciar e utilizar as utilidades de validação de forma padronizada.
128
- """
129
- @staticmethod
130
- def parse_int_list(*args, **kwargs):
131
- return parse_int_list(*args, **kwargs)
132
-
133
- @staticmethod
134
- def sanitize_like(*args, **kwargs):
135
- return sanitize_like(*args, **kwargs)
File without changes
File without changes