# Component Declaration Status Python Script Generator (BOM CSV vs Supplier Declarations)

> Source: https://netray.co/tools/component-declaration-status-python-script-generator
> Publisher: Netray (netray.co), AI and integration engineering for ERP and manufacturing systems.
> Section: Free Tools

## Short answer

Creates a standard-library Python script that reads a BOM export and a declarations export and writes a gap report CSV.

## Category

developer

## Audience

- Compliance engineer
- Supplier quality
- Data analyst

## Tool

**Kind:** template

**Output:** code

**Language:** python

**Fields:**

#### BOM CSV file

**Key:** bom_file

**Type:** text

**Default:** bom_export.csv

#### Declarations CSV file

**Key:** decl_file

**Type:** text

**Default:** declarations.csv

#### Output CSV file

**Key:** out_file

**Type:** text

**Default:** compliance_gaps.csv

#### Part number column name

**Key:** part_col

**Type:** text

**Default:** part_number

#### Status column in declarations

**Key:** status_col

**Type:** text

**Default:** status

#### Declaration date column

**Key:** date_col

**Type:** text

**Default:** declaration_date

#### Value meaning compliant

**Key:** good_value

**Type:** text

**Default:** Compliant

#### Maximum age in days

**Key:** max_age

**Type:** number

**Default:** 730

**Blocks:**

#### check_declarations.py

**Body:** import csv
from datetime import date, datetime

BOM_FILE = "{{bom_file}}"
DECL_FILE = "{{decl_file}}"
OUT_FILE = "{{out_file}}"
PART_COL = "{{part_col}}"
STATUS_COL = "{{status_col}}"
DATE_COL = "{{date_col}}"
GOOD_VALUE = "{{good_value}}"
MAX_AGE_DAYS = {{max_age}}

def load_declarations(path):
    result = {}
    with open(path, newline="", encoding="utf-8-sig") as handle:
        for row in csv.DictReader(handle):
            part = row[PART_COL].strip().upper()
            result[part] = row
    return result

def age_in_days(text):
    try:
        return (date.today() - datetime.strptime(text.strip(), "%Y-%m-%d").date()).days
    except ValueError:
        return None

def main():
    declarations = load_declarations(DECL_FILE)
    gaps = []
    with open(BOM_FILE, newline="", encoding="utf-8-sig") as handle:
        for row in csv.DictReader(handle):
            part = row[PART_COL].strip().upper()
            decl = declarations.get(part)
            if decl is None:
                gaps.append([part, "MISSING", ""])
            elif decl[STATUS_COL].strip() != GOOD_VALUE:
                gaps.append([part, "NOT COMPLIANT", decl[DATE_COL]])
            else:
                age = age_in_days(decl[DATE_COL])
                if age is None:
                    gaps.append([part, "BAD DATE", decl[DATE_COL]])
                elif age > MAX_AGE_DAYS:
                    gaps.append([part, "EXPIRED", decl[DATE_COL]])
    with open(OUT_FILE, "w", newline="", encoding="utf-8") as handle:
        writer = csv.writer(handle)
        writer.writerow(["part_number", "gap_reason", "declaration_date"])
        writer.writerows(gaps)
    print("Gaps found:", len(gaps), "written to", OUT_FILE)

if __name__ == "__main__":
    main()

#### Expected input layout

**Body:** # BOM CSV header:          {{part_col}},description,qty
# Declarations CSV header: {{part_col}},{{status_col}},{{date_col}}
# Dates must be YYYY-MM-DD. Status text must match: {{good_value}}

**Notes:** Uses only the Python standard library (3.8 or newer). Both CSV files need the part number column under the same name. Dates must be ISO format. Test on a small sample first and review the output manually before acting on it.

## Content

**Intro:** Not every team can query the ERP database directly. If you can export a BOM and a declarations list to CSV, this generator gives you a small script that finds missing, non compliant and expired declarations without any extra libraries.

**Sections:**

#### How to use the script

**Body:** Fill in the file names, the column header names in your exports, the text that means compliant and the maximum age in days. Copy the generated code into a file named check_declarations.py, place it in the same folder as the two CSV files and run it with Python. The result is a CSV that you can open in Excel and send to buyers or suppliers as a chase list.

#### Logic behind the checks

**Body:** The script builds a dictionary of declarations keyed by upper case part number, then walks the BOM. A part with no entry is MISSING. A part whose status differs from your compliant text is NOT COMPLIANT. A compliant part whose date is older than the limit is EXPIRED, and a date that cannot be read is flagged as BAD DATE so bad data is never silently accepted. Normalising case and spaces avoids false gaps from inconsistent part numbers.

#### Extending it

**Body:** Common additions are a second key for manufacturer part numbers, one declaration file per regulation, and an exemption column that lists the RoHS exemption relied on. You can also email the output to buyers or write it back through the ERP API. If you do automate writing back, keep a human approval step so a data error cannot change item status.

#### Common mistakes

**Body:** Mismatched part numbers cause most false results: leading zeros lost in Excel, revision suffixes, and supplier versus internal numbering. Open CSVs in a text editor to check encoding, and keep a lookup of cross references. Also remember that a clean report only shows that a record exists, not that the supplier data is correct, so keep a risk based sampling and test program.

**Cta:** For a version that reads directly from your ERP and supplier portals, with logging and approvals, Netray can help design it.

**Faq:**

#### Do I need to install any package?

**Answer:** No. The script uses the csv and datetime modules that ship with Python 3.8 and later, so it runs on a locked down workstation without installing anything from the internet.

#### What if my dates are in another format?

**Answer:** Change the format string in the age_in_days function, for example to %d/%m/%Y for day first dates. It is best to export dates in ISO format, which also sorts correctly.

#### Can it handle several regulations?

**Answer:** Run it once per regulation with a separate declarations file, or add a regulation column and filter on it. Keeping separate outputs makes it easier to assign follow up to different owners.

#### Is the output proof of compliance?

**Answer:** No. It only shows which parts have a declaration on file that meets your rule. Compliance still depends on the content and reliability of those declarations, supported by your verification and testing plan.

## Search terms

python script bom compliance check, compare bom csv with supplier declarations, rohs declaration expiry script, reach compliance automation python, component compliance csv report, supplier declaration tracker script, bom gap analysis python, csv compliance validator

---
Talk to an engineer: https://netray.co/contact?intent=erp_ai | Machine catalog: https://netray.co/agent/catalog.json
