From b8229955d0949fa03b843fa189d96fa375ccafa9 Mon Sep 17 00:00:00 2001 From: devchima Date: Wed, 26 Feb 2025 03:10:06 -0500 Subject: [PATCH 1/8] Fix xls import --- home/import_assessments.py | 16 +++++++++------- .../assessment_empty_values.xlsx | Bin 0 -> 14768 bytes home/tests/test_assessment_import_export.py | 12 ++++++++++++ 3 files changed, 21 insertions(+), 7 deletions(-) create mode 100644 home/tests/import-export-data/assessment_empty_values.xlsx diff --git a/home/import_assessments.py b/home/import_assessments.py index 0b23c9b3..cf80cb7c 100644 --- a/home/import_assessments.py +++ b/home/import_assessments.py @@ -115,16 +115,18 @@ def parse_file(self) -> list["AssessmentRow"]: row_iterator = helper_parse_file(self.file_content, self.file_type) rows = [row for _, row in row_iterator] - original_headers = rows[0].keys() - headers_mapping = convert_headers_to_snake_case( - list(original_headers), row_num=1 - ) + original_headers = list(rows[0].keys()) + headers_mapping = convert_headers_to_snake_case(original_headers, row_num=1) snake_case_headers = list(headers_mapping.values()) self.validate_headers(snake_case_headers, row_num=1) - transformed_rows = [ - {headers_mapping[key]: value for key, value in row.items()} for row in rows - ] + + transformed_rows = [] + for _i, row in enumerate(rows, start=1): + transformed_row = { + headers_mapping.get(key, key): value for key, value in row.items() + } + transformed_rows.append(transformed_row) return [ AssessmentRow.from_flat(row, i + 2) diff --git a/home/tests/import-export-data/assessment_empty_values.xlsx b/home/tests/import-export-data/assessment_empty_values.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..ca0347ea04d47ff6f3cb972af3af7a90f8caa546 GIT binary patch literal 14768 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 None: content_pages = Assessment.objects.all() assert len(content_pages) > 0 + def test_import_assessment_empty_values_xlsx( + self, xlsx_impexp: ImportExport + ) -> None: + """ + Importing an XLSX Assessments file where the corresponding cell is empty + should not break. + """ + xlsx_impexp.import_content_file("assessment_results.xlsx", purge=False) + xlsx_impexp.import_file("assessment_empty_values.xlsx", purge=False) + content_pages = Assessment.objects.all() + assert len(content_pages) > 0 + def test_invalid_high_inflecton_format(self, xlsx_impexp: ImportExport) -> None: """ Importing an xlsx with a comma in high inflecton value From 139d891107e514bc365a65aea72326a410072d5c Mon Sep 17 00:00:00 2001 From: devchima Date: Wed, 26 Feb 2025 03:11:41 -0500 Subject: [PATCH 2/8] Update Changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 120d6ce7..56ff34e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Test coverage report - Changed Assessments to CMS Forms - Validation for high_inflection, medium_inflection and score field on CMS Forms +- Fix cms-forms xls import ### Removed - Locale field on exports - Menu app From 6e43f9d899f729e3cdf50f59682071a5b7b495ed Mon Sep 17 00:00:00 2001 From: devchima Date: Wed, 26 Feb 2025 05:48:36 -0500 Subject: [PATCH 3/8] Clean up xls file --- .../assessment_empty_values.xlsx | Bin 14768 -> 14775 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/home/tests/import-export-data/assessment_empty_values.xlsx b/home/tests/import-export-data/assessment_empty_values.xlsx index ca0347ea04d47ff6f3cb972af3af7a90f8caa546..079b4cd621b14c2fa32bdfb85856d8830426bab7 100644 GIT binary patch delta 10561 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 z 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 From 9bcacf0d84df49a059495c016a0917ec9ced1c0a Mon Sep 17 00:00:00 2001 From: devchima Date: Wed, 26 Feb 2025 08:36:38 -0500 Subject: [PATCH 4/8] Move xls fix into global xlsx reader so other importers can use it --- home/import_assessments.py | 16 +++++++-------- home/import_helpers.py | 19 +++++++++++++----- .../assessment_empty_values.xlsx | Bin 14775 -> 13893 bytes 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/home/import_assessments.py b/home/import_assessments.py index b7885146..1a3c0adf 100644 --- a/home/import_assessments.py +++ b/home/import_assessments.py @@ -115,18 +115,16 @@ def parse_file(self) -> list["AssessmentRow"]: row_iterator = helper_parse_file(self.file_content, self.file_type) rows = [row for _, row in row_iterator] - original_headers = list(rows[0].keys()) - headers_mapping = convert_headers_to_snake_case(original_headers, row_num=1) + original_headers = rows[0].keys() + headers_mapping = convert_headers_to_snake_case( + list(original_headers), row_num=1 + ) snake_case_headers = list(headers_mapping.values()) self.validate_headers(snake_case_headers, row_num=1) - - transformed_rows = [] - for _i, row in enumerate(rows, start=1): - transformed_row = { - headers_mapping.get(key, key): value for key, value in row.items() - } - transformed_rows.append(transformed_row) + transformed_rows = [ + {headers_mapping[key]: value for key, value in row.items()} for row in rows + ] return [ AssessmentRow.from_flat(row, i + 2) diff --git a/home/import_helpers.py b/home/import_helpers.py index 755ae393..600d0078 100644 --- a/home/import_helpers.py +++ b/home/import_helpers.py @@ -262,24 +262,33 @@ def read_csv(file_content: bytes) -> Iterator[dict[str, Any]]: return csv.DictReader(StringIO(file_content.decode())) +def remove_trailing_nones(row: list[Any]) -> list[Any]: + while row and row[-1] is None: + row = row[:-1] + return row + + +def clean_excel_cell(cell_value: str | float | datetime | None) -> str: + return "" if cell_value is None else str(cell_value).replace("_x000D", "").strip() + + def read_xlsx(file_content: bytes) -> Iterator[dict[str, Any]]: workbook = load_workbook(BytesIO(file_content), read_only=True, data_only=True) worksheet = get_active_sheet(workbook) - def clean_excel_cell(cell_value: str | float | datetime | None) -> str: - return str(cell_value).replace("_x000D", "").strip() - first_row = next(worksheet.iter_rows(max_row=1, values_only=True)) header = [clean_excel_cell(cell) if cell else None for cell in first_row] + header = remove_trailing_nones(header) for row in worksheet.iter_rows(min_row=2, values_only=True): + row = remove_trailing_nones(row) r = {} if len(row) > len(header): raise ImportException( "Invalid format. Please check that all row values have headers." ) - for name, cell in zip(header, row): # noqa: B905 - if name and cell: + for name, cell in zip(header, row, strict=False): + if name: r[name] = clean_excel_cell(cell) if r: yield r diff --git a/home/tests/import-export-data/assessment_empty_values.xlsx b/home/tests/import-export-data/assessment_empty_values.xlsx index 079b4cd621b14c2fa32bdfb85856d8830426bab7..6f4261dd98b8d14080674ce3ac9d0592c653b54d 100644 GIT binary patch delta 9863 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 aJ6xP>_wOD!xYNr_`xw&d=G|gDt^WX-$0)@B delta 10832 zcmc(F2UJtrx;3B(N>f1Mk*YwD7D0Lu1O$v2niPQmqVyJeCtE>OKtTzD5QhBHGkIl6tCb(mWM=M$ScGZl5M zXsy3=j>X99>mm7`QQvyWs_x9n6>+64!gcAT6uWf2l@f9A-CI^6`(8VCAg?J;?DZ;~$>r(yrk1dhK6?JL;{gSUn+-Qp zWRzem(OwcVDubuh&&EVim+4Ar`tKJO=vjzKbbGwczyT#~lz6QS@BU-o1 z8{`&!HuRhdusyS{)7JArNjCGg=ZYox(r4qt_416V^fPDfx^+=ZCs^!Yjo;9A1MzR# z)>#kR=s!!R@Sp^qUs|P0;4OGS7aJ8jH~xV9qU`G073tQntY$>2!H4;-QcyPLsqO#^}rK9=Gp?+LgeqGANQV;KeI9W>cPQseF6L9D4UAyZ!j$ zi?|3&Axq~Z6YjW|UvF6Rh(%#TzJBHGk|H=>xg=Sv^gfP06t>lDIef5bikJfYcek1* z`vUhMm1%gs^;=5_r`y2Ap#{4lQ^oNZs<*MHVVQn`tzbik%`}_F!(z)|ezB&UTFtMs z@4iWd;hsx)Ro*)|YEq`&L--M%9Evj-=kqz=r^0fws6-*eSkpf2JkwGoj~$=^2x*t?$;SzFuV2@qGMt=%vR1J}jV0yhiXUk!@ts)X(u; zd$3|LRX~}%>q#QpF@GjNeC_2Z?jG zo?tOe&&#Cr;6ORn$g2DDJZPQC?@3R6=y3~MZ|;|3L>ZelY}dlhTkS$+jjoxTnE;V6 zGS7RuS;aXs{gwUuv1eW|$)0Vt{SaoKHsg2D`|JyOrF})1+jMiw*o!EDjYjF%?Ubp+ zkoO@jd-lZ_Ua_d<~fnagjeCC@1u&=L}CqS44O99wg{yi=x2ZThq9Rl7B~(Ji z#=H&z`9ZJx9GZnwC|#3n($VQhrP~zLj(Q?YoC_DIOVbYK@rWXWlVE1jK}{C^sa2nn)~uybPtw;(2NG z3BROtpOC9vwfP+G(Eoulgo8otDo1uz=M;LR{?nLzhfB+e46|Ek1zSxUhWb;soEkvfQgno80RIN`qrt3nKEua+g$9j0&jOtjVNu&y3^s zlAuxiDJ!ziTs2yg=Gi0^{g?c^d>g)B6;*uwvQGnEQMy7)*vlI4ZTC4zlvsPIEqua; z{qp42WC$Clx%`J06TtwD400}H*kgo<^ZtMWDQ(K-F$c^sv>n?Fxt^qb7k z(TTfa&z4tkQdp&=j$<@T)ZxK|sey2+`O~frL8_pbM2iaPlidv~4Jxl8^mi+K1a6_{ zN6x%$I(*cTb>XuZuaV@jXVX(L8W&BWNye=U`xMn}cW-G1iON(1KGdHl$(}X2%XE7U zoI%;W*k@hYl4|H5a}nYZJolUawvLvG@EXs`x%6kpb9sZu-kSknhs1|*Nyn}I0#;7H zo+TIQ&ZL+?FE7WBRMKr1Z0{)^Z2{e5ZXxZ*$jH7i{C*2CHYWS!I!#7a%tA*;d9)Ys zGF}Eu5rZPkfg=S^hYcxCK4ro3==WyL)hnbucZz)Vp3c=ZfP3ggp?Qr1pGZeq))^kD zY2;RtJ0ga`G!GSAqWO^jhC=+Wz4mC2LJMc9Hd>n#CJ0ynkAQu zuzJn3;rwjm^IOrEzBt5=ZOmm3MDwtTe90R5;uAk&J#YyRrRb61cz?QE#Qba;$1FbU zG6hv7YF`FlrwK;9dA6qhT*85n&WjqQ)sM=vQie|4S1%NN%AoElqUOdaEA&)V(DD{! z2T(vgJ)W`=26K+?V-x=tH0=02%J;R!jMAs(z*@9m-L<&B4uN2|xgbYnHOEr&OnC^E zl>?REG9j>a!5~hr<#}d!gO4O)@8nuX$E>3~op#Qnf*GM?;+a=^L(SdWxWz39kMs?b zmUwXv6*@@&{)LUAHGZ)V6dDe^kJPkfN&y4oZSK6&FQ>$1$(`b*u14X4Oe+7LvM7d zwBRzkar|QXbn^3$2rZYsHwWp)&9f{YA9dP)8Af+E*PbusgjvapWpC<|?U5N|yzLP{hCSdy)auD8ZiiIy9bDW81P z3n&_wc7MhAD@e!sUr1ikXJ7m%J1|3$ep2a-EuK0nhaxYgck(H*){UPQ>>o>;0~oUw`I^- zAMk6Na++tYFP>_?3}Sd`?J%!!&4pItQU`ua9J-R+AFRJL_0SCKA~4Hv!r8ced=xJy zb8e^%HmHN3BWkTQ?s;}bp4Y(Tg&h-cujR*l47lIIW*($X<1&16qP{tD{OlQ*R*zD; zU4Es;996_`@0`~p+>so3z*bmEo?ZDf-BQWPY)v?`+MC9Q?OnSw+g36vR%%7Aw~D0E zLQSvnirUHwl^Olyfi^U91A(uu%%kZGD@%uvfyaoAFHfAdzZ^)Xz5_qlRUlkG^8B94 zFj1GBj4X`g`!AmB|F<0h<-x)Q@aJ+xpKyxzQXZsdAIxiJ1YIF$K*O4A%*p7aCs6x? zevUPkSM6W1f26X51!t&+UJ)5SW#>h=V?VOS+pKJ+`kP+eY-uOL|OVgYsalf*AW;k_O^@M!+FV~6K!r3_~|kIWHq zr`y>kZH)0GgO1Fh{@Z^p6dKfb^q4_5znJ%5SaA~ zxMTQA@dL**@a{Z2GH(A1M|Vq0r>ehv)s_cNlVu)ez35Xo;|w4rD&j_#Hru~H*<@`y zVP1jp^H(G~ulVdYLI2!=JRUn1=JYpq#ivd5q(GWTOZR74HF%u1V zvW|Elmg;TgjRQ<^69*{uoK_%t(KO<7xYwqe>_QvCO(Y3}a|o|}lG(lDQ6{y!HMVj9 zC2Hv>CM<9&_o}qgM zccOmN?YrHFJNUY}tYNdmVcZHSe$%RNWTkMXR12fl(2CEtGm!|1aWMDT^{=cUI>}Zk z)SP=(X``y|x!hipci@Ng+}3M9VV;?65NWkGx7xjGA-nJIYllUY*2qUfD~avfFz=!k z8h>*sMO~!I#sPlxp6Jf7Q`O#aU_8{p%|cj z(3HCLbvozJH0i*{1rRge?6>X?*IHXzL@YVrlnhhH3KN-I^6kwS4vg3d8@5F|huh=x zMZqyug}(k%T%QSR+gRRtSW|^w7l+>ZnnpYfdi#=*Ar*LUFUsq77t76x;87$}6_Yh{ zv%QzoXKhVm2L?44fKurl?nPPLz7ieL#aYhop*0-+%rE&RP{JSAYy*{(*2s2NSJFR- zUPyU3<9rZ(;zc^{L-&yDwRGRYRHpPHNQy3N@8%n`KzA89!}bQTvi9Eh$xg=|D@57( zj`^;6`SP4HS{6h0<6f-uy_kXG>f2rp3;Ui3e

3nl;Z3MSQZip`v0I2RqUXKVsc* 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 l5s@Tww5a|OWcC}X=RZNeK7w< Date: Wed, 26 Feb 2025 09:05:57 -0500 Subject: [PATCH 5/8] Experiencing a type error only in remote but not local so trying this to see if it fixes it. --- home/import_helpers.py | 1 + 1 file changed, 1 insertion(+) diff --git a/home/import_helpers.py b/home/import_helpers.py index 600d0078..1bd1d10b 100644 --- a/home/import_helpers.py +++ b/home/import_helpers.py @@ -281,6 +281,7 @@ def read_xlsx(file_content: bytes) -> Iterator[dict[str, Any]]: header = remove_trailing_nones(header) for row in worksheet.iter_rows(min_row=2, values_only=True): + row = list(row) row = remove_trailing_nones(row) r = {} if len(row) > len(header): From 6cd5eec21e6f8f7c166c8c2a518284216cfe2da5 Mon Sep 17 00:00:00 2001 From: devchima Date: Wed, 26 Feb 2025 09:23:34 -0500 Subject: [PATCH 6/8] Another attemtpt to fix mypy error in remote env --- home/import_helpers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/home/import_helpers.py b/home/import_helpers.py index 1bd1d10b..6fd0ae7f 100644 --- a/home/import_helpers.py +++ b/home/import_helpers.py @@ -276,7 +276,7 @@ def read_xlsx(file_content: bytes) -> Iterator[dict[str, Any]]: workbook = load_workbook(BytesIO(file_content), read_only=True, data_only=True) worksheet = get_active_sheet(workbook) - first_row = next(worksheet.iter_rows(max_row=1, values_only=True)) + first_row = list(next(worksheet.iter_rows(max_row=1, values_only=True))) header = [clean_excel_cell(cell) if cell else None for cell in first_row] header = remove_trailing_nones(header) From 29ee864e4335e986fe695a2dfd12db69c5fc6dd3 Mon Sep 17 00:00:00 2001 From: devchima Date: Thu, 27 Feb 2025 03:26:25 -0500 Subject: [PATCH 7/8] type ignore since there's no way to convince mypy that the lists/tuples are valid --- home/import_helpers.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/home/import_helpers.py b/home/import_helpers.py index 6fd0ae7f..aaab9fde 100644 --- a/home/import_helpers.py +++ b/home/import_helpers.py @@ -276,13 +276,12 @@ def read_xlsx(file_content: bytes) -> Iterator[dict[str, Any]]: workbook = load_workbook(BytesIO(file_content), read_only=True, data_only=True) worksheet = get_active_sheet(workbook) - first_row = list(next(worksheet.iter_rows(max_row=1, values_only=True))) + first_row = next(worksheet.iter_rows(max_row=1, values_only=True)) header = [clean_excel_cell(cell) if cell else None for cell in first_row] header = remove_trailing_nones(header) for row in worksheet.iter_rows(min_row=2, values_only=True): - row = list(row) - row = remove_trailing_nones(row) + row = remove_trailing_nones(row) # type: ignore r = {} if len(row) > len(header): raise ImportException( From df5917989f888a82cdd39545d1dad07083414a6c Mon Sep 17 00:00:00 2001 From: devchima Date: Thu, 27 Feb 2025 04:03:31 -0500 Subject: [PATCH 8/8] Why type ignore (mypy) --- home/import_helpers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/home/import_helpers.py b/home/import_helpers.py index aaab9fde..0afcf73a 100644 --- a/home/import_helpers.py +++ b/home/import_helpers.py @@ -281,7 +281,7 @@ def read_xlsx(file_content: bytes) -> Iterator[dict[str, Any]]: header = remove_trailing_nones(header) for row in worksheet.iter_rows(min_row=2, values_only=True): - row = remove_trailing_nones(row) # type: ignore + row = remove_trailing_nones(row) # type: ignore # Mypy cannot guarantee row is a list; rows may be tuples so we bypass. r = {} if len(row) > len(header): raise ImportException(