browser-core


Namebrowser-core JSON
Version 0.2.4 PyPI version JSON
download
home_pageNone
SummaryUm framework robusto e configurável para automação de navegadores, com gestão de perfis, sessões e uma CLI.
upload_time2025-07-09 01:11:04
maintainerNone
docs_urlNone
authorgabigolo
requires_python>=3.8
licenseMIT
keywords automation selenium web browser framework
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Browser-Core

[![PyPI version](https://badge.fury.io/py/browser-core.svg)](https://badge.fury.io/py/browser-core)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

**Browser-Core** é uma plataforma de orquestração de ambientes de navegador, projetada para automação web em escala, com
foco em eficiência, isolamento e reprodutibilidade total.

---

## Visão Geral

O Browser-Core evoluiu de uma simples biblioteca de automação para uma plataforma de orquestração completa. Ele permite
provisionar, gerir e executar frotas de "Workers" (navegadores) em paralelo, com uma arquitetura robusta e elegante.

A base do framework é um **sistema de snapshots em camadas**, análogo ao Docker e Git, que permite criar, derivar e
reutilizar estados de navegador (como sessões com login efetuado) de forma rápida, eficiente em disco e, crucialmente, *
*100% reprodutível**.

## Conceitos Fundamentais

* **Snapshots em Camadas**: Crie "imagens" do estado do seu navegador (com cookies, `localStorage`, etc.) e derive
  outras a partir delas. Diga adeus à necessidade de repetir o login a cada execução.
* **Workers Isolados**: Execute cada tarefa em um "Worker" limpo e isolado, instanciado a partir de um snapshot,
  garantindo que execuções paralelas não interfiram umas nas outras.
* **API Fluente e Intuitiva**: Interaja com os elementos da página de forma declarativa e legível com o método
  `worker.get()`, que torna a automação mais limpa e de fácil manutenção.
* **Gestão Automática de Drivers**: O `browser-core` faz o download e gere o cache da versão exata do WebDriver
  necessária para cada snapshot, eliminando problemas de compatibilidade.
* **CLI Integrada**: Uma ferramenta de linha de comando para listar, inspecionar e gerir seus snapshots e o
  armazenamento de objetos.

---

## Instalação

A forma recomendada de instalar o `browser-core` é através do PyPI:

```bash
pip install browser-core
```

---

## Um Fluxo de Trabalho Moderno

O uso do `browser-core` é dividido em duas fases lógicas: a **preparação de ambientes** (criação de snapshots) e a *
*execução de tarefas**.

### Fase 1: Criar um Snapshot Reutilizável

Primeiro, você cria um estado base. O caso de uso mais comum é um snapshot com uma sessão de usuário já autenticada.
Este processo é feito uma única vez e automatizado pelo `WorkforceManager`.

```python
# scripts/create_login_snapshot.py
import os
from browser_core import WorkforceManager, Worker, create_selector, ConfigurationError
from browser_core.types import SelectorType

# De preferência, carregue credenciais como variáveis de ambiente
# Nunca coloque senhas ou dados sensíveis diretamente no código.
# Antes de executar, defina as variáveis no seu terminal:
# export APP_USER="meu_usuario@exemplo.com"
# export APP_PASSWORD="minha-senha-super-segura"
APP_USER = os.getenv("APP_USER")
APP_PASSWORD = os.getenv("APP_PASSWORD")


# 1. Defina a função que executa a lógica de setup
def perform_login(worker: Worker):
    """Esta função navega e realiza o login para criar o estado desejado."""
    # Valida se as credenciais foram carregadas do ambiente
    if not APP_USER or not APP_PASSWORD:
        raise ConfigurationError("As variáveis de ambiente APP_USER e APP_PASSWORD devem ser definidas.")

    worker.logger.info("Iniciando processo de login para criar o snapshot...")
    worker.navigate_to("https://app.exemplo.com/login")

    # Define os seletores de forma clara e reutilizável
    EMAIL_INPUT = create_selector("input[name='email']", SelectorType.CSS)
    PASSWORD_INPUT = create_selector("input[name='password']", SelectorType.CSS)
    LOGIN_BUTTON = create_selector("//button[text()='Entrar']", SelectorType.XPATH)

    # Utiliza a API para interagir com a página
    worker.get(EMAIL_INPUT).send_keys(APP_USER)
    worker.get(PASSWORD_INPUT).send_keys(APP_PASSWORD)
    worker.get(LOGIN_BUTTON).click()

    # Aguarda a navegação para a página de dashboard, confirmando o login
    worker.get(create_selector("#dashboard-welcome-message", SelectorType.CSS))
    worker.logger.info("Login realizado com sucesso! Estado pronto para ser capturado.")


# 2. Execute o orquestrador para criar o snapshot
def main():
    workforce = WorkforceManager()

    # Assumindo que um snapshot base para o Chrome já existe.
    # Ele pode ser criado com a CLI ou um script simples.
    BASE_SNAPSHOT = "chrome_base"  # Ex: um snapshot limpo do Chrome
    NEW_SNAPSHOT = "app_logged_in_v1"

    try:
        workforce.create_snapshot_from_task(
            base_snapshot_id=BASE_SNAPSHOT,
            new_snapshot_id=NEW_SNAPSHOT,
            setup_function=perform_login,
            metadata={
                "description": "Sessão autenticada no app.exemplo.com.",
                "user": APP_USER
            }
        )
        print(f"\nSnapshot '{NEW_SNAPSHOT}' criado com sucesso!")
    except Exception as e:
        print(f"\n[!!!] Falha ao criar o snapshot: {e}")


if __name__ == "__main__":
    main()
```

### Fase 2: Executar Tarefas Usando o Snapshot

Com o snapshot `app_logged_in_v1` pronto, você pode executar inúmeras tarefas que dependem de um usuário autenticado, de
forma massivamente paralela, e **sem nunca mais precisar fazer login**.

```python
# scripts/run_report_tasks.py
from browser_core import WorkforceManager, Worker, create_selector, default_settings
from browser_core.types import SelectorType


# --- Lógica da Tarefa ---
# Esta função já parte do princípio que o worker está logado.
def extract_report_data(worker: Worker, report_id: str):
    worker.logger.info(f"Iniciando extração para o relatório: {report_id}")
    worker.navigate_to(f"https://app.exemplo.com/reports/{report_id}")

    REPORT_TABLE = create_selector("#report-data-table", SelectorType.CSS)

    # A simples chamada a .text força o worker a aguardar o elemento aparecer
    table_data = worker.get(REPORT_TABLE).text

    # ... aqui você processaria os dados da tabela ...
    processed_data = {"report_id": report_id, "content_length": len(table_data)}
    worker.logger.info(f"Extração do relatório '{report_id}' concluída.")
    return processed_data


# --- Lógica de Setup do Worker (opcional) ---
# Função executada uma vez por worker antes de ele começar a processar os itens.
def worker_session_setup(worker: Worker) -> bool:
    worker.logger.info(f"Worker {worker.logger.extra['task_id']} está pronto e online.")
    # Poderia, por exemplo, navegar para uma página inicial comum.
    # Retornar True indica que o setup foi bem-sucedido.
    return True


# --- Execução em Lote ---
def main():
    settings = default_settings()
    # Para depuração, é útil desativar o modo headless
    settings["browser"]["headless"] = False

    workforce = WorkforceManager(settings)

    # Lista de tarefas a serem executadas
    reports_to_process = ["Q1-2024", "Q2-2024", "Q3-2024", "Q4-2024"]

    try:
        results = workforce.run_tasks_in_squad(
            squad_size=2,  # Executa 2 navegadores em paralelo
            base_snapshot_id="app_logged_in_v1",  # Usa o estado de login
            task_items=reports_to_process,
            worker_setup_function=worker_session_setup,
            item_processing_function=extract_report_data
        )
        print("\n--- Processamento Concluído ---")
        for res in results:
            print(res)

    except Exception as e:
        print(f"\n[!!!] Uma falha ocorreu durante a execução do esquadrão: {e}")


if __name__ == "__main__":
    main()
```

### Uso da CLI

Use o comando `browser-core` no seu terminal para gerir o ecossistema.

* **Listar snapshots disponíveis:**
    ```bash
    browser-core snapshots list
    ```

* **Inspecionar os detalhes de um snapshot:**
    ```bash
    browser-core snapshots inspect app_logged_in_v1
    ```

* **Limpar todo o armazenamento (cuidado, operação destrutiva!):**
    ```bash
    browser-core storage clean
    ```

---

## Desenvolvimento e Contribuição

Se pretende contribuir para o `browser-core`, siga estes passos para configurar seu ambiente.

1. **Clone o repositório:**
   ```bash
   git clone https://github.com/gabrielbarbosel/browser-core.git
   cd browser-core
   ```

2. **Crie e ative um ambiente virtual:**
   ```bash
   python -m venv .venv
   source .venv/bin/activate  # No Linux/macOS
   # .venv\Scripts\activate    # No Windows
   ```

3. **Instale o projeto em modo "editável":**
   ```bash
   pip install -e .
    

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "browser-core",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": null,
    "keywords": "automation, selenium, web, browser, framework",
    "author": "gabigolo",
    "author_email": null,
    "download_url": "https://files.pythonhosted.org/packages/dc/51/08d0760fd54489af08f9e0a20d096f5089be99765318290b12e60a79e9b6/browser_core-0.2.4.tar.gz",
    "platform": null,
    "description": "# Browser-Core\n\n[![PyPI version](https://badge.fury.io/py/browser-core.svg)](https://badge.fury.io/py/browser-core)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\n**Browser-Core** \u00e9 uma plataforma de orquestra\u00e7\u00e3o de ambientes de navegador, projetada para automa\u00e7\u00e3o web em escala, com\nfoco em efici\u00eancia, isolamento e reprodutibilidade total.\n\n---\n\n## Vis\u00e3o Geral\n\nO Browser-Core evoluiu de uma simples biblioteca de automa\u00e7\u00e3o para uma plataforma de orquestra\u00e7\u00e3o completa. Ele permite\nprovisionar, gerir e executar frotas de \"Workers\" (navegadores) em paralelo, com uma arquitetura robusta e elegante.\n\nA base do framework \u00e9 um **sistema de snapshots em camadas**, an\u00e1logo ao Docker e Git, que permite criar, derivar e\nreutilizar estados de navegador (como sess\u00f5es com login efetuado) de forma r\u00e1pida, eficiente em disco e, crucialmente, *\n*100% reprodut\u00edvel**.\n\n## Conceitos Fundamentais\n\n* **Snapshots em Camadas**: Crie \"imagens\" do estado do seu navegador (com cookies, `localStorage`, etc.) e derive\n  outras a partir delas. Diga adeus \u00e0 necessidade de repetir o login a cada execu\u00e7\u00e3o.\n* **Workers Isolados**: Execute cada tarefa em um \"Worker\" limpo e isolado, instanciado a partir de um snapshot,\n  garantindo que execu\u00e7\u00f5es paralelas n\u00e3o interfiram umas nas outras.\n* **API Fluente e Intuitiva**: Interaja com os elementos da p\u00e1gina de forma declarativa e leg\u00edvel com o m\u00e9todo\n  `worker.get()`, que torna a automa\u00e7\u00e3o mais limpa e de f\u00e1cil manuten\u00e7\u00e3o.\n* **Gest\u00e3o Autom\u00e1tica de Drivers**: O `browser-core` faz o download e gere o cache da vers\u00e3o exata do WebDriver\n  necess\u00e1ria para cada snapshot, eliminando problemas de compatibilidade.\n* **CLI Integrada**: Uma ferramenta de linha de comando para listar, inspecionar e gerir seus snapshots e o\n  armazenamento de objetos.\n\n---\n\n## Instala\u00e7\u00e3o\n\nA forma recomendada de instalar o `browser-core` \u00e9 atrav\u00e9s do PyPI:\n\n```bash\npip install browser-core\n```\n\n---\n\n## Um Fluxo de Trabalho Moderno\n\nO uso do `browser-core` \u00e9 dividido em duas fases l\u00f3gicas: a **prepara\u00e7\u00e3o de ambientes** (cria\u00e7\u00e3o de snapshots) e a *\n*execu\u00e7\u00e3o de tarefas**.\n\n### Fase 1: Criar um Snapshot Reutiliz\u00e1vel\n\nPrimeiro, voc\u00ea cria um estado base. O caso de uso mais comum \u00e9 um snapshot com uma sess\u00e3o de usu\u00e1rio j\u00e1 autenticada.\nEste processo \u00e9 feito uma \u00fanica vez e automatizado pelo `WorkforceManager`.\n\n```python\n# scripts/create_login_snapshot.py\nimport os\nfrom browser_core import WorkforceManager, Worker, create_selector, ConfigurationError\nfrom browser_core.types import SelectorType\n\n# De prefer\u00eancia, carregue credenciais como vari\u00e1veis de ambiente\n# Nunca coloque senhas ou dados sens\u00edveis diretamente no c\u00f3digo.\n# Antes de executar, defina as vari\u00e1veis no seu terminal:\n# export APP_USER=\"meu_usuario@exemplo.com\"\n# export APP_PASSWORD=\"minha-senha-super-segura\"\nAPP_USER = os.getenv(\"APP_USER\")\nAPP_PASSWORD = os.getenv(\"APP_PASSWORD\")\n\n\n# 1. Defina a fun\u00e7\u00e3o que executa a l\u00f3gica de setup\ndef perform_login(worker: Worker):\n    \"\"\"Esta fun\u00e7\u00e3o navega e realiza o login para criar o estado desejado.\"\"\"\n    # Valida se as credenciais foram carregadas do ambiente\n    if not APP_USER or not APP_PASSWORD:\n        raise ConfigurationError(\"As vari\u00e1veis de ambiente APP_USER e APP_PASSWORD devem ser definidas.\")\n\n    worker.logger.info(\"Iniciando processo de login para criar o snapshot...\")\n    worker.navigate_to(\"https://app.exemplo.com/login\")\n\n    # Define os seletores de forma clara e reutiliz\u00e1vel\n    EMAIL_INPUT = create_selector(\"input[name='email']\", SelectorType.CSS)\n    PASSWORD_INPUT = create_selector(\"input[name='password']\", SelectorType.CSS)\n    LOGIN_BUTTON = create_selector(\"//button[text()='Entrar']\", SelectorType.XPATH)\n\n    # Utiliza a API para interagir com a p\u00e1gina\n    worker.get(EMAIL_INPUT).send_keys(APP_USER)\n    worker.get(PASSWORD_INPUT).send_keys(APP_PASSWORD)\n    worker.get(LOGIN_BUTTON).click()\n\n    # Aguarda a navega\u00e7\u00e3o para a p\u00e1gina de dashboard, confirmando o login\n    worker.get(create_selector(\"#dashboard-welcome-message\", SelectorType.CSS))\n    worker.logger.info(\"Login realizado com sucesso! Estado pronto para ser capturado.\")\n\n\n# 2. Execute o orquestrador para criar o snapshot\ndef main():\n    workforce = WorkforceManager()\n\n    # Assumindo que um snapshot base para o Chrome j\u00e1 existe.\n    # Ele pode ser criado com a CLI ou um script simples.\n    BASE_SNAPSHOT = \"chrome_base\"  # Ex: um snapshot limpo do Chrome\n    NEW_SNAPSHOT = \"app_logged_in_v1\"\n\n    try:\n        workforce.create_snapshot_from_task(\n            base_snapshot_id=BASE_SNAPSHOT,\n            new_snapshot_id=NEW_SNAPSHOT,\n            setup_function=perform_login,\n            metadata={\n                \"description\": \"Sess\u00e3o autenticada no app.exemplo.com.\",\n                \"user\": APP_USER\n            }\n        )\n        print(f\"\\nSnapshot '{NEW_SNAPSHOT}' criado com sucesso!\")\n    except Exception as e:\n        print(f\"\\n[!!!] Falha ao criar o snapshot: {e}\")\n\n\nif __name__ == \"__main__\":\n    main()\n```\n\n### Fase 2: Executar Tarefas Usando o Snapshot\n\nCom o snapshot `app_logged_in_v1` pronto, voc\u00ea pode executar in\u00fameras tarefas que dependem de um usu\u00e1rio autenticado, de\nforma massivamente paralela, e **sem nunca mais precisar fazer login**.\n\n```python\n# scripts/run_report_tasks.py\nfrom browser_core import WorkforceManager, Worker, create_selector, default_settings\nfrom browser_core.types import SelectorType\n\n\n# --- L\u00f3gica da Tarefa ---\n# Esta fun\u00e7\u00e3o j\u00e1 parte do princ\u00edpio que o worker est\u00e1 logado.\ndef extract_report_data(worker: Worker, report_id: str):\n    worker.logger.info(f\"Iniciando extra\u00e7\u00e3o para o relat\u00f3rio: {report_id}\")\n    worker.navigate_to(f\"https://app.exemplo.com/reports/{report_id}\")\n\n    REPORT_TABLE = create_selector(\"#report-data-table\", SelectorType.CSS)\n\n    # A simples chamada a .text for\u00e7a o worker a aguardar o elemento aparecer\n    table_data = worker.get(REPORT_TABLE).text\n\n    # ... aqui voc\u00ea processaria os dados da tabela ...\n    processed_data = {\"report_id\": report_id, \"content_length\": len(table_data)}\n    worker.logger.info(f\"Extra\u00e7\u00e3o do relat\u00f3rio '{report_id}' conclu\u00edda.\")\n    return processed_data\n\n\n# --- L\u00f3gica de Setup do Worker (opcional) ---\n# Fun\u00e7\u00e3o executada uma vez por worker antes de ele come\u00e7ar a processar os itens.\ndef worker_session_setup(worker: Worker) -> bool:\n    worker.logger.info(f\"Worker {worker.logger.extra['task_id']} est\u00e1 pronto e online.\")\n    # Poderia, por exemplo, navegar para uma p\u00e1gina inicial comum.\n    # Retornar True indica que o setup foi bem-sucedido.\n    return True\n\n\n# --- Execu\u00e7\u00e3o em Lote ---\ndef main():\n    settings = default_settings()\n    # Para depura\u00e7\u00e3o, \u00e9 \u00fatil desativar o modo headless\n    settings[\"browser\"][\"headless\"] = False\n\n    workforce = WorkforceManager(settings)\n\n    # Lista de tarefas a serem executadas\n    reports_to_process = [\"Q1-2024\", \"Q2-2024\", \"Q3-2024\", \"Q4-2024\"]\n\n    try:\n        results = workforce.run_tasks_in_squad(\n            squad_size=2,  # Executa 2 navegadores em paralelo\n            base_snapshot_id=\"app_logged_in_v1\",  # Usa o estado de login\n            task_items=reports_to_process,\n            worker_setup_function=worker_session_setup,\n            item_processing_function=extract_report_data\n        )\n        print(\"\\n--- Processamento Conclu\u00eddo ---\")\n        for res in results:\n            print(res)\n\n    except Exception as e:\n        print(f\"\\n[!!!] Uma falha ocorreu durante a execu\u00e7\u00e3o do esquadr\u00e3o: {e}\")\n\n\nif __name__ == \"__main__\":\n    main()\n```\n\n### Uso da CLI\n\nUse o comando `browser-core` no seu terminal para gerir o ecossistema.\n\n* **Listar snapshots dispon\u00edveis:**\n    ```bash\n    browser-core snapshots list\n    ```\n\n* **Inspecionar os detalhes de um snapshot:**\n    ```bash\n    browser-core snapshots inspect app_logged_in_v1\n    ```\n\n* **Limpar todo o armazenamento (cuidado, opera\u00e7\u00e3o destrutiva!):**\n    ```bash\n    browser-core storage clean\n    ```\n\n---\n\n## Desenvolvimento e Contribui\u00e7\u00e3o\n\nSe pretende contribuir para o `browser-core`, siga estes passos para configurar seu ambiente.\n\n1. **Clone o reposit\u00f3rio:**\n   ```bash\n   git clone https://github.com/gabrielbarbosel/browser-core.git\n   cd browser-core\n   ```\n\n2. **Crie e ative um ambiente virtual:**\n   ```bash\n   python -m venv .venv\n   source .venv/bin/activate  # No Linux/macOS\n   # .venv\\Scripts\\activate    # No Windows\n   ```\n\n3. **Instale o projeto em modo \"edit\u00e1vel\":**\n   ```bash\n   pip install -e .\n    \n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Um framework robusto e configur\u00e1vel para automa\u00e7\u00e3o de navegadores, com gest\u00e3o de perfis, sess\u00f5es e uma CLI.",
    "version": "0.2.4",
    "project_urls": {
        "Bug Tracker": "https://github.com/gabrielbarbosel/browser-core/issues",
        "Homepage": "https://github.com/gabrielbarbosel/browser-core",
        "Repository": "https://github.com/gabrielbarbosel/browser-core"
    },
    "split_keywords": [
        "automation",
        " selenium",
        " web",
        " browser",
        " framework"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "3f8642001f57d35e5dec21bded66abbc7dc81474a94aa9cb6df7f55921afb159",
                "md5": "2f1ce69d1cb275fe96fdc0fe2c09220f",
                "sha256": "b801b7f7fde99e9a44d4e7f3a322bf49c7319c67c839809878482477e8f88118"
            },
            "downloads": -1,
            "filename": "browser_core-0.2.4-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "2f1ce69d1cb275fe96fdc0fe2c09220f",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 35233,
            "upload_time": "2025-07-09T01:11:02",
            "upload_time_iso_8601": "2025-07-09T01:11:02.957619Z",
            "url": "https://files.pythonhosted.org/packages/3f/86/42001f57d35e5dec21bded66abbc7dc81474a94aa9cb6df7f55921afb159/browser_core-0.2.4-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "dc5108d0760fd54489af08f9e0a20d096f5089be99765318290b12e60a79e9b6",
                "md5": "3341c9d04563a2fb42f85969400fc374",
                "sha256": "616c158fa6c5688f9dfef6988b61f4df07e972c30ecb1952ff033eaae85ed77e"
            },
            "downloads": -1,
            "filename": "browser_core-0.2.4.tar.gz",
            "has_sig": false,
            "md5_digest": "3341c9d04563a2fb42f85969400fc374",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 31494,
            "upload_time": "2025-07-09T01:11:04",
            "upload_time_iso_8601": "2025-07-09T01:11:04.575338Z",
            "url": "https://files.pythonhosted.org/packages/dc/51/08d0760fd54489af08f9e0a20d096f5089be99765318290b12e60a79e9b6/browser_core-0.2.4.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-07-09 01:11:04",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "gabrielbarbosel",
    "github_project": "browser-core",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "browser-core"
}
        
Elapsed time: 1.01747s