11from typing import Any , TypedDict , cast
22
3- from constance import config
3+ from constance import config as constance_config
44from django .core .cache import cache
55
66from country_workspace .contrib .kobo .api .client .main import Client
77from country_workspace .contrib .kobo .api .data .asset import Asset
88from country_workspace .contrib .kobo .api .data .submission import Submission
99from country_workspace .contrib .kobo .models import KoboSubmission
1010from country_workspace .models import AsyncJob , Batch , Household , Individual
11- from country_workspace .utils .fields import clean_field_name
11+ from country_workspace .utils .config import BatchNameConfig , FailIfAlienConfig
12+ from country_workspace .utils .fields import clean_field_names
13+
14+
15+ class Config (BatchNameConfig , FailIfAlienConfig ):
16+ project_id : str
17+ individual_records_field : str
1218
1319
1420def make_client (country_code : str | None ) -> Client :
15- token = config .KOBO_MASTER_API_TOKEN or config .KOBO_API_TOKEN
16- project_view_id = config .KOBO_PROJECT_VIEW_ID if config .KOBO_MASTER_API_TOKEN else None
21+ token = constance_config .KOBO_MASTER_API_TOKEN or constance_config .KOBO_API_TOKEN
22+ project_view_id = constance_config .KOBO_PROJECT_VIEW_ID if constance_config .KOBO_MASTER_API_TOKEN else None
1723 return Client (
18- base_url = config .KOBO_KF_URL ,
24+ base_url = constance_config .KOBO_KF_URL ,
1925 token = token ,
2026 country_code = country_code ,
2127 project_view_id = project_view_id ,
@@ -26,31 +32,32 @@ def extract_household_data(submission: Submission, individual_records_field: str
2632 return {key : value for key , value in submission .items () if key != individual_records_field }
2733
2834
29- def create_individuals (
30- batch : Batch , household : Household , submission : Submission , individual_records_field : str
31- ) -> int :
35+ def create_individuals (batch : Batch , household : Household , submission : Submission , config : Config ) -> int :
3236 individuals = []
33- for raw_individual in submission .get (individual_records_field , []):
34- individual = {key .lstrip (f"{ individual_records_field } /" ): value for key , value in raw_individual .items ()}
37+ for raw_individual in submission .get (config ["individual_records_field" ], []):
38+ individual = {
39+ key .replace (f"{ config ['individual_records_field' ]} /" , "" ): value for key , value in raw_individual .items ()
40+ }
3541 fullname = next ((key for key in individual if key .startswith ("full_name" )), None )
3642 individuals .append (
3743 Individual (
3844 batch = batch ,
3945 household = household ,
4046 name = individual .get (fullname , "" ),
41- flex_fields = { clean_field_name ( key ): value for key , value in individual . items ()} ,
47+ flex_fields = clean_field_names ( individual ) ,
4248 ),
4349 )
4450 household .program .individuals .bulk_create (individuals )
4551 return len (individuals )
4652
4753
48- def create_household (batch : Batch , submission : Submission , individual_records_field : str ) -> Household :
49- household_fields = extract_household_data (submission , individual_records_field )
54+ def create_household (batch : Batch , submission : Submission , config : Config ) -> Household :
55+ household_fields = extract_household_data (submission , config [ " individual_records_field" ] )
5056 return cast (
5157 Household ,
5258 batch .program .households .create (
53- batch = batch , flex_fields = {clean_field_name (key ): value for key , value in household_fields .items ()}
59+ batch = batch ,
60+ flex_fields = clean_field_names (household_fields ),
5461 ),
5562 )
5663
@@ -63,7 +70,7 @@ class ImportResult(TypedDict):
6370 individuals : int
6471
6572
66- def import_asset (batch : Batch , asset : Asset , individual_records_field : str ) -> ImportResult :
73+ def import_asset (batch : Batch , asset : Asset , config : Config ) -> ImportResult :
6774 household_counter = 0
6875 individual_counter = 0
6976
@@ -72,31 +79,32 @@ def import_asset(batch: Batch, asset: Asset, individual_records_field: str) -> I
7279 for submission in asset .submissions :
7380 if submission .id in submission_ids :
7481 continue
75- household = create_household (batch , submission , individual_records_field )
82+ household = create_household (batch , submission , config )
7683 household_counter += 1
77- individual_counter += create_individuals (batch , household , submission , individual_records_field )
84+ individual_counter += create_individuals (batch , household , submission , config )
7885
7986 return ImportResult (households = household_counter , individuals = individual_counter )
8087
8188
8289def import_data (job : AsyncJob ) -> ImportResult :
90+ config : Config = job .config
91+
8392 batch = Batch .objects .create (
84- name = job . config ["batch_name" ],
93+ name = config ["batch_name" ],
8594 program = job .program ,
8695 country_office = job .program .country_office ,
8796 imported_by = job .owner ,
8897 source = Batch .BatchSource .KOBO ,
8998 )
90- individual_records_field = job .config ["individual_records_field" ]
9199 client = make_client (job .program .country_office .kobo_country_code )
92100
93101 household_counter = 0
94102 individual_counter = 0
95103
96104 for asset in client .assets :
97105 # TODO: fetch specific asset
98- if job . config ["project_id" ] == asset .uid :
99- import_result = import_asset (batch , asset , individual_records_field )
106+ if config ["project_id" ] == asset .uid :
107+ import_result = import_asset (batch , asset , config )
100108 household_counter += import_result ["households" ]
101109 individual_counter += import_result ["individuals" ]
102110
0 commit comments