Metadata-Version: 2.5
Name: analog-sdk
Version: 0.19.0
Summary: Command-line app and Python SDK for Analog — Analog lets any AI understand websites as code. Webpages in, structured records out: deterministic, zero-shot, honest.
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.4.0,>=0.3.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.** The perception layer for
LLMs: webpages in, structured records out. Deterministic, zero-shot, honest.
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 browser downloads automatically on first use. To install it
ahead of time:

<!-- 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.

## Extract a page

From the shell:

```bash example=runnable scenario=cli-extract-quotes
analog get https://quotes.toscrape.com/js/
```

Analog renders the page, returns its structured records, saves the result
locally, and prints a handle such as `20260719-k7m2p9`. Use that handle
with `analog open`, `describe`, `find`, `distinct`, `export`, or `diff`
without fetching the page again. Run `analog --help` for the complete
command surface.

The same call in Python:

```python example=runnable scenario=python-extract-preview
from analog import analog

result = analog("https://quotes.toscrape.com/js/")
print(result.preview())

for section in result.structured_content:
    print(section.label, section.records)
```

`analog()` uses the built-in browser by default. Its main controls are
`reveal_all`, `load_all`, `expand_all`, and `pages`; the
[Fetching guide](https://getanalog.io/docs/fetching/) explains when to
use each. Pass `fetcher=HttpFetcher()` for a plain HTTP request, supply
your own `Fetcher`, or use `html=` when you already have the page content.
For a local markdown conversion with no extraction or account, set
`mode="local"`.

## Result shape

An `AnalogResponse` is an orientation view plus the page's data:

- `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.

Read `result.preview()` first. Then use `result.section(label)`,
`sections_by_kind(kind)`, or `find(...)` to narrow the data before pulling
whole record sets. 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

Pages are fetched on your machine by default. The SDK uses a local headless
browser, which visits as an unauthenticated user by default. For structured
extraction, the SDK sends the URL and rendered page content to Analog. Results
return to the SDK and are saved locally unless disabled. Authenticated content
is sent only when you explicitly provide it through `html=` or a custom
fetcher. `mode="local"` is the Markdown-only path that sends nothing.

Raw HTML is used for the extraction request 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).
