Documentation navigation

Input and output data reference

Application version: 1.0.0Documentation version: 1.0.1Last technical review: 2026-10-17View Source Code on GitHub →

Written by Elena David, SEO, ORM, and AI Visibility Consultant.

Input file format

Both snapshots are CSV files opened with:

csv_path.open("r", encoding="utf-8-sig", newline="")

utf-8-sig accepts ordinary UTF-8 and removes an initial UTF-8 byte-order mark when present. csv.DictReader maps column headers to text values.

Required input fields

Field Python value after loading Required Constraint Fictional example
review_id str Yes Non-empty after trimming; first valid occurrence must be unique within the file. REV-021
practice_id str Yes Non-empty after trimming. PR-006
practice_name str Yes Non-empty after trimming. Cabinet Médical Exemple
review_date datetime.date Yes Must be accepted by date.fromisoformat(); use YYYY-MM-DD for documented interoperability. 2026-10-12
rating int Yes Must convert with int() and be in range(1, 6). 2
review_text str Yes Non-empty after trimming. Fictional review
source_label str Yes Non-empty after trimming. Demo Reviews

All required values are stripped of leading and trailing whitespace. Header names are not stripped or case-normalized.

Although the validation message describes YYYY-MM-DD, Python 3.11's date.fromisoformat() accepts some additional ISO 8601 forms. Use YYYY-MM-DD; version 1.0 does not explicitly enforce a regular expression for that exact representation.

Structural validation

The loader compares the header set with the seven required names. One or more missing names raise:

Missing required columns: field_name, another_field

An empty file has no field names and therefore reports all required columns as missing. Extra columns are ignored.

Row validation messages

Condition Message form Result
Empty required value empty required field(s): ... Row skipped.
Rating cannot convert with int() rating must be a whole number from 1 to 5 Row skipped.
Integer outside 1–5 rating must be from 1 to 5 Row skipped.
Date conversion fails review_date must use YYYY-MM-DD format Row skipped.
Valid ID already seen duplicate review_id '...' in this input Later row skipped.

CSV data rows begin at reported row 2 because row 1 is the header.

In-memory types

Review
├── review_id: str
├── practice_id: str
├── practice_name: str
├── review_date: date
├── rating: int
├── review_text: str
└── source_label: str

LoadResult contains reviews: list[Review] and issues: list[ValidationIssue].

Supported website extraction methods

The importer attempts these methods in order and reports the first format that produces valid records:

  1. Schema.org Review JSON-LD in application/ld+json scripts, including reviews nested under an organization or medical-practice entity.
  2. Schema.org Review Microdata using itemscope, itemtype, and itemprop attributes.
  3. Operator-provided CSS selectors, when enabled in Streamlit.
  4. The existing article.review layout.

JSON-LD and Microdata mappings use reviewRating.ratingValue or ratingValue, datePublished, reviewBody or description, and itemReviewed.name. @id, identifier, itemid, and source URLs are retained when present.

The article.review layout uses data-review-id and data-practice-id when available. It contains .review-practice, .review-rating with data-rating or visible rating text, time[datetime], .review-text, and an optional a.review-source[href].

<article class="review" data-review-id="web-001" data-practice-id="practice-demo">
  <h2 class="review-practice">Clinique Exemple Rivoli</h2>
  <span class="review-rating" data-rating="2">2 stars</span>
  <time datetime="2026-10-15">15 October 2026</time>
  <p class="review-text">The appointment began later than expected.</p>
  <a class="review-source" href="/reviews/web-001">Source</a>
</article>

Extracted fields pass through the same validation as CSV rows. The importer accepts public HTTP(S) URLs only, checks robots.txt, validates redirect destinations, blocks non-public IP space, limits redirects to three and HTML to 2 MB, and uses connection/read timeouts. It does not support arbitrary markup, authenticated pages, CAPTCHAs, JavaScript rendering, or Google review pages.

When a source omits a review or practice identifier, the importer generates a deterministic identifier and displays a notice in the preview. A generated review identifier can change if its source content changes. Missing ratings and dates are not generated or defaulted: the record fails validation and the preview reports the missing fields.

For a custom static layout, configure a container selector plus selectors for review text, rating, date, and practice name. Review ID, practice ID, and source URL selectors are optional. Attribute settings support values stored in attributes such as data-rating, datetime, or href. Invalid selectors produce an unsupported-format error rather than a partial analysis.

Alert CSV output

The alert writer emits the seven review fields plus:

Field Type in CSV Value
alert_reason Text Generated from maximum_rating; the default is New review rated 1 or 2 stars.

Dates are serialized with date.isoformat(). CSV files contain text, so consumers must parse the rating if they require an integer type.

The output uses UTF-8, includes a header even when no alerts exist, and is overwritten on each run to the same path.

HTML output

The HTML report contains summary counts, a six-column alert table when comparison is available, and validation messages. Dynamic text is HTML-escaped. With no previous snapshot it explicitly states that comparison was not run and does not identify reviews as new. It does not embed the output CSV's practice_id or alert_reason fields.

See Error handling and validation for control flow after each type of problem.