Welcome to the WUiW Docs

What's Up in Windsor is an online civic archive, built to help busy residents stay informed on local government decisions.

System Architecture

The intent is to make it easier for residents to follow the, lets be honest: less-than-enthralling proceedings of local government. How?

  1. It requests official meeting documents (minutes, agendas, etc.) from the town's web host.
  2. It downloads the text and sends it to a Large Language Model for summarization.
  3. It stores the summary in a local WUiW database.
  4. Then, the summaries are posted to whatsupinwindsor.com for easy reader digest.

WUiW System Architecture Diagram

Main Pipeline Source Code

Source code in wuiw/main.py
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
def main():
    """
    Main Pipeline Source Code
    """
    # Initialize run conditions
    run_id = None
    new_assignments = 0
    failed_assignments = 0
    status = STATUS_FAILED
    error = None
    ai_log.reset()
    civic_log.reset()

    try:
        run_id = open_intake(datetime.now())
        ai_log.set_run_id(run_id)
        civic_log.set_run_id(run_id)
        logger.info("WUIW pipeline started")

        # Fetch RSS feed
        logger.info("Pinging RSS feed.")
        try:
            new_leads = get_rss(RSS_URL)
        except Exception as e:
            logger.error("Feed parsing failed: %s", e)
            status = STATUS_FAILED
            error = "Feed parsing failed, see logs for details"
            raise
        logger.info(f"RSS fetch returned {len(new_leads)} new leads")

        # Enter new assignments to db table: assignments
        save_assignments(new_leads, run_id=run_id)
        logger.info(f"Assignments saved")

        # Compile a list of pending assignments
        assignments = assign()
        new_assignments = len(assignments)
        logger.info(f"{len(assignments)} assignments pending")

        # Send assignments to reporter to transcribe docs. 
        # TODO: Parameter doc_type is set to "minutes" for v1.0, update in later versions
        for assignment in assignments:
            failed = False
            documents, status, error = fetch_documents(assignment["materials"], doc_type="minutes")
            if not documents:
                update_status(assignment["meeting_id"], status, error)
                logger.warning(f"fetch_documents failed for {assignment['meeting_id']}: {error}")
                failed = True
                continue
            logger.info(f"Fetched {len(documents)} documents for {assignment['meeting_id']}")

            # Summarize documents. 
            for doc_type, text in documents.items():
                article, status, error = write_article(assignment["meeting_id"], text, doc_type)
                if not article:
                    update_status(assignment["meeting_id"], status, error)
                    logger.warning(f"write_article failed for {assignment['meeting_id']}: {error}")
                    failed = True
                    continue
                save_articles([article])
                logger.info(f"Article saved: {article['meeting_id']} {doc_type}")
                update_status(article["meeting_id"], status, error)

            # count failure
            if failed:
                failed_assignments += 1

        if failed_assignments == new_assignments and new_assignments > 0:
            status = STATUS_FAILED
            error = "all assignments failed"
        elif failed_assignments > 0 and failed_assignments < new_assignments:
            status = STATUS_WARNING
            error = f"{failed_assignments} assignments failed"
        else:
            status = STATUS_COMPLETE
            error = None

        logger.info("WUIW pipeline complete")
    except Exception as e:
        status = STATUS_FAILED
        error = "WUIW pipeline failed, see logs for details"
        logger.error("WUIW pipeline failed. Error: %s", e)
    finally:
        # log http/api requests
        save_civic_log(civic_log.info)
        save_ai_log(ai_log.info)

        if not run_id:
            logger.warning("WUIW pipeline not captured in intake_records. It may not have succeeded. Check logs for details.")
        else:
            close_intake(run_id, datetime.now(), status, new_assignments, failed_assignments, error=error)

        if status == STATUS_FAILED:
            send_alert(error)

See the API refereence for details, and visit www.whatsupinwindsor.com to find out what happened at the last town council meeting in 2 minutes or less.