Metadata-Version: 2.5
Name: analog-sdk
Version: 0.20.0
Summary: Command-line app and Python SDK for Analog, a web interface built for AIs.
Project-URL: Homepage, https://getanalog.io
Project-URL: Documentation, https://getanalog.io/docs/
Project-URL: Changelog, https://getanalog.io/docs/changelog/
Author-email: Marcus Campbell <marcus@getanalog.io>
License: MIT
License-File: LICENSE
Keywords: ai-agents,deterministic,html-parsing,llm-tools,structured-data,web-extraction
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: backports-zstd>=1.0; python_version < '3.14'
Requires-Dist: click>=8.1
Requires-Dist: filelock>=3.13
Requires-Dist: httpx>=0.27
Requires-Dist: lxml>=5.2
Requires-Dist: marcato<0.5.0,>=0.4.0
Requires-Dist: playwright<2,>=1.49
Requires-Dist: protego>=0.4
Requires-Dist: pydantic>=2.6
Requires-Dist: pyyaml>=6.0
Requires-Dist: rich>=13
Requires-Dist: typing-extensions>=4.4
Provides-Extra: dataframe
Requires-Dist: pandas>=2.0; extra == 'dataframe'
Description-Content-Type: text/markdown

# analog-sdk

Command-line app and Python SDK for [Analog](https://getanalog.io).
**Analog lets any AI understand websites as code.** Analog is a web interface
built for AIs. It converts webpages into the things they contain — products,
articles, events, and other records — so AIs can query, compare, export, and use
them directly. The extraction pipeline contains no LLMs. Given the same page
URL and HTML, the same engine produces the same records. A live page's HTML can
change between fetches.

## Install

macOS, Linux, or WSL:

<!-- BEGIN GENERATED: onboarding sdk-install-shell -->

```bash example=runnable scenario=onboarding-sdk-install-shell
curl -LsSf https://getanalog.io/install | sh
```
<!-- END GENERATED: onboarding sdk-install-shell -->

Windows PowerShell:

<!-- BEGIN GENERATED: onboarding sdk-install-powershell -->

```powershell example=runnable scenario=onboarding-sdk-install-powershell
powershell -ExecutionPolicy ByPass -c "irm https://getanalog.io/install.ps1 | iex"
```
<!-- END GENERATED: onboarding sdk-install-powershell -->

The installer puts the `analog` command on your PATH as an isolated
[`uv`](https://docs.astral.sh/uv/) tool. If uv is already installed:

<!-- BEGIN GENERATED: onboarding sdk-install-uv -->

```bash example=runnable scenario=onboarding-sdk-install-uv
uv tool install analog-sdk
```
<!-- END GENERATED: onboarding sdk-install-uv -->

Homebrew users can instead run
`brew install getanalog/tap/analog`; `pipx install analog-sdk` and
`pip install analog-sdk` in a managed virtual environment also work with
Python 3.10+.

Analog's built-in browser downloads automatically on first `browse` use.
Supplying a page file to `view` needs no browser download. To prepare the fallback:

<!-- BEGIN GENERATED: onboarding browser-preinstall -->

```bash example=runnable scenario=onboarding-browser-preinstall-default
analog browser install
```
<!-- END GENERATED: onboarding browser-preinstall -->

The complete installation options and CI guidance live in the
[installation guide](https://getanalog.io/docs/install/).

Create an account and connect this terminal (an invite code is required
during the private alpha):

<!-- BEGIN GENERATED: onboarding new-user-auth -->

```bash example=runnable scenario=onboarding-new-user-auth-default
analog signup
```
<!-- END GENERATED: onboarding new-user-auth -->

For an existing account or another machine:

<!-- BEGIN GENERATED: onboarding existing-user-auth -->

```bash example=runnable scenario=onboarding-existing-user-auth-default
analog login
```
<!-- END GENERATED: onboarding existing-user-auth -->

On an interactive machine without a browser:

<!-- BEGIN GENERATED: onboarding existing-user-auth-browserless -->

```bash example=runnable scenario=onboarding-existing-user-auth-browserless
analog login --no-browser
```
<!-- END GENERATED: onboarding existing-user-auth-browserless -->

Open its link in a browser elsewhere, then paste the one-time handoff at
the hidden prompt.

The credential is stored locally and picked up automatically by the SDK,
CLI, and MCP server; see
[authentication](https://getanalog.io/docs/authenticate/) for its storage,
scope, and revocation model.

## View a page from your browser

Use your agent's browser to open [Analog's About page](https://getanalog.io/about/).
The browser handles navigation and interaction; Analog makes the captured
content available for searching, inspection, and reuse.

For a harness browser with supported JavaScript evaluation and Node filesystem
access, prepare a reusable helper at a new path:

```bash example=illustrative fragment=true
analog browser capture-script --output ./analog_capture.mjs
```

Import the returned path inside the browser tool's runtime, then call
`capturePage({evaluate, path})` with its supported evaluator and a new absolute
capture path. Return only the receipt. The
[Codex GUI capture recipe](https://getanalog.io/docs/fetching/#capture-from-your-browsers-current-page)
shows the binding and capture limits; other environments need their own
supported evaluator. Capture does not change the live page.

Use the capture's actual path and an unused saved name:

```bash example=illustrative fragment=true
analog view ./about.capture.json --save-as about --find "Frankie"
analog view about --find "Marcus" --find "Frankie"
```

The first command validates the capture, sends its prepared HTML and actual
URL for extraction, saves the result, and returns matching evidence. Matches
go to stdout; the handle and capture qualifications go to stderr. The second
command searches the saved result locally, without fetching or extracting again.
Observed shadow/frame omissions remain qualified in the saved result.

Already have ordinary HTML? Use `analog view ./about.html --url
https://getanalog.io/about/ --save-as about --find Frankie`. The URL identifies
the captured page; `view` never fetches it. `--mode local` converts a supplied
page to Markdown without sending its HTML or URL to Analog.

Request an overview with `analog view about`, or ingest a file with
`--save-only` when you just want its receipt. Use handles or names with
`describe`, `distinct`, `export`, and `diff` as the task requires. For batch
JSON, `queries` contains each pattern and indexes into the shared `matches`
array; an empty index list means no matches in this capture.

## When you need Analog's browser

If your environment cannot supply a capture, or you choose Analog to acquire
the URL, use its built-in browser:

```bash wrap=true example=runnable scenario=cli-browse-find-about
analog browse https://getanalog.io/about/ --find "Frankie"
```

`browse` renders, saves, and searches in one command. It starts a fresh browser
session, separate from your browser's sign-in. The printed handle identifies
this result for later use; `analog view latest --find Marcus` searches the
most recent save. Bare `browse URL` returns a receipt. `--json` and `--markdown`
select full data; `--no-save` requires one of those formats. `--find --json`
returns full matching objects; `--find` cannot combine with `--markdown` or
`--no-save`. Put `--guidance` before `browse` or `view` for an optional next action.

## In Python

Supply HTML captured in your environment:

```python example=illustrative fragment=true
from pathlib import Path
from analog import analog

html = Path("about.html").read_text(encoding="utf-8")
result = analog("https://getanalog.io/about/", html=html)
print(result.find("Frankie"))
```

Omit `html=` to use Analog's built-in browser. `analog()` also accepts an
`HttpFetcher` or a custom `Fetcher`; `reveal_all`, `load_all`, `expand_all`, and
`pages` control built-in acquisition. The [Fetching guide](https://getanalog.io/docs/fetching/)
owns those options. `mode="local"` converts to Markdown without hosted extraction.
Use `result.preview()` when an overview would help; `guidance=True` adds an
available next action, and `complete=True` includes hidden fields in its summary.

## Result shape

An `AnalogResponse` holds the page's data and offers views over it:

- `sections` is the readable document sequence: extracted record sections and
  locally rendered `MarkdownSection` regions together in page order. Its order
  comes from the response's required `document_section_plan`; an unresolved
  prose region remains present with empty markdown instead of disappearing.
- `structured_content` is the ordered list of extracted `Section` objects.
- Each section carries `records`, field metadata, and its own markdown.
- `collections` provides high-confidence unions over compatible physical
  sections, with one identity-deduplicated local records view and pointers
  back to every placement.
- `outline` reports the significant page areas and what happened to them.
- `navigation` preserves the page's labeled link trees.
- `warnings`, pagination details, and browse actions disclose partial or
  uncertain coverage.
- `handle` identifies the local saved result.

Use `find(...)` for a known value, `result.section(label)` or
`sections_by_kind(kind)` for a known area, or `result.preview()` when an
overview would help. Export helpers include `to_json()`, `to_yaml()`,
`to_csv()`, and the optional pandas-backed `to_dataframe()`.

A page can contain several unrelated sections: for example, a catalog,
a reviews area, and a comparison table. Analog preserves those boundaries
instead of silently pooling unlike records. When several physical sections
are confidently parts of the same dataset, `result.collections[0].records`
offers the combined view while `collection.sections` preserves every authored
placement. Work with one section, one Collection, all sections of a shared
kind, or project common fields explicitly. Field names are a best-effort
starting point when the page supplies no useful label; field values preserve
what the page rendered. Coverage notes call out withheld content, unusual
rows, page-owned truncation, pagination, and interactive controls that were
available but not used.

Results are saved by default as structured records, ordered Markdown regions,
and page markdown, never raw HTML. Reopen them with `analog.open(handle)`,
`latest()`, and `history()`; pass `save=False` to skip persistence. The
[Results guide](https://getanalog.io/docs/results/) covers querying,
field statistics, filters, numeric values, exports, renaming, several
sections on one page, retention, and CLI exit codes. Exact Python names,
parameters, and return types are in the compact
[Python API reference](https://getanalog.io/docs/api-reference/).

## Data flow and privacy

For URL acquisition, pages are rendered in a browser on your machine by default. The built-in
browser starts a fresh session and does not use your browser profile, cookies,
or saved credentials. For structured extraction, the rendered page content and
its URL are sent to Analog. Results return to the SDK and are saved locally
unless disabled. Signed-in page content is sent only when you explicitly supply it.
`mode="local"` converts the page
to Markdown on your machine and sends nothing to Analog.

Supply signed-in content through a capture or HTML file to `view`, Python's
`html=`, or a custom fetcher. Your capture files remain on disk; `view` does not
delete them. Raw HTML is used for extraction and local Markdown conversion,
then dropped rather than written to the result store. Point Analog at content
that is acceptable to send. Local and private-network targets are declined by
default. The built-in browser checks redirects, client navigation,
subresources, and WebSockets before connecting, including whether each
hostname currently resolves only to public addresses. Reaching a trusted
development server or intranet host requires the explicit
`allow_private=True` opt-in. This request guard does not pin Chromium to the
DNS answer Python checked; the linked security guide
states that rebinding limit.

Library failures derive from `AnalogError`, with narrower types for
authentication, connectivity, rate limits, version skew, fetch refusals,
robots.txt decisions, incompatible sections, and saved-result problems.
Catch the narrow type when your application has a specific recovery path;
otherwise catch `AnalogError` at the integration boundary. The API
reference lists the complete exception inventory.

Extraction URLs are never logged. A quality report includes the URL you
explicitly submit; it never includes page content. Read
[Privacy](https://getanalog.io/docs/privacy/) for the complete data contract,
[Security](https://getanalog.io/docs/security/) for credential and network
boundaries, and [Fetching](https://getanalog.io/docs/fetching/) for fetching
identity and controls.

## Where to go next

- [Quickstart](https://getanalog.io/docs/quickstart/) — the shortest path
  from installation to a useful saved result.
- [Fit check](https://getanalog.io/docs/assess/) — decide whether a page
  belongs in a structured extraction workflow before spending one.
- [Fetching](https://getanalog.io/docs/fetching/) and
  [Results](https://getanalog.io/docs/results/) — control page capture,
  then query and export what came back.
- [MCP server](https://getanalog.io/docs/mcp/) — expose the same workflow
  as tools to an MCP client.
- [Limitations](https://getanalog.io/docs/limitations/) and
  [Troubleshooting](https://getanalog.io/docs/troubleshooting/) — known
  boundaries and fixes for common failures.

The docs site is the durable owner for task guidance; this README stays a
short landing page. `analog docs` prints its URL when you need to hand the
documentation to another process, and the core docs are also included in
the site's `/llms.txt` and `/llms-full.txt` views.

Use `analog feedback` to report a poor extraction or request a feature.
Use `analog contact` or email [hello@getanalog.io](mailto:hello@getanalog.io)
for support.

## License

MIT — see [LICENSE](./LICENSE).
