Esta documentação descreve a API interna do MinerU Desktop Client, incluindo todas as classes públicas, métodos e suas interfaces.
Cliente para interação com a API REST do MinerU.
Localização: mineru_client.py
CONFIG_FILE = "config.ini"
KEYRING_SERVICE = "MinerU"
KEYRING_USERNAME = "api_token"
API_BASE_URL = "https://mineru.net/api/v4"def __init__(self) -> NoneInicializa o cliente com configuração padrão e carrega configurações do keyring e arquivo.
Efeitos Colaterais:
- Carrega token do keyring
- Lê config.ini se existir
- Define valores padrão se não houver configuração
def load_config(self) -> NoneCarrega configuração do keyring e arquivo config.ini.
Configurações Carregadas:
api_token: Do keyring (seguro)is_ocr: bool - Forçar OCRenable_formula: bool - Reconhecimento de fórmulasenable_table: bool - Reconhecimento de tabelaslanguage: str - Idioma OCR (pt, en, ch)model_version: str - Modelo (pipeline, vlm)output_directory: str - Diretório de saída
Exemplo:
client = MineruClient()
client.load_config() # Recarrega após mudança de configuraçãodef get_headers(self) -> Dict[str, str]Retorna headers HTTP com token de autorização.
Retorna:
dict: Headers incluindoAuthorization: Bearer <token>
Exceções:
ValueError: Se token não estiver configurado
Exemplo:
headers = client.get_headers()
# {'Authorization': 'Bearer abc123...'}def get_processing_options(self) -> Dict[str, any]Retorna opções de processamento atuais para parâmetros em nível de lote.
Retorna:
dict: Opções de configuraçãoenable_formula: boolenable_table: boolmodel_version: strlanguage: str (apenas para modelo pipeline)
Nota: is_ocr não é incluído pois deve ser definido por arquivo.
Exemplo:
options = client.get_processing_options()
# {
# 'enable_formula': False,
# 'enable_table': True,
# 'model_version': 'pipeline',
# 'language': 'pt'
# }def upload_batch(
self,
file_paths: List[str],
progress_callback: Optional[Callable[[int], None]] = None
) -> DictFaz upload de lote de arquivos para API MinerU com uploads paralelos.
Processo em Duas Etapas:
- POST request para obter batch_id e presigned URLs
- PUT requests paralelos para upload dos arquivos
Parâmetros:
file_paths: Lista de caminhos de arquivos locaisprogress_callback: Função callback opcional para atualizações de progresso (0-100)
Retorna:
dict: Resposta contendo:batch_id: str - ID do loteuploads: List[dict] - Status de cada uploadfile: str - Nome do arquivostatus: str - "success" ou "failed"error: str - Mensagem de erro (se failed)
Exceções:
ValueError: Se token não configurado ou nenhum arquivo fornecidoConnectionError: Falha de conexão com APITimeoutError: Request timeoutrequests.HTTPError: Erros HTTP específicos (401, 403, etc.)
Exemplo:
def update_progress(percent):
print(f"Progress: {percent}%")
result = client.upload_batch(
['doc1.pdf', 'doc2.pdf'],
progress_callback=update_progress
)
print(f"Batch ID: {result['batch_id']}")
for upload in result['uploads']:
print(f"{upload['file']}: {upload['status']}")Comportamento de Upload Paralelo:
- Máximo de 5 uploads simultâneos
- ThreadPoolExecutor gerencia paralelismo
- Callback de progresso chamado após cada arquivo completar
def get_batch_status(self, batch_id: str) -> DictObtém status de processamento de um lote.
Parâmetros:
batch_id: ID do lote a verificar
Retorna:
dict: Informação de status para todos os arquivos do lote{ 'data': { 'batch_id': str, 'extract_result': [ { 'file_name': str, 'state': str, # 'pending', 'processing', 'done', 'failed' 'err_msg': str, # Se failed 'full_zip_url': str # Se done }, ... ] } }
Exceções:
ValueError: Token inválido ou batch_id não encontradoConnectionError: Falha de conexãoTimeoutError: Request timeout
Exemplo:
status = client.get_batch_status('batch_abc123')
for file_info in status['data']['extract_result']:
print(f"{file_info['file_name']}: {file_info['state']}")def download_result(self, zip_url: str, filename: str) -> strFaz download de arquivo de resultado da URL fornecida.
Parâmetros:
zip_url: URL para download do arquivo ZIPfilename: Nome para o arquivo baixado
Retorna:
str: Caminho completo do arquivo baixado
Efeitos Colaterais:
- Cria
output_directoryse não existir - Salva arquivo no diretório de saída
Exceções:
ConnectionError: Falha no downloadTimeoutError: Download timeout
Exemplo:
zip_path = client.download_result(
'https://s3.../result.zip',
'doc1_result.zip'
)
print(f"Downloaded to: {zip_path}")
# /home/user/Documents/MinerU_Output/doc1_result.zipJanela principal da aplicação.
Localização: main.py
def __init__(self) -> NoneInicializa a janela principal e componentes.
Atributos Inicializados:
selected_files: List[str] - Arquivos selecionadoscurrent_batch_id: Optional[str] - ID do lote atualmineru_client: MineruClient - Cliente APIupload_worker: Optional[UploadWorker] - Worker de uploadpolling_timer: Optional[QTimer] - Timer de pollingfile_status_map: Dict[str, str] - Map de status de arquivos
def setup_ui(self) -> NoneConfigura componentes da interface do usuário.
Cria e organiza todos os elementos da UI incluindo menu bar, controles de seleção de arquivos, indicadores de progresso e botões.
def create_menu_bar(self) -> NoneCria menu bar com menus File e Help.
Menus:
- File:
- Settings (Ctrl+,)
- Exit (Ctrl+Q)
- Help:
- About
def open_settings(self) -> NoneAbre diálogo de configurações.
Recarrega configuração do cliente se settings forem salvos com sucesso.
def show_about(self) -> NoneMostra diálogo About com informações de versão e features.
def add_files(self) -> NoneAbre diálogo de seleção de arquivos.
Comportamento:
- Permite seleção múltipla
- Filtra por tipos suportados (PDF, DOCX, PPTX, JPG, PNG)
- Previne duplicatas
- Atualiza lista de arquivos e status map
- Habilita botão de processar se houver arquivos
def remove_selected_files(self) -> NoneRemove arquivos selecionados da lista de processamento.
Comportamento:
- Remove de
selected_files - Remove de
file_status_map - Atualiza widget de lista
- Desabilita botão processar se lista ficar vazia
def start_processing(self) -> NoneInicia processamento de arquivos selecionados via upload em background.
Comportamento:
- Valida que há arquivos selecionados
- Desabilita controles durante upload
- Cria e inicia UploadWorker
- Mostra progress bar
- Conecta signals do worker
Mostra Warning Se: Nenhum arquivo selecionado
def on_upload_progress(self, progress: int) -> NoneAtualiza progress bar durante upload.
Parâmetros:
progress: Porcentagem de progresso (0-100)
def on_upload_completed(self, result: dict) -> NoneTrata conclusão de upload bem-sucedido.
Parâmetros:
result: Resultado do uploadbatch_id: struploads: List[dict]
Comportamento:
- Armazena batch_id
- Atualiza status dos arquivos na UI
- Mostra mensagem de sucesso/falha
- Inicia polling automático se algum upload teve sucesso
def on_upload_failed(self, error_message: str) -> NoneTrata falha de upload com notificação ao usuário.
Parâmetros:
error_message: Descrição do erro
Comportamento:
- Mostra diálogo de erro
- Re-habilita controles UI
def start_polling(self) -> NoneInicia polling automático de status.
Comportamento:
- Cria QTimer que verifica status a cada 10 segundos
- Faz verificação imediata ao iniciar
- Limpa timer existente antes de criar novo
def check_batch_status(self) -> NoneVerifica status do lote atual e baixa arquivos completos.
Comportamento:
- Consulta API para status atual
- Atualiza status dos arquivos na UI
- Baixa e extrai resultados completos automaticamente
- Continua polling até todos os arquivos atingirem estado final
- Habilita botão "Abrir Pasta" quando pelo menos um arquivo completa
- Para polling quando todos os arquivos estiverem finalizados
Estados de Arquivo:
pending: Na filaprocessing: Em processamentodone: Completo (trigger download)failed: Falhou
def update_file_status(self, filename: str, status: str) -> NoneAtualiza status de arquivo no widget de lista.
Parâmetros:
filename: Nome do arquivostatus: Novo texto de status
def open_output_folder(self) -> NoneAbre diretório de saída no gerenciador de arquivos do sistema.
Comportamento:
- Usa QDesktopServices para abrir pasta
- Mostra warning se diretório não existe
def closeEvent(self, event: QCloseEvent) -> NoneTrata evento de fechamento da aplicação com cleanup adequado.
Parâmetros:
event: Evento de fechamento
Comportamento:
- Para timer de polling ativo
- Aguarda thread de upload worker completar
- Aceita evento de fechamento
Worker thread para uploads de arquivos.
Localização: main.py
progress_updated = Signal(int) # Progresso 0-100
upload_completed = Signal(dict) # Resultado completo
upload_failed = Signal(str) # Mensagem de errodef __init__(self, mineru_client: MineruClient, file_paths: List[str]) -> NoneParâmetros:
mineru_client: Instância do cliente APIfile_paths: Lista de caminhos de arquivos para upload
def run(self) -> NoneExecuta operação de upload em thread separada.
Comportamento:
- Roda em background
- Comunica via signals
- Trata exceções
- Emite signals apropriados baseado no resultado
Emits:
progress_updated: Durante upload com porcentagemupload_completed: Em sucesso com dict de resultadoupload_failed: Em erro com string de mensagem
Exemplo de Uso:
worker = UploadWorker(client, ['file1.pdf', 'file2.pdf'])
worker.progress_updated.connect(on_progress)
worker.upload_completed.connect(on_complete)
worker.upload_failed.connect(on_error)
worker.start()Diálogo para configuração de settings API e opções de processamento.
Localização: settings_dialog.py
CONFIG_FILE = "config.ini"
KEYRING_SERVICE = "MinerU"
KEYRING_USERNAME = "api_token"def __init__(self, parent: Optional[QWidget] = None) -> NoneParâmetros:
parent: Widget pai (opcional)
Comportamento:
- Configura UI
- Carrega settings existentes
def setup_ui(self) -> NoneConfigura componentes da interface do usuário.
Cria e organiza todos os elementos incluindo input de token API, seletor de diretório de saída, checkboxes de opções de processamento e dropdowns de seleção de modelo/idioma.
def select_output_folder(self) -> NoneAbre diálogo de seleção de diretório.
Atualiza campo de input com diretório selecionado.
def on_model_changed(self) -> NoneTrata mudança de seleção de modelo.
Comportamento:
- Habilita/desabilita seletor de idioma baseado no modelo
- Modelo Pipeline: Suporta configuração de idioma
- Modelo VLM: Não suporta idioma
- Ajusta estilo de mensagem de warning
def load_settings(self) -> NoneCarrega settings do keyring e arquivo config.
Fontes:
- Keyring: API token
- config.ini: Outras configurações
Defaults (se não houver config):
- Output directory:
~/Documents/MinerU_Output - Force OCR: True
- Enable formula: False
- Enable table: True
- Language: Portuguese (pt)
- Model: Pipeline
def save_settings(self) -> NoneSalva settings para keyring e arquivo config.
Validações:
- Token não pode ser vazio
- Diretório de saída deve ser especificado
Comportamento:
- Salva token para keyring
- Cria diretório de saída se não existir
- Escreve settings não-sensíveis para config.ini
- Mostra diálogo de sucesso/erro
Settings Salvos em config.ini:
[Settings]
is_ocr = True
enable_formula = False
enable_table = True
language = pt
model_version = pipeline
[Paths]
output_directory = ~/Documents/MinerU_OutputInformações de versão da aplicação.
Localização: version.py
VERSION = "1.0.1"
VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH = VERSION.split(".")
VERSION_STRING = f"MinerU Desktop Client v{VERSION}"
VERSION_SHORT = VERSIONdef get_version() -> strRetorna string de versão atual.
Retorna: "1.0.1"
def get_version_string() -> strRetorna string de versão completa para display.
Retorna: "MinerU Desktop Client v1.0.1"
def get_version_info() -> dictRetorna informações de versão como dicionário.
Retorna:
{
"version": "1.0.1",
"major": "1",
"minor": "0",
"patch": "1",
"string": "MinerU Desktop Client v1.0.1"
}{
"batch_id": str,
"uploads": [
{
"file": str,
"status": "success" | "failed",
"error": str # Opcional, presente se status == "failed"
}
]
}{
"data": {
"batch_id": str,
"extract_result": [
{
"file_name": str,
"state": "pending" | "processing" | "done" | "failed",
"err_msg": str, # Se state == "failed"
"full_zip_url": str # Se state == "done"
}
]
}
}[Settings]
is_ocr = True
enable_formula = False
enable_table = True
language = pt
model_version = pipeline
[Paths]
output_directory = ~/Documents/MinerU_OutputLançado quando:
- Token API não está configurado
- Token API é inválido (HTTP 401)
- Acesso proibido (HTTP 403)
- Nenhum arquivo fornecido para upload
- Resposta API inválida (faltando batch_id ou file_urls)
- Contagem de URL não corresponde à contagem de arquivos
- Batch ID não encontrado (HTTP 404)
Lançado quando:
- Falha na conexão com API MinerU
- Falha no download de arquivo
Lançado quando:
- Request para API MinerU timeout
- Download timeout
Lançado quando:
- Falha em request API com código de status inesperado
- Falha no download com erro inesperado
from mineru_client import MineruClient
# Inicializar cliente
client = MineruClient()
# Upload de arquivos
result = client.upload_batch(['doc1.pdf', 'doc2.pdf'])
batch_id = result['batch_id']
print(f"Batch ID: {batch_id}")
for upload in result['uploads']:
print(f"{upload['file']}: {upload['status']}")
# Verificar status
status = client.get_batch_status(batch_id)
for file_info in status['data']['extract_result']:
state = file_info['state']
filename = file_info['file_name']
print(f"{filename}: {state}")
# Download se pronto
if state == 'done':
zip_url = file_info['full_zip_url']
output_name = f"{filename}_result.zip"
zip_path = client.download_result(zip_url, output_name)
print(f"Downloaded: {zip_path}")from mineru_client import MineruClient
def show_progress(percent):
print(f"Upload Progress: {percent}%")
client = MineruClient()
result = client.upload_batch(
['large1.pdf', 'large2.pdf', 'large3.pdf'],
progress_callback=show_progress
)
print(f"Upload complete! Batch ID: {result['batch_id']}")import configparser
import keyring
# Salvar token no keyring
keyring.set_password("MinerU", "api_token", "your_token_here")
# Criar config.ini
config = configparser.ConfigParser()
config['Settings'] = {
'is_ocr': 'True',
'enable_formula': 'False',
'enable_table': 'True',
'language': 'pt',
'model_version': 'pipeline'
}
config['Paths'] = {
'output_directory': '~/Documents/MinerU_Output'
}
with open('config.ini', 'w') as f:
config.write(f)
# Cliente agora carregará estas configurações
from mineru_client import MineruClient
client = MineruClient()from mineru_client import MineruClient
client = MineruClient()
try:
result = client.upload_batch(['doc.pdf'])
except ValueError as e:
print(f"Configuration error: {e}")
# Abrir settings dialog
except ConnectionError as e:
print(f"Network error: {e}")
# Mostrar mensagem para verificar internet
except TimeoutError as e:
print(f"Timeout: {e}")
# Sugerir retry
except Exception as e:
print(f"Unexpected error: {e}")
# Log e reportarMineruClientnão é thread-safe- Criar instâncias separadas para threads diferentes
- Ou usar locks para proteger acesso compartilhado
- Upload paralelo usa até 5 workers
- Arquivos grandes podem levar vários minutos
- Progress callback é chamado após cada arquivo (não durante)
- Polling interval é 10 segundos (hard-coded)
- Tokens são armazenados em keyring do sistema
- Nunca logados ou impressos
- HTTPS usado para todas as comunicações
- config.ini não deve ser versionado
- Upload paralelo fixado em 5 workers
- Polling interval fixado em 10s
- Sem suporte a cancelamento de upload
- Sem retry automático em falhas de rede
- Sem persistência de estado entre execuções
- Adicionadas docstrings detalhadas
- Melhor tratamento de erros
- Documentação de API completa
- Release inicial
- Upload em lote com paralelismo
- Polling automático
- Download e extração de resultados