docs-cli 0.1.0__py3-none-any.whl
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.
- docs_cli-0.1.0.dist-info/METADATA +223 -0
- docs_cli-0.1.0.dist-info/RECORD +13 -0
- docs_cli-0.1.0.dist-info/WHEEL +5 -0
- docs_cli-0.1.0.dist-info/entry_points.txt +9 -0
- docs_cli-0.1.0.dist-info/top_level.txt +8 -0
- docs_tc.py +258 -0
- evaluate_coverage.py +362 -0
- extract_data_from_markdown.py +128 -0
- generate_embeddings.py +237 -0
- generate_report.py +118 -0
- generate_report_html.py +204 -0
- limpa_csv.py +170 -0
- merge_markdown.py +91 -0
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: docs-cli
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Um toolkit para processamento e avaliação de documentação.
|
|
5
|
+
Author-email: Paulo Guilherme Pilott <seuemail@example.com>
|
|
6
|
+
License: MIT License
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
9
|
+
Classifier: Operating System :: OS Independent
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Topic :: Documentation
|
|
13
|
+
Classifier: Topic :: Utilities
|
|
14
|
+
Classifier: Environment :: Console
|
|
15
|
+
Requires-Python: >=3.8
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
Requires-Dist: google-generativeai
|
|
18
|
+
Requires-Dist: python-dotenv
|
|
19
|
+
Requires-Dist: numpy
|
|
20
|
+
Requires-Dist: pandas
|
|
21
|
+
|
|
22
|
+
# Toolkit de Análise e Cobertura de Documentação Técnica (`docs-cli`)
|
|
23
|
+
|
|
24
|
+
Este toolkit fornece um conjunto de scripts Python para processar documentação técnica em formato Markdown, gerar embeddings semânticos, avaliar a cobertura da documentação em relação a um conjunto de perguntas e respostas, e gerar relatórios detalhados. O script principal `docs_tc.py` orquestra a execução dos scripts individuais.
|
|
25
|
+
|
|
26
|
+
## Pré-requisitos
|
|
27
|
+
|
|
28
|
+
1. **Python 3.7+**: certifique-se de que o Python está instalado e configurado no seu PATH.
|
|
29
|
+
2. **Dependências Python**: instale as bibliotecas necessárias. É recomendado criar um ambiente virtual:
|
|
30
|
+
```bash
|
|
31
|
+
python -m venv venv
|
|
32
|
+
source venv/bin/activate # Linux/macOS
|
|
33
|
+
# venv\Scripts\activate # Windows
|
|
34
|
+
pip install google-generativeai python-dotenv numpy pandas
|
|
35
|
+
```
|
|
36
|
+
Você também pode criar um arquivo `requirements.txt` com o conteúdo acima e rodar `pip install -r requirements.txt`.
|
|
37
|
+
3. **Chave da API Google Gemini**:
|
|
38
|
+
* Crie um arquivo chamado `.env` na raiz do projeto.
|
|
39
|
+
* Dentro do `.env`, adicione sua chave da API:
|
|
40
|
+
```
|
|
41
|
+
GOOGLE_API_KEY="SUA_CHAVE_API_AQUI"
|
|
42
|
+
```
|
|
43
|
+
* **IMPORTANTE**: o arquivo `.env` contém informações sensíveis e **não deve ser versionado** no Git. Adicione `.env` ao seu arquivo `.gitignore`.
|
|
44
|
+
|
|
45
|
+
## Estrutura de Arquivos Esperada (Antes da Execução)
|
|
46
|
+
|
|
47
|
+
```txt
|
|
48
|
+
/seu-projeto-raiz/
|
|
49
|
+
|-- docs_tc.py # Script orquestrador principal
|
|
50
|
+
|-- merge_markdown.py # Script para consolidar .md
|
|
51
|
+
|-- extract_data_from_markdown.py # Script para extrair dados do .md consolidado
|
|
52
|
+
|-- generate_embeddings.py # Script para gerar embeddings
|
|
53
|
+
|-- limpa_csv.py # Script para limpar o CSV de Q&A
|
|
54
|
+
|-- evaluate_coverage.py # Script para avaliar a cobertura
|
|
55
|
+
|-- generate_report.py # Script para gerar relatório .md
|
|
56
|
+
|-- generate_report_html.py # Script para gerar relatório .html
|
|
57
|
+
```
|
|
58
|
+
## Arquivos Gerados (e não versionados por padrão):
|
|
59
|
+
|
|
60
|
+
Os seguintes arquivos são gerados durante a execução dos scripts. É recomendado adicioná-los ao seu `.gitignore` se você não pretende versioná-los:
|
|
61
|
+
|
|
62
|
+
- `corpus_consolidated.md`
|
|
63
|
+
- `raw_docs.json`
|
|
64
|
+
- `embedings.json` (ou o nome que você usar para o arquivo de embeddings)
|
|
65
|
+
- `gartner_filtrado_processed.csv` (ou o nome do seu CSV de Q&A limpo)
|
|
66
|
+
- `evaluation_results.json`
|
|
67
|
+
- `coverage_report.md`
|
|
68
|
+
- `coverage_report.html`
|
|
69
|
+
|
|
70
|
+
### Configuração do `.gitignore`:
|
|
71
|
+
|
|
72
|
+
#### Arquivos de Ambiente
|
|
73
|
+
```gitignore
|
|
74
|
+
.env
|
|
75
|
+
chaves/.env
|
|
76
|
+
```
|
|
77
|
+
#### Arquivos de Dados Gerados
|
|
78
|
+
```gitignore
|
|
79
|
+
# Ignorar arquivos gerados automaticamente
|
|
80
|
+
*.json
|
|
81
|
+
*.csv
|
|
82
|
+
*.md
|
|
83
|
+
*.html
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
#### Exceto os arquivos que SÃO parte do toolkit/interface
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
# Mantenha estes arquivos versionados (exceções à regra global)
|
|
90
|
+
!docs_tc.py
|
|
91
|
+
!merge_markdown.py
|
|
92
|
+
!extract_data_from_markdown.py
|
|
93
|
+
!generate_embedings.py
|
|
94
|
+
!limpa_csv.py
|
|
95
|
+
!evaluate_coverage.py
|
|
96
|
+
!generate_report.py
|
|
97
|
+
!generate_report_html.py
|
|
98
|
+
!assistente/index.html
|
|
99
|
+
!assistente/about.html
|
|
100
|
+
!assistente/mudanca.html
|
|
101
|
+
!README.md
|
|
102
|
+
!requirements.txt
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
#### Arquivos de Cache Python
|
|
106
|
+
```gitignore
|
|
107
|
+
pycache/
|
|
108
|
+
*.py[cod]
|
|
109
|
+
*$py.class
|
|
110
|
+
```
|
|
111
|
+
#### Ambiente Virtual
|
|
112
|
+
```gitignore
|
|
113
|
+
venv/
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
- Ajuste o `.gitignore` acima para manter os arquivos `.md` e `.html` que são parte da sua documentação ou da ferramenta em si (como este `README.md` ou o `index.html` da interface).*
|
|
117
|
+
- No exemplo acima, `*.json`, `*.csv`, `*.md`, `*.html` são ignorados globalmente, e depois exceções são adicionadas. Seus arquivos de documentação originais em `DocumentosMD/` e o CSV bruto em `DadosQA/` **não serão ignorados** por esta configuração, o que é o desejado.*
|
|
118
|
+
|
|
119
|
+
## Utilização do `docs-cli`
|
|
120
|
+
|
|
121
|
+
O `docs_tc.py` é o ponto de entrada principal para utilizar o toolkit. Abra um terminal na raiz do projeto.
|
|
122
|
+
|
|
123
|
+
### 1. Ajuda Geral e de Comandos:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
docs-cli -h
|
|
127
|
+
docs-cli <comando> -h # Ex: docs-cli merge -h
|
|
128
|
+
```
|
|
129
|
+
### 2. Execução de Comandos Individuais:
|
|
130
|
+
|
|
131
|
+
Cada script pode ser chamado por um subcomando. Os nomes de arquivo padrão são usados se não especificados.
|
|
132
|
+
|
|
133
|
+
#### Consolidar Documentos (`merge`):
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
docs-cli merge ./docs/ --output_file corpus_consolidated.md
|
|
137
|
+
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
- `./docs/`: Diretório contendo seus arquivos .md originais.
|
|
141
|
+
- `-output_file`: (opcional) Nome do arquivo consolidado. Padrão: `corpus_consolidated.md`.
|
|
142
|
+
|
|
143
|
+
#### Extrair Dados do Markdown Consolidado (`extract`):
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
docs-cli extract --input_file corpus_consolidated.md --output_file raw_docs.json
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
- `-input_file`: (Opcional) Arquivo .md consolidado. Padrão: `corpus_consolidated.md`.
|
|
150
|
+
- `-output_file`: (Opcional) Arquivo JSON para os dados brutos. Padrão: `raw_docs.json`.
|
|
151
|
+
|
|
152
|
+
#### Gerar Embeddings (`generate_embeddings`):
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
docs-cli generate_embeddings --input_file raw_docs.json --output_file embeddings.json
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
- `-input_file`: (Opcional) Arquivo JSON com os dados brutos. Padrão: `raw_docs.json`.
|
|
159
|
+
- `-output_file`: (Opcional) Arquivo JSON para os embeddings. Padrão: `embeddings.json`.
|
|
160
|
+
|
|
161
|
+
#### Limpar CSV de Q&A (`clean_csv`):
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
docs-cli clean_csv ./csv/qa_bruto.csv --output_file qa_processado.csv
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
- `./csv/qa_bruto.csv`: Caminho para o arquivo CSV de perguntas e respostas bruto.
|
|
168
|
+
- `-output_file`: (Opcional) Nome do arquivo CSV processado. Padrão: `gartner_filtrado_processed.csv`.
|
|
169
|
+
|
|
170
|
+
#### Avaliar Cobertura (`evaluate_coverage`):
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
docs-cli evaluate qa_processado.csv embeddings.json -k 5 -o evaluation_results.json
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
- `qa_processado.csv`: Caminho para o arquivo CSV de perguntas e respostas processado.
|
|
177
|
+
- `embeddings.json`: Caminho para o arquivo JSON com os embeddings.
|
|
178
|
+
- `-k`: (Opcional) Número de resultados a retornar. Padrão: 5.
|
|
179
|
+
- `-o`: (Opcional) Nome do arquivo JSON para os resultados da avaliação. Padrão: `evaluation_results.json`.
|
|
180
|
+
De forma geral, os parâmetros são:
|
|
181
|
+
|
|
182
|
+
| Parâmetro | Tipo | Obrigatório | Descrição |
|
|
183
|
+
|--------------------------|---------|-------------|-------------------------------------------------------------------------------------------------|
|
|
184
|
+
| `qa_file` | string | Sim | Caminho para o arquivo CSV com perguntas e respostas |
|
|
185
|
+
| `embeddings_file` | string | Sim | Caminho para o arquivo JSON com os chunks processados e embeddings |
|
|
186
|
+
| `-k`, `--top-k` | inteiro | Não | Número de chunks mais relevantes a considerar (padrão: `5`) |
|
|
187
|
+
| `-o`, `--output` | string | Não | Caminho do arquivo de saída para os resultados (padrão: `evaluation_results.json`) |
|
|
188
|
+
|
|
189
|
+
#### Gerar Relatório Markdown (`generate_report`):
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
docs-cli generate_report evaluation_results.json --output_file coverage_report.md
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
- `evaluation_results.json`: Caminho para o arquivo JSON com os resultados da avaliação.
|
|
196
|
+
- `-output_file`: (Opcional) Nome do arquivo Markdown para o relatório. Padrão: `coverage_report.md`.
|
|
197
|
+
|
|
198
|
+
#### Gerar Relatório HTML (`generate_report_html`):
|
|
199
|
+
|
|
200
|
+
```bash
|
|
201
|
+
docs-cli generate_report_html evaluation_results.json --output_file coverage_report.html
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
- `evaluation_results.json`: Caminho para o arquivo JSON com os resultados da avaliação.
|
|
205
|
+
- `-output_file`: (Opcional) Nome do arquivo HTML para o relatório. Padrão: `coverage_report.html`.
|
|
206
|
+
|
|
207
|
+
## Executando o Toolkit Completo
|
|
208
|
+
Para executar todo o fluxo de trabalho do toolkit, você pode usar o comando principal `docs_tc.py` com o subcomando `full_flow`. Este comando executa todos os passos necessários, desde a consolidação dos documentos até a geração dos relatórios.
|
|
209
|
+
|
|
210
|
+
```bash
|
|
211
|
+
docs-cli full_flow ./docs/ ./csv/qa_bruto.csv --eval_top_k 5 --embeddings_file embedings.json
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
## Manutenção e Versionamento
|
|
215
|
+
|
|
216
|
+
- NÃO FAÇA COMMIT do seu arquivo `.env` contendo a `GOOGLE_API_KEY`.
|
|
217
|
+
- NÃO FAÇA COMMIT dos arquivos de dados gerados automaticamente (como `corpus_consolidated.md`, `raw_docs.json`, `embedings.json`, `evaluation_results.json`, etc.), a menos que tenha um motivo específico para versionar um estado particular desses dados. Adicione-os ao seu `.gitignore`.
|
|
218
|
+
- O arquivo CSV original com os dados de Q&A e os arquivos Markdown originais da sua documentação podem e devem ser versionados se fizerem parte da fonte do seu projeto.
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
Dê um alô :)
|
|
223
|
+
paulo[at]paulogpd.com.br
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
docs_tc.py,sha256=2SDRu3E4vuyHmtTT1KNVuvPSOLopRm6B4OahEDe9Zo8,15921
|
|
2
|
+
evaluate_coverage.py,sha256=4dvQZGKqVtC6UoEXyYDyfW53t-MSDvhgsg82xofUkow,17177
|
|
3
|
+
extract_data_from_markdown.py,sha256=kkGLlHrnEXFxuGDdpXKdQLu2gDqkX2e8TlOHQARwDiQ,5729
|
|
4
|
+
generate_embeddings.py,sha256=8wWoVZ_pdu-hQ6iYNi8kS4LE-ZyoQav5NtHkeTApFkY,10687
|
|
5
|
+
generate_report.py,sha256=twQICwbh_4G5BMIZw0sZLzU8RW67FMxgZuI23Xh7xao,4726
|
|
6
|
+
generate_report_html.py,sha256=0Zf3O1NMqsY7pGBwmwkD3KvDH8_yR2mGTPPZIzD8cV4,10232
|
|
7
|
+
limpa_csv.py,sha256=fOVv3ryh3LxQFF99WgrXuqocnExvHgzP46eVZT4zjWk,6096
|
|
8
|
+
merge_markdown.py,sha256=TlACWE73mhRYOImb-YVezEu0QUxqh2pa8_cz3-K94Ws,3458
|
|
9
|
+
docs_cli-0.1.0.dist-info/METADATA,sha256=DwLaaGh92xsFDJRc8MS33eq6BpafwbLjjEqbxlUOXIo,9366
|
|
10
|
+
docs_cli-0.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
11
|
+
docs_cli-0.1.0.dist-info/entry_points.txt,sha256=QujFzE6D1LdLGX79v7Lk3rNQpiGQE6czUUwWfdiWTMY,417
|
|
12
|
+
docs_cli-0.1.0.dist-info/top_level.txt,sha256=rYmdCpf_cAsmIgkzk_iA0SvgEQzGKPRE6UDwg6qO5ZQ,135
|
|
13
|
+
docs_cli-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
[console_scripts]
|
|
2
|
+
docs-cli = docs_tc:main
|
|
3
|
+
docs-tc-clean-csv = limpa_csv:cli_main
|
|
4
|
+
docs-tc-evaluate-coverage = evaluate_coverage:cli_main
|
|
5
|
+
docs-tc-extract-data = extract_data_from_markdown:cli_main
|
|
6
|
+
docs-tc-generate-embeddings = generate_embedings:cli_main
|
|
7
|
+
docs-tc-generate-report-html = generate_report_html:cli_main
|
|
8
|
+
docs-tc-generate-report-md = generate_report:cli_main
|
|
9
|
+
docs-tc-merge-markdown = merge_markdown:cli_main
|
docs_tc.py
ADDED
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
|
|
4
|
+
import argparse
|
|
5
|
+
import subprocess
|
|
6
|
+
import sys
|
|
7
|
+
import os
|
|
8
|
+
|
|
9
|
+
# Nomes de arquivo padrão intermediários e finais
|
|
10
|
+
DEFAULT_CORPUS_CONSOLIDATED = "corpus_consolidated.md"
|
|
11
|
+
DEFAULT_RAW_DOCS = "raw_docs.json"
|
|
12
|
+
DEFAULT_EMBEDDINGS = "embeddings.json" # Conforme sua solicitação
|
|
13
|
+
DEFAULT_EVAL_RESULTS = "evaluation_results.json"
|
|
14
|
+
DEFAULT_QA_PROCESSED = "gartner_filtrado_processed.csv" # Saída do limpa_csv e entrada do evaluate
|
|
15
|
+
DEFAULT_MD_REPORT = "coverage_report.md"
|
|
16
|
+
DEFAULT_HTML_REPORT = "coverage_report.html"
|
|
17
|
+
|
|
18
|
+
def run_script(command_args):
|
|
19
|
+
"""Executa um script (entry point) como um subprocesso."""
|
|
20
|
+
# Espera que command_args[0] seja um executável no PATH (ex: 'docs-tc-extract-data')
|
|
21
|
+
command = command_args
|
|
22
|
+
print(f"🚀 Executando: {' '.join(command)}")
|
|
23
|
+
try:
|
|
24
|
+
process = subprocess.run(command, capture_output=True, text=True, encoding=sys.stdout.encoding or 'latin-1', errors='replace')
|
|
25
|
+
|
|
26
|
+
if process.stdout:
|
|
27
|
+
print("Output:\n", process.stdout)
|
|
28
|
+
if process.stderr:
|
|
29
|
+
print("Errors:\n", process.stderr, file=sys.stderr)
|
|
30
|
+
|
|
31
|
+
if process.returncode != 0:
|
|
32
|
+
print(f"❌ Erro ao executar {' '.join(command)}. Código de saída: {process.returncode}", file=sys.stderr)
|
|
33
|
+
return None # Indica falha para as funções run_step_or_exit
|
|
34
|
+
|
|
35
|
+
print(f"✅ Script {' '.join(command_args)} concluído com sucesso.")
|
|
36
|
+
return process
|
|
37
|
+
|
|
38
|
+
except FileNotFoundError:
|
|
39
|
+
print(f"🚨 Erro: Comando '{command[0]}' não encontrado. Verifique se o docs-cli está instalado corretamente e se os scripts dos subcomandos (ex: {command[0]}.exe) foram criados na pasta Scripts do seu ambiente virtual e se o ambiente virtual está ativo.", file=sys.stderr)
|
|
40
|
+
sys.exit(1) # Falha crítica se o comando do script não for encontrado
|
|
41
|
+
except Exception as e:
|
|
42
|
+
print(f"🚨 Exceção ao executar o subprocesso {' '.join(command)}: {e}", file=sys.stderr)
|
|
43
|
+
sys.exit(1)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def main():
|
|
47
|
+
parser = argparse.ArgumentParser(description="Docs Toolkit CLI - Orquestrador de scripts de processamento de documentação.")
|
|
48
|
+
subparsers = parser.add_subparsers(dest="command", help="Comandos disponíveis", required=True)
|
|
49
|
+
|
|
50
|
+
# --- Subparser para merge_markdown.py ---
|
|
51
|
+
parser_merge = subparsers.add_parser("merge", help="Consolida arquivos Markdown de um diretório.")
|
|
52
|
+
parser_merge.add_argument("input_dir", help="Diretório de entrada contendo os arquivos .md.")
|
|
53
|
+
parser_merge.add_argument("--output_file", default=DEFAULT_CORPUS_CONSOLIDATED,
|
|
54
|
+
help=f"Arquivo de saída para o Markdown consolidado (padrão: {DEFAULT_CORPUS_CONSOLIDATED}).")
|
|
55
|
+
|
|
56
|
+
# --- Subparser para extract_data_from_markdown.py ---
|
|
57
|
+
parser_extract = subparsers.add_parser("extract", help="Extrai dados estruturados do Markdown consolidado.")
|
|
58
|
+
parser_extract.add_argument("--input_file", default=DEFAULT_CORPUS_CONSOLIDATED,
|
|
59
|
+
help=f"Arquivo Markdown consolidado de entrada (padrão: {DEFAULT_CORPUS_CONSOLIDATED}).")
|
|
60
|
+
parser_extract.add_argument("--output_file", default=DEFAULT_RAW_DOCS,
|
|
61
|
+
help=f"Arquivo JSON de saída para os documentos brutos (padrão: {DEFAULT_RAW_DOCS}).")
|
|
62
|
+
|
|
63
|
+
# --- Subparser para generate_embedings.py ---
|
|
64
|
+
parser_generate = subparsers.add_parser("generate_embeddings", help="Gera embeddings para os documentos processados.")
|
|
65
|
+
parser_generate.add_argument("--input_file", default=DEFAULT_RAW_DOCS,
|
|
66
|
+
help=f"Arquivo JSON de entrada com os documentos brutos (padrão: {DEFAULT_RAW_DOCS}).")
|
|
67
|
+
parser_generate.add_argument("--output_file", default=DEFAULT_EMBEDDINGS,
|
|
68
|
+
help=f"Arquivo JSON de saída para os embeddings (padrão: {DEFAULT_EMBEDDINGS}).")
|
|
69
|
+
|
|
70
|
+
# --- Subparser para limpa_csv.py ---
|
|
71
|
+
parser_clean_csv = subparsers.add_parser("clean_csv", help="Limpa o arquivo CSV de Perguntas e Respostas.")
|
|
72
|
+
parser_clean_csv.add_argument("input_file", help="Arquivo CSV de entrada a ser limpo (ex: qa-data.csv).")
|
|
73
|
+
parser_clean_csv.add_argument("--output_file", default=DEFAULT_QA_PROCESSED,
|
|
74
|
+
help=f"Arquivo CSV de saída limpo (padrão: {DEFAULT_QA_PROCESSED}).")
|
|
75
|
+
|
|
76
|
+
# --- Subparser para evaluate_coverage.py ---
|
|
77
|
+
parser_evaluate = subparsers.add_parser("evaluate", help="Avalia a cobertura da documentação.")
|
|
78
|
+
parser_evaluate.add_argument("qa_file",
|
|
79
|
+
help="Caminho para o arquivo CSV limpo com perguntas e respostas.")
|
|
80
|
+
parser_evaluate.add_argument("embeddings_file",
|
|
81
|
+
help="Caminho para o arquivo JSON com chunks processados e embeddings.")
|
|
82
|
+
parser_evaluate.add_argument("-k", "--top_k", type=int, default=5,
|
|
83
|
+
help="Número de chunks mais relevantes a considerar (padrão: 5).")
|
|
84
|
+
parser_evaluate.add_argument("-o", "--output", default=DEFAULT_EVAL_RESULTS,
|
|
85
|
+
help=f"Arquivo de saída para os resultados da avaliação (padrão: {DEFAULT_EVAL_RESULTS}).")
|
|
86
|
+
|
|
87
|
+
# --- Subparser para generate_report.py (Markdown) ---
|
|
88
|
+
parser_report_md = subparsers.add_parser("report_md", help="Gera o relatório de cobertura em Markdown.")
|
|
89
|
+
parser_report_md.add_argument("--input_file", default=DEFAULT_EVAL_RESULTS,
|
|
90
|
+
help=f"Arquivo JSON de entrada com os resultados da avaliação (padrão: {DEFAULT_EVAL_RESULTS}).")
|
|
91
|
+
parser_report_md.add_argument("--output_file", default=DEFAULT_MD_REPORT,
|
|
92
|
+
help=f"Arquivo Markdown de saída para o relatório (padrão: {DEFAULT_MD_REPORT}).")
|
|
93
|
+
parser_report_md.add_argument("--top_k_chunks", type=int, default=5,
|
|
94
|
+
help="Valor de top_k_chunks usado na avaliação (para consistência do relatório, padrão: 5).")
|
|
95
|
+
|
|
96
|
+
# --- Subparser para generate_report_html.py (HTML) ---
|
|
97
|
+
parser_report_html = subparsers.add_parser("report_html", help="Gera o relatório de cobertura em HTML.")
|
|
98
|
+
parser_report_html.add_argument("--input_file", default=DEFAULT_EVAL_RESULTS,
|
|
99
|
+
help=f"Arquivo JSON de entrada com os resultados da avaliação (padrão: {DEFAULT_EVAL_RESULTS}).")
|
|
100
|
+
parser_report_html.add_argument("--output_file", default=DEFAULT_HTML_REPORT,
|
|
101
|
+
help=f"Arquivo HTML de saída para o relatório (padrão: {DEFAULT_HTML_REPORT}).")
|
|
102
|
+
parser_report_html.add_argument("--top_k_chunks", type=int, default=5,
|
|
103
|
+
help="Valor de top_k_chunks usado na avaliação (para consistência do relatório, padrão: 5).")
|
|
104
|
+
|
|
105
|
+
# --- Subparser para o fluxo completo ---
|
|
106
|
+
parser_full_flow = subparsers.add_parser("full_flow", help="Executa o fluxo completo de processamento e avaliação.")
|
|
107
|
+
parser_full_flow.add_argument("doc_input_dir", help="Diretório de entrada dos arquivos .md originais.")
|
|
108
|
+
parser_full_flow.add_argument("qa_input_file", help="Arquivo CSV de entrada original com Perguntas e Respostas (ex: qa-data.csv).")
|
|
109
|
+
parser_full_flow.add_argument("--eval_top_k", type=int, default=5, help="Top K para a etapa de avaliação (padrão: 5).")
|
|
110
|
+
parser_full_flow.add_argument("--corpus_file", default=DEFAULT_CORPUS_CONSOLIDATED)
|
|
111
|
+
parser_full_flow.add_argument("--raw_docs_file", default=DEFAULT_RAW_DOCS)
|
|
112
|
+
parser_full_flow.add_argument("--embeddings_file", default=DEFAULT_EMBEDDINGS)
|
|
113
|
+
parser_full_flow.add_argument("--cleaned_qa_file", default=DEFAULT_QA_PROCESSED)
|
|
114
|
+
parser_full_flow.add_argument("--eval_results_file", default=DEFAULT_EVAL_RESULTS)
|
|
115
|
+
parser_full_flow.add_argument("--md_report_file", default=DEFAULT_MD_REPORT)
|
|
116
|
+
parser_full_flow.add_argument("--html_report_file", default=DEFAULT_HTML_REPORT)
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
# --- Subparser para fluxo customizado ---
|
|
120
|
+
parser_custom_flow = subparsers.add_parser("custom_flow", help="Executa uma sequência customizada de scripts.")
|
|
121
|
+
parser_custom_flow.add_argument("steps", nargs='+', choices=['merge', 'extract', 'generate_embeddings', 'clean_csv', 'evaluate', 'report_md', 'report_html'],
|
|
122
|
+
help="Sequência de etapas a serem executadas (ex: merge extract generate_embeddings).")
|
|
123
|
+
|
|
124
|
+
args = parser.parse_args()
|
|
125
|
+
|
|
126
|
+
# Nomes dos entry points (conforme definido em setup.py)
|
|
127
|
+
SCRIPT_MAP = {
|
|
128
|
+
"merge": "docs-tc-merge-markdown",
|
|
129
|
+
"extract": "docs-tc-extract-data",
|
|
130
|
+
"generate_embeddings": "docs-tc-generate-embeddings", # Certifique-se que 'generate_embedings.py' (com typo) tem cli_main e o entry point no setup.py usa esse nome de módulo
|
|
131
|
+
"clean_csv": "docs-tc-clean-csv",
|
|
132
|
+
"evaluate": "docs-tc-evaluate-coverage",
|
|
133
|
+
"report_md": "docs-tc-generate-report-md",
|
|
134
|
+
"report_html": "docs-tc-generate-report-html"
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if args.command == "merge":
|
|
138
|
+
run_script([SCRIPT_MAP["merge"], args.input_dir, args.output_file])
|
|
139
|
+
elif args.command == "extract":
|
|
140
|
+
run_script([SCRIPT_MAP["extract"], args.input_file, args.output_file])
|
|
141
|
+
elif args.command == "generate_embeddings":
|
|
142
|
+
run_script([SCRIPT_MAP["generate_embeddings"], args.input_file, args.output_file])
|
|
143
|
+
elif args.command == "clean_csv":
|
|
144
|
+
run_script([SCRIPT_MAP["clean_csv"], args.input_file, args.output_file])
|
|
145
|
+
elif args.command == "evaluate":
|
|
146
|
+
run_script([
|
|
147
|
+
SCRIPT_MAP["evaluate"],
|
|
148
|
+
args.qa_file,
|
|
149
|
+
args.embeddings_file,
|
|
150
|
+
"-k", str(args.top_k),
|
|
151
|
+
"-o", args.output
|
|
152
|
+
])
|
|
153
|
+
elif args.command == "report_md":
|
|
154
|
+
run_script([
|
|
155
|
+
SCRIPT_MAP["report_md"],
|
|
156
|
+
args.input_file,
|
|
157
|
+
args.output_file,
|
|
158
|
+
str(args.top_k_chunks)
|
|
159
|
+
])
|
|
160
|
+
elif args.command == "report_html":
|
|
161
|
+
run_script([
|
|
162
|
+
SCRIPT_MAP["report_html"],
|
|
163
|
+
args.input_file,
|
|
164
|
+
args.output_file,
|
|
165
|
+
str(args.top_k_chunks)
|
|
166
|
+
])
|
|
167
|
+
elif args.command == "full_flow":
|
|
168
|
+
print("🚀 Iniciando fluxo completo...")
|
|
169
|
+
def run_step_or_exit(step_command_args):
|
|
170
|
+
if run_script(step_command_args) is None:
|
|
171
|
+
print(f"❌ Etapa {step_command_args[0]} falhou. Abortando fluxo completo.")
|
|
172
|
+
sys.exit(1)
|
|
173
|
+
|
|
174
|
+
run_step_or_exit([SCRIPT_MAP["merge"], args.doc_input_dir, args.corpus_file])
|
|
175
|
+
run_step_or_exit([SCRIPT_MAP["clean_csv"], args.qa_input_file, args.cleaned_qa_file])
|
|
176
|
+
run_step_or_exit([SCRIPT_MAP["extract"], args.corpus_file, args.raw_docs_file])
|
|
177
|
+
run_step_or_exit([SCRIPT_MAP["generate_embeddings"], args.raw_docs_file, args.embeddings_file])
|
|
178
|
+
run_step_or_exit([
|
|
179
|
+
SCRIPT_MAP["evaluate"],
|
|
180
|
+
args.cleaned_qa_file,
|
|
181
|
+
args.embeddings_file,
|
|
182
|
+
"-k", str(args.eval_top_k),
|
|
183
|
+
"-o", args.eval_results_file
|
|
184
|
+
])
|
|
185
|
+
run_step_or_exit([
|
|
186
|
+
SCRIPT_MAP["report_md"],
|
|
187
|
+
args.eval_results_file,
|
|
188
|
+
args.md_report_file,
|
|
189
|
+
str(args.eval_top_k)
|
|
190
|
+
])
|
|
191
|
+
run_step_or_exit([
|
|
192
|
+
SCRIPT_MAP["report_html"],
|
|
193
|
+
args.eval_results_file,
|
|
194
|
+
args.html_report_file,
|
|
195
|
+
str(args.eval_top_k)
|
|
196
|
+
])
|
|
197
|
+
print("🎉 Fluxo completo concluído!")
|
|
198
|
+
|
|
199
|
+
elif args.command == "custom_flow":
|
|
200
|
+
print(f"▶️ Iniciando fluxo customizado: {' -> '.join(args.steps)}")
|
|
201
|
+
current_corpus_file = DEFAULT_CORPUS_CONSOLIDATED
|
|
202
|
+
current_raw_docs_file = DEFAULT_RAW_DOCS
|
|
203
|
+
current_embeddings_file = DEFAULT_EMBEDDINGS
|
|
204
|
+
current_cleaned_qa_file = DEFAULT_QA_PROCESSED
|
|
205
|
+
current_eval_results_file = DEFAULT_EVAL_RESULTS
|
|
206
|
+
default_eval_top_k = 5
|
|
207
|
+
|
|
208
|
+
def run_custom_step_or_exit(step_command_args):
|
|
209
|
+
if run_script(step_command_args) is None:
|
|
210
|
+
print(f"❌ Etapa {step_command_args[0]} falhou. Abortando fluxo customizado.")
|
|
211
|
+
sys.exit(1)
|
|
212
|
+
|
|
213
|
+
for step in args.steps:
|
|
214
|
+
print(f"\n--- Executando etapa: {step} ---")
|
|
215
|
+
if step == "merge":
|
|
216
|
+
doc_input_dir = input("Por favor, informe o diretório de entrada para 'merge' (pressione Enter para usar 'docs' como padrão): ") or "docs"
|
|
217
|
+
run_custom_step_or_exit([SCRIPT_MAP["merge"], doc_input_dir, current_corpus_file])
|
|
218
|
+
elif step == "extract":
|
|
219
|
+
if not os.path.exists(current_corpus_file):
|
|
220
|
+
current_corpus_file = input(f"Arquivo Corpus ({current_corpus_file}) não encontrado. Informe o caminho correto: ")
|
|
221
|
+
run_custom_step_or_exit([SCRIPT_MAP["extract"], current_corpus_file, current_raw_docs_file])
|
|
222
|
+
elif step == "generate_embeddings":
|
|
223
|
+
if not os.path.exists(current_raw_docs_file):
|
|
224
|
+
current_raw_docs_file = input(f"Arquivo Raw Docs ({current_raw_docs_file}) não encontrado. Informe o caminho correto: ")
|
|
225
|
+
run_custom_step_or_exit([SCRIPT_MAP["generate_embeddings"], current_raw_docs_file, current_embeddings_file])
|
|
226
|
+
elif step == "clean_csv":
|
|
227
|
+
qa_input_file = input("Por favor, informe o arquivo CSV de Q&A original para 'clean_csv' (pressione Enter para usar 'qa-data.csv'): ") or "qa-data.csv"
|
|
228
|
+
run_custom_step_or_exit([SCRIPT_MAP["clean_csv"], qa_input_file, current_cleaned_qa_file])
|
|
229
|
+
elif step == "evaluate":
|
|
230
|
+
if not os.path.exists(current_cleaned_qa_file):
|
|
231
|
+
current_cleaned_qa_file = input(f"Arquivo QA limpo ({current_cleaned_qa_file}) não encontrado. Informe o caminho correto: ")
|
|
232
|
+
if not os.path.exists(current_embeddings_file):
|
|
233
|
+
current_embeddings_file = input(f"Arquivo de Embeddings ({current_embeddings_file}) não encontrado. Informe o caminho correto: ")
|
|
234
|
+
eval_k_str = input(f"Informe o top_k para evaluate (pressione Enter para usar {default_eval_top_k}): ") or str(default_eval_top_k)
|
|
235
|
+
run_custom_step_or_exit([
|
|
236
|
+
SCRIPT_MAP["evaluate"],
|
|
237
|
+
current_cleaned_qa_file, current_embeddings_file,
|
|
238
|
+
"-k", eval_k_str,
|
|
239
|
+
"-o", current_eval_results_file
|
|
240
|
+
])
|
|
241
|
+
elif step == "report_md":
|
|
242
|
+
if not os.path.exists(current_eval_results_file):
|
|
243
|
+
current_eval_results_file = input(f"Arquivo de Resultados da Avaliação ({current_eval_results_file}) não encontrado. Informe o caminho correto: ")
|
|
244
|
+
report_k_str = input(f"Informe o top_k_chunks para report_md (pressione Enter para usar {default_eval_top_k}, deve coincidir com o usado na avaliação): ") or str(default_eval_top_k)
|
|
245
|
+
run_custom_step_or_exit([
|
|
246
|
+
SCRIPT_MAP["report_md"], current_eval_results_file, DEFAULT_MD_REPORT, report_k_str
|
|
247
|
+
])
|
|
248
|
+
elif step == "report_html":
|
|
249
|
+
if not os.path.exists(current_eval_results_file):
|
|
250
|
+
current_eval_results_file = input(f"Arquivo de Resultados da Avaliação ({current_eval_results_file}) não encontrado. Informe o caminho correto: ")
|
|
251
|
+
report_k_str = input(f"Informe o top_k_chunks para report_html (pressione Enter para usar {default_eval_top_k}, deve coincidir com o usado na avaliação): ") or str(default_eval_top_k)
|
|
252
|
+
run_custom_step_or_exit([
|
|
253
|
+
SCRIPT_MAP["report_html"], current_eval_results_file, DEFAULT_HTML_REPORT, report_k_str
|
|
254
|
+
])
|
|
255
|
+
print("⏹️ Fluxo customizado concluído.")
|
|
256
|
+
|
|
257
|
+
if __name__ == "__main__":
|
|
258
|
+
main()
|