This module provides a unified interface for loading evaluation data from organizational repositories (IOM, UNHCR, etc.) and transforming it into standardized JSON format.
Components:
EvalReader: Base interface for all repository readers
Title EVALUATION OF IOM’S MIGRATION DATA STRATEGY
Year 2025
Author IOM CENTRAL EVALUATION
Best Practicesor Lessons Learnt Yes
Date of Publication 2025-08-11
Donor IOM
Evaluation Brief Yes
Evaluation Commissioner IOM
Evaluation Coverage Global
Evaluation Period From Date 2025-08-20
Evaluation Period To Date 2025-05-31
Executive Summary Yes
External Version of the Report No
Languages English
Migration Thematic Areas Organisational policy/strategy
Name of Project(s) Being Evaluated NaN
Number of Pages Excluding annexes 44.0
Other Documents Included NaN
Project Code NaN
Countries Covered Worldwide
Regions Covered HQ Geneva
Relevant Crosscutting Themes NaN
Report Published Yes
Terms of Reference Yes
Type of Evaluation Scope Strategy
Type of Evaluation Timing Not applicable
Type of Evaluator External
Level of Evaluation Centralized
Document Subtype Evaluation report, Evaluation brief, Annexes, ...
File URL https://evaluation.iom.int/sites/g/files/tmzbd...
File description Evaluation Report, Evaluation Brief, Annex VI ...
Management response No
Date added Thu, 08/07/2025 - 23:52
Name: 0, dtype: object
df = reader.read()len(df)
740
dstrat = df.iloc[0]dstrat
Title EVALUATION OF IOM’S MIGRATION DATA STRATEGY
Year 2025
Author IOM CENTRAL EVALUATION
Best Practicesor Lessons Learnt Yes
Date of Publication 2025-08-11
Donor IOM
Evaluation Brief Yes
Evaluation Commissioner IOM
Evaluation Coverage Global
Evaluation Period From Date 2025-08-20
Evaluation Period To Date 2025-05-31
Executive Summary Yes
External Version of the Report No
Languages English
Migration Thematic Areas Organisational policy/strategy
Name of Project(s) Being Evaluated NaN
Number of Pages Excluding annexes 44.0
Other Documents Included NaN
Project Code NaN
Countries Covered Worldwide
Regions Covered HQ Geneva
Relevant Crosscutting Themes NaN
Report Published Yes
Terms of Reference Yes
Type of Evaluation Scope Strategy
Type of Evaluation Timing Not applicable
Type of Evaluator External
Level of Evaluation Centralized
Document Subtype Evaluation report, Evaluation brief, Annexes, ...
File URL https://evaluation.iom.int/sites/g/files/tmzbd...
File description Evaluation Report, Evaluation Brief, Annex VI ...
Management response No
Date added Thu, 08/07/2025 - 23:52
Name: 0, dtype: object
dstrat['Document Subtype']
'Evaluation report, Evaluation brief, Annexes, Annexes, Annexes, Special related reports/documents'
'Evaluation Report, Evaluation Brief, Annex VI Case Study - RDH East, Horn and Southern Africa, Annex VII Case Study - RDH Asia-Pacific, Annex VIII - Inception Report, Infographics'
Each evaluation needs a unique identifier. Since the CSV doesn’t include one, we generate an MD5 hash from key fields:
Exported source
@patchdef _mk_id(self:IOMRepoReader, row # DataFrame row containing evaluation metadata ): id_str =''.join(str(row[f]) for f inself.cfg['id_gen']['fields'])return hashlib.md5(id_str.encode('utf-8')).hexdigest()
IOM evaluations can have multiple associated documents (reports, briefs, annexes). The CSV stores these as comma-separated values in three parallel fields. We parse and combine them into structured document records:
Document Handling
Exported source
@patchdef _mk_docs(self:IOMRepoReader, row # DataFrame row with document fields ):"Parse document fields into structured records" stypes = [s.strip() for s instr(row['Document Subtype']).split(', ')] urls = [u.strip() for u instr(row['File URL']).split(', ')] descs = [d.strip() for d instr(row['File description']).split(', ')]return [dict(subtype=st, url=u, desc=d) for st,u,d inzip(stypes,urls,descs) if u.strip()]
test_eq(df_proc['Date of Publication'].dtype, 'string')test_eq(df_proc['Evaluation Period From Date'].dtype, 'string')test_eq(df_proc['Evaluation Period To Date'].dtype, 'string')df_proc['Date of Publication'].iloc[0]
'2025-08-11'
Exported source
@patchdef _proc_lists(self:IOMRepoReader, df):for fname,fcfg inself.cfg['list_fields'].items(): vals = df[fname].fillna('').astype(str).str.split(fcfg['separator']) df[fname] = vals.apply(lambda x: [item.strip() for item in x if item.strip()])return df
@patchdef _to_dict(self:IOMRepoReader, row):"Convert row to evaluation dict" meta_cols = [col for col in row.index if col notin ['id', 'docs']]returndict(id=row['id'], docs=row['docs'], meta={f:row[f] for f in meta_cols})
Exported source
@patchdef _to_eval(self:IOMRepoReader, row):"Convert row to Evaluation object" meta_cols = [col for col in row.index if col notin ['id', 'docs']]return Evaluation(id=row['id'], docs=row['docs'], meta={f:row[f] for f in meta_cols})
Exported source
@patchdef tfm(self:IOMRepoReader, df:pd.DataFrame):"Transform raw dataframe to evaluation objects" df_proc =self._proc_lists(self._proc_dates(df.copy())) df_proc['id'] = df_proc.apply(self._mk_id, axis=1) df_proc['docs'] = df_proc.apply(self._mk_docs, axis=1)return [self._to_eval(row) for _,row in df_proc.iterrows()]
def in_docs( ev:Evaluation, # Evaluation object url:str, # URL of an evaluation report):
Check if a URL is in the documents of an evaluation
Exported source
def in_docs( ev:Evaluation, # Evaluation object url:str# URL of an evaluation report ):"Check if a URL is in the documents of an evaluation"returnany(L(ev.docs).filter(lambda x: x['url'] == url))
def find_eval( evals:list, # List of evaluations query:str, # Title or URL of evaluation by:str='title', # 'title', 'url' or 'id'):
Find evaluation by title, URL or id
title ='Evaluation of IOM Accountability to Affected Populations'url ="https://evaluation.iom.int/sites/g/files/tmzbdl151/files/docs/resources/AAP%20Evaluation%20Report_final_.pdf"test_eq(find_eval(evals, title, by='title').id, '6c3c2cf3fa479112967612b0baddab72')test_eq(find_eval(evals, url, by='url').id, '6c3c2cf3fa479112967612b0baddab72')test_eq(find_eval(evals, 'Nonexistent Title', by='title'), None)test_eq(find_eval(evals, 'https://fake.url/nowhere.pdf', by='url'), None)test_eq(find_eval(evals, '6c3c2cf3fa479112967612b0baddab72', by='id').meta['Title'], 'Evaluation of IOM Accountability to Affected Populations')
find_eval(evals, title, by='title')
Evaluation of IOM Accountability to Affected Populations
Year: 2025 | Organization: IOM | Countries: Worldwide
Documents: 4 available ID:6c3c2cf3fa479112967612b0baddab72