def sample_hello_world(): farmbeats_endpoint = os.environ['FARMBEATS_ENDPOINT'] credential = DefaultAzureCredential() client = FarmBeatsClient(endpoint=farmbeats_endpoint, credential=credential) farmer_id = "contoso-farmer" farmer_name = "Contoso" farmer_description = "Contoso is hard working." print("Creating farmer, or updating if farmer already exists...", end=" ", flush=True) farmer = client.farmers.create_or_update( farmer_id=farmer_id, farmer=Farmer(name=farmer_name, description=farmer_description)) print("Done") print("Here are the details of the farmer:") print(f"\tID: {farmer.id}") print(f"\tName: {farmer.name}") print(f"\tDescription: {farmer.description}") print(f"\tCreated timestamp: {farmer.created_date_time}") print(f"\tLast modified timestamp: {farmer.modified_date_time}")
def test_satellite_flow(self, agrifood_endpoint): # Setup data common_id_prefix = "satellite-flow-" farmer_id = common_id_prefix + "test-farmer" boundary_id = common_id_prefix + "test-boundary" job_id_prefix = common_id_prefix + "job" job_id = self.generate_random_name(job_id_prefix) start_date_time = datetime(2020, 1, 1, tzinfo=Utc()) end_date_time = datetime(2020, 1, 31, tzinfo=Utc()) # Setup client client = self.create_client(agrifood_endpoint=agrifood_endpoint) # Create farmer farmer = client.farmers.create_or_update(farmer_id=farmer_id, farmer=Farmer()) # Create boundary if not exists self.create_boundary_if_not_exist(client, farmer_id, boundary_id) # Create satellite job satellite_job_poller = client.scenes.begin_create_satellite_data_ingestion_job( job_id=job_id, job=SatelliteDataIngestionJob( farmer_id=farmer_id, boundary_id=boundary_id, start_date_time=start_date_time, end_date_time=end_date_time, data=SatelliteData(image_names=["LAI"])), ) # Get terminal job state and assert satellite_job = satellite_job_poller.result() assert satellite_job.farmer_id == farmer_id assert satellite_job.id == job_id assert satellite_job.boundary_id == boundary_id assert satellite_job.start_date_time == start_date_time assert satellite_job.end_date_time == end_date_time assert satellite_job.status == "Succeeded" # Get corresponding scenes scenes = client.scenes.list( farmer_id=farmer_id, boundary_id=boundary_id, start_date_time=start_date_time, end_date_time=end_date_time, ) scenes_list = list(scenes) # Assert scenes got created assert len(scenes_list) > 0 for scene in scenes_list: assert scene.farmer_id == farmer_id assert scene.boundary_id == boundary_id
def test_boundary(self, agrifood_endpoint): client = self.create_client(agrifood_endpoint=agrifood_endpoint) farmer_id = "smoke-test-boundary-farmer" boundary_id = "smoke-test-boundary" farmer = client.farmers.create_or_update(farmer_id=farmer_id, farmer=Farmer()) boundary = self.create_boundary_if_not_exist(client, farmer_id, boundary_id) assert boundary == client.boundaries.get(farmer_id=farmer_id, boundary_id=boundary_id) self.delete_boundary(client, farmer_id, boundary_id) client.farmers.delete(farmer_id=farmer_id)
async def test_boundary(self, agrifood_endpoint): client = self.create_client(agrifood_endpoint=agrifood_endpoint) boundary_id = "async-test-boundary" farmer_id = boundary_id + "-farmer" farmer = await client.farmers.create_or_update(farmer_id=farmer_id, body=Farmer()) boundary = await self.create_boundary_if_not_exist( client, farmer_id, boundary_id) assert boundary == await client.boundaries.get(farmer_id=farmer_id, boundary_id=boundary_id) await self.delete_boundary(client, farmer_id, boundary_id) await client.farmers.delete(farmer_id=farmer_id)
def test_farmer(self, farmbeats_endpoint, farmbeats_farmer_id): client = self.create_client(farmbeats_endpoint=farmbeats_endpoint) farmer = client.farmers.create_or_update(farmer_id=farmbeats_farmer_id, body=Farmer()) assert farmer.id == farmbeats_farmer_id assert farmer.e_tag assert farmer.created_date_time assert farmer.modified_date_time retrieved_farmer = client.farmers.get(farmer_id=farmbeats_farmer_id) assert farmer.id == retrieved_farmer.id assert farmer.e_tag == retrieved_farmer.e_tag assert farmer.created_date_time == retrieved_farmer.created_date_time assert farmer.modified_date_time == retrieved_farmer.modified_date_time
async def test_farmer(self, agrifood_endpoint): client = self.create_client(agrifood_endpoint=agrifood_endpoint) farmer_id = "async-test-farmer" farmer = await client.farmers.create_or_update(farmer_id=farmer_id, body=Farmer()) assert farmer.id == farmer_id assert farmer.e_tag assert farmer.created_date_time assert farmer.modified_date_time retrieved_farmer = await client.farmers.get(farmer_id=farmer_id) assert farmer.id == retrieved_farmer.id assert farmer.e_tag == retrieved_farmer.e_tag assert farmer.created_date_time == retrieved_farmer.created_date_time assert farmer.modified_date_time == retrieved_farmer.modified_date_time await client.farmers.delete(farmer_id=farmer_id)
def test_farmer(self, agrifood_endpoint): client = self.create_client(agrifood_endpoint=agrifood_endpoint) farmer_id = self.generate_random_name("smoke-test-farmer") farmer = client.farmers.create_or_update( farmer_id=farmer_id, farmer=Farmer() ) assert farmer.id == farmer_id assert farmer.e_tag assert farmer.created_date_time assert farmer.modified_date_time retrieved_farmer = client.farmers.get(farmer_id=farmer_id) assert farmer.id == retrieved_farmer.id assert farmer.e_tag == retrieved_farmer.e_tag assert farmer.created_date_time == retrieved_farmer.created_date_time assert farmer.modified_date_time == retrieved_farmer.modified_date_time client.farmers.delete(farmer_id=farmer_id)
def sample_farm_hierarchy(): farmbeats_endpoint = os.environ['FARMBEATS_ENDPOINT'] credential = DefaultAzureCredential() client = FarmBeatsClient( endpoint=farmbeats_endpoint, credential=credential ) farmer_id = "contoso-farmer" farmer_name = "contoso-farmer-name" farmer_description = "contoso-farmer-description" farm_id = "contoso-farm" farm_name = "contoso-farm-name" farm_description = "contoso-farm-description" field_id = "contoso-field" field_name = "contoso-field-name" field_description = "contoso-field-description" boundary_id = "contoso-boundary" boundary_name = "contoso-boundary-name" boundary_description = "contoso-boundary-description" multi_polygon = MultiPolygon( coordinates=[ [ [ [-94.05807495, 44.75916947], [-94.05802487, 44.7592142], [-94.05798752, 44.75921875], [-94.05692697, 44.75883808], [-94.05697525, 44.75861334], [-94.05542493, 44.75844192], [-94.05537128, 44.75891045], [-94.05443251, 44.75884951], [-94.05086517, 44.75856001], [-94.05093491, 44.75533736], [-94.05389607, 44.75516594], [-94.05421793, 44.75520023], [-94.05447543, 44.75534879], [-94.05746988, 44.75751702], [-94.05795157, 44.75824385], [-94.05805349, 44.75863619], [-94.05807495, 44.75916947] ] ], [ [ [-94.05802667, 44.75929136], [-94.05793598, 44.7607673], [-94.05693233, 44.76072738], [-94.05694842, 44.76008746], [-94.05727246, 44.75988264], [-94.05752903, 44.75946416], [-94.05760288, 44.75923042], [-94.05802667, 44.75929136] ] ] ] ) # Step 1: Create a farmer. print( f"Creating or updating farmer with Id {farmer_id}...", end=" ", flush=True) farmer = client.farmers.create_or_update( farmer_id=farmer_id, farmer=Farmer( name=farmer_name, description=farmer_description ) ) print("Done") print("Details of farmer:") print("\tID:", farmer.id) print("\tName:", farmer.name) print("\tDescription:", farmer.description) # Step 2: Create a farm. print( f"Creating or updating farm with Id {farm_id}...", end=" ", flush=True) farm = client.farms.create_or_update( farmer_id=farmer_id, farm_id= farm_id, farm=Farm( name=farm_name, description=farm_description ) ) print("Done") print("Details of farm:") print("\tID:", farm.id) print("\tName:", farm.name) print("\tFarmer Name:", farm.farmer_id) print("\tDescription:", farm.description) # Step 3: Create a field. print( f"Creating or updating field with Id {field_id}...", end=" ", flush=True) field = client.fields.create_or_update( farmer_id=farmer_id, field_id= field_id, field=Field( name=field_name, farm_id=farm_id, description=field_description ) ) print("Done") print("Details of field:") print("\tID:", field.id) print("\tName:", field.name) print("\tFarmer Name:", field.farmer_id) print("\tFarm Name:", field.farm_id) print("\tName:", field.name) print("\tDescription:", field.description) # Step 4: Create a boundary. try: print( f"Trying to fetch boundary with id {boundary_id}...", end=" ", flush=True) boundary = client.boundaries.get( farmer_id=farmer_id, boundary_id=boundary_id ) print("Boundary already exists.") except ResourceNotFoundError: print( f"Doesn't exist. Creating boundary...", end=" ", flush=True) boundary = client.boundaries.create_or_update( farmer_id=farmer_id, boundary_id=boundary_id, boundary=Boundary( name=boundary_name, geometry=multi_polygon, description=boundary_description ) ) print("Done") print("Details of boundary:") print("\tID:", boundary.id) print("\tName:", boundary.name) print("\tDescription:", boundary.description)
def sample_satellite_download(): farmbeats_endpoint = os.environ['FARMBEATS_ENDPOINT'] credential = DefaultAzureCredential() client = FarmBeatsClient(endpoint=farmbeats_endpoint, credential=credential) farmer_id = "contoso-farmer" boundary_id = "contoso-boundary" job_id_prefix = "contoso-job" start_date_time = datetime(2020, 1, 1, tzinfo=UTC) end_date_time = datetime(2020, 1, 31, tzinfo=UTC) data_root_dir = "./data/satellite/" # Create or update a farmer within FarmBeats. print(f"Ensure farmer with id {farmer_id} exists... ", end="", flush=True) farmer = client.farmers.create_or_update(farmer_id=farmer_id, farmer=Farmer()) print("Done") # Create a boundary if the boundary does not exist. try: print(f"Checking if boundary with id {boundary_id} exists... ", end="", flush=True) boundary = client.boundaries.get(farmer_id=farmer_id, boundary_id=boundary_id) print("Exists") except ResourceNotFoundError as e: print("Boundary doesn't exist. Creating... ", end="", flush=True) # Creating a boundary. boundary = client.boundaries.create_or_update( farmer_id=farmer_id, boundary_id=boundary_id, boundary=Boundary(geometry=Polygon( coordinates=[[[79.27057921886444, 18.042507660177698], [79.26899135112762, 18.040135849620704], [79.27113711833954, 18.03927382882835], [79.27248358726501, 18.041069275656195], [79.27057921886444, 18.042507660177698]]]))) print("Created") # Queue a satellite job and wait for completion. job_id = f"{job_id_prefix}-{randint(0, 1000)}" print(f"Queuing satellite job {job_id}... ", end="", flush=True) satellite_job_poller = client.scenes.begin_create_satellite_data_ingestion_job( job_id=job_id, job=SatelliteDataIngestionJob(farmer_id=farmer_id, boundary_id=boundary_id, start_date_time=start_date_time, end_date_time=end_date_time, data=SatelliteData(image_names=["LAI"]))) print("Queued. Waiting for completion... ", end="", flush=True) satellite_job_poller.result() print(f"Job completed with status {satellite_job_poller.status()}") # Get scenes which are available in FarmBeats for our farmer and boundary of intrest. print("Getting scenes list... ", end="", flush=True) scenes = client.scenes.list( boundary.farmer_id, boundary.id, start_date_time=start_date_time, end_date_time=end_date_time, ) print("Done") for scene in scenes: safe_datetime_str = scene.scene_date_time.strftime("%Y-%m-%d %H-%M-%S") scene_out_path = Path(data_root_dir, scene.provider, scene.source, safe_datetime_str) for image_file in scene.image_files: band_out_path = Path( scene_out_path, f"{image_file.name}-{int(image_file.resolution)}.tif") download_image(client, image_file.file_link, band_out_path) print("Downloads done")
async def test_satellite_flow(self, agrifood_endpoint): # not running in playback for now because the binary body is not being scrubbed properly # Setup data common_id_prefix = "satellite-flow-async-" farmer_id_prefix = common_id_prefix + "test-farmer" boundary_id_prefix = common_id_prefix + "test-boundary" job_id_prefix = common_id_prefix + "job" job_id = self.generate_random_name(job_id_prefix) farmer_id = self.generate_random_name(farmer_id_prefix) boundary_id = self.generate_random_name(boundary_id_prefix) start_date_time = datetime.datetime(2020, 1, 1, tzinfo=Utc()) end_date_time = datetime.datetime(2020, 12, 31, tzinfo=Utc()) # Setup client client = self.create_client(agrifood_endpoint=agrifood_endpoint) # Create farmer farmer = await client.farmers.create_or_update(farmer_id=farmer_id, farmer=Farmer()) # Create boundary if not exists boundary = await self.create_boundary_if_not_exist( client, farmer_id, boundary_id) # Create satellite job satellite_job_poller = await client.scenes.begin_create_satellite_data_ingestion_job( job_id=job_id, job=SatelliteDataIngestionJob( farmer_id=farmer_id, boundary_id=boundary_id, start_date_time=start_date_time, end_date_time=end_date_time, data=SatelliteData(image_names=["LAI"])), ) # Get terminal job state and assert satellite_job = await satellite_job_poller.result() assert satellite_job.farmer_id == farmer_id # in async, we're getting binary form of body, so can't scrub job id from binary assert job_id in satellite_job.id assert satellite_job.boundary_id == boundary_id assert satellite_job.start_date_time == start_date_time assert satellite_job.end_date_time == end_date_time assert satellite_job.status == "Succeeded" # Get corresponding scenes scenes = client.scenes.list( farmer_id=farmer_id, boundary_id=boundary_id, start_date_time=start_date_time, end_date_time=end_date_time, ) scenes_list = [scene async for scene in scenes] # Assert scenes got created assert len(scenes_list) > 0 for scene in scenes_list: assert scene.farmer_id == farmer_id assert scene.boundary_id == boundary_id
async def sample_attachments_async(): farmbeats_endpoint = os.environ['FARMBEATS_ENDPOINT'] credential = DefaultAzureCredential() client = FarmBeatsClient(endpoint=farmbeats_endpoint, credential=credential) farmer_id = "contoso-farmer" farm_id = "contoso-farm" attachment_on_farmer_id = "contoso-farmer-attachment-1" attachment_on_farm_id = "contoso-farm-attachment-1" attachment_on_farmer_file_path = "../test.txt" attachment_on_farm_file_path = "../test.txt" if not (os.path.isfile(attachment_on_farmer_file_path) and os.path.isfile(attachment_on_farm_file_path)): raise SystemExit( "Please provide the paths to the files you want to upload.") # Ensure farmer exists, create if necessary. print(f"Create/updating farmer with id {farmer_id}...", end=" ", flush=True) await client.farmers.create_or_update(farmer_id=farmer_id, farmer=Farmer()) print("Done!") # Ensure farm exists, create if necessary. print(f"Create/updating farm with id {farm_id}...", end=" ", flush=True) await client.farms.create_or_update(farmer_id=farmer_id, farm_id=farm_id, farm=Farmer()) print("Done!") # Create attachment on farmer try: print( f"Checking if attachment with id {attachment_on_farmer_id} already exists " f"on farmer with id {farmer_id}...", end=" ", flush=True) await client.attachments.get(farmer_id=farmer_id, attachment_id=attachment_on_farmer_id) print("Attachment already exists. Not updating file.") except ResourceNotFoundError: print("Attachment doesn't exist") print("Creating attachment...", end=" ", flush=True) # Open file with buffering set to 0, to get a IO object. file_to_attach_on_farmer = open(attachment_on_farmer_file_path, "rb", buffering=0) await client.attachments.create_or_update( farmer_id=farmer_id, attachment_id=attachment_on_farmer_id, resource_id=farmer_id, resource_type="Farmer", file=file_to_attach_on_farmer) print("Done!") # Create attachment with farm try: print( f"Checking if attachment with id {attachment_on_farm_id} already exists " + f"on farm with id {farm_id}...", end=" ", flush=True) await client.attachments.get(farmer_id=farmer_id, attachment_id=attachment_on_farm_id) print("Attachment already exists. Not updating file.") except ResourceNotFoundError: print("Attachment doesn't exist") print("Creating attachment...", end=" ", flush=True) # Open file with buffering set to 0, to get a IO object. file_to_attach_on_farm = open(attachment_on_farm_file_path, "rb", buffering=0) await client.attachments.create_or_update( farmer_id=farmer_id, attachment_id=attachment_on_farm_id, resource_id=farm_id, resource_type="Farm", file=file_to_attach_on_farm) print("Done!") print("Proceeding to download all attachments on the farmer. " + "Press enter to continue...") input() print("Getting a list of all attachments " + f"on the farmer with id {farmer_id}...", end=" ", flush=True) farmer_attachments = client.attachments.list_by_farmer_id( farmer_id=farmer_id, ) print("Done!") # Using a semaphore to limit the number of concurrent downloads. semaphore = asyncio.Semaphore(2) print("Downloading attachments with a maximum concurrency " + "of two downloads at a time...") # Setting up a async function (a coroutine) to download each attachment async def download(attachment, semaphore): async with semaphore: downloaded_attachment = await client.attachments.download( farmer_id=farmer_id, attachment_id=attachment_on_farmer_id) out_path = Path( "../data/attachments/" + f"{attachment.resource_type}/{attachment.resource_id}" + f"/{attachment.id}/{attachment.original_file_name}") # Make sure the dirs to the output path exists out_path.parent.mkdir(parents=True, exist_ok=True) print( f"Saving attachment id {attachment.id} to {out_path.resolve()}" ) with open(out_path, 'wb') as out_file: async for bits in downloaded_attachment: out_file.write(bits) await asyncio.gather(*[ download(attachment, semaphore) async for attachment in farmer_attachments ]) print("Done!") await client.close() await credential.close()
def test_farmer_operations(self, agrifood_endpoint): # Setup data farmer_id = "test-farmer-farmer-ops" farmer_name = "Test Farmer" farmer_description = "Farmer created during testing." farmer_status = "Sample Status" farmer_properties = {"foo": "bar", "numeric one": 1, 1: "numeric key"} # Setup client client = self.create_client(agrifood_endpoint=agrifood_endpoint) # Create farmer = client.farmers.create_or_update( farmer_id=farmer_id, farmer=Farmer(name=farmer_name, description=farmer_description, status=farmer_status, properties=farmer_properties)) # Assert on immediate response assert farmer.id == farmer_id assert farmer.name == farmer_name assert farmer.description == farmer_description assert farmer.status == farmer_status assert len(farmer.properties) == 3 assert farmer.properties["foo"] == "bar" assert farmer.properties["numeric one"] == 1 assert farmer.properties["1"] == "numeric key" assert farmer.e_tag assert type(farmer.created_date_time) is datetime assert type(farmer.modified_date_time) is datetime # Retrieve created object retrieved_farmer = client.farmers.get(farmer_id=farmer_id) # Assert on retrieved object assert farmer == retrieved_farmer # Setup data for update farmer.name += " Updated" # Update updated_farmer = client.farmers.create_or_update(farmer_id=farmer_id, farmer=farmer) # Assert on immediate response assert farmer.name == updated_farmer.name assert farmer.created_date_time == updated_farmer.created_date_time assert farmer.modified_date_time != updated_farmer.modified_date_time # Retrieve updated object updated_retrieved_farmer = client.farmers.get(farmer_id=farmer_id) # Assert updated object assert updated_retrieved_farmer == updated_farmer # Delete client.farmers.delete(farmer_id=farmer_id) # Assert object doesn't exist anymore with pytest.raises(ResourceNotFoundError): client.farmers.get(farmer_id=farmer_id)
async def sample_farm_hierarchy_complete_async(): farmbeats_endpoint = os.environ['FARMBEATS_ENDPOINT'] credential = DefaultAzureCredential() client = FarmBeatsClient(endpoint=farmbeats_endpoint, credential=credential) farmer_id = "contoso-farmer" farmer_name = "Contoso" farmer_description = "Contoso is hard working." farmer_id = "contoso-farmer" farmer_name = "contoso-farmer-name" farmer_description = "contoso-farmer-description" farm_id = "contoso-farm" farm_name = "contoso-farm-name" farm_description = "contoso-farm-description" field_id = "contoso-field" field_name = "contoso-field-name" field_description = "contoso-field-description" boundary_id = "contoso-boundary" boundary_name = "contoso-boundary-name" boundary_description = "contoso-boundary-description" crop_id = "contoso-crop" crop_name = "contoso-crop-name" crop_description = "contoso-crop-description" crop_variety_id = "contoso-crop-variety" crop_variety_name = "contoso-crop_variety-name" crop_variety_description = "contoso-crop-variety-description" season_id = "contoso-season" season_name = "contoso-season-name" season_description = "contoso-season-description" seasonal_field_id = "contoso-seasonal_field" seasonal_field_name = "contoso-seasonal_field-name" seasonal_field_description = "contoso-seasonal_field-description" year = "2021" start_date_time = "2021-01-01T20:08:10.137Z" end_date_time = "2021-06-06T20:08:10.137Z" multi_polygon = MultiPolygon(coordinates=[ [[[-94.05807495, 44.75916947], [-94.05802487, 44.7592142], [-94.05798752, 44.75921875], [-94.05692697, 44.75883808], [-94.05697525, 44.75861334], [-94.05542493, 44.75844192], [-94.05537128, 44.75891045], [-94.05443251, 44.75884951], [-94.05086517, 44.75856001], [-94.05093491, 44.75533736], [-94.05389607, 44.75516594], [-94.05421793, 44.75520023], [-94.05447543, 44.75534879], [-94.05746988, 44.75751702], [-94.05795157, 44.75824385], [-94.05805349, 44.75863619], [-94.05807495, 44.75916947]]], [[[-94.05802667, 44.75929136], [-94.05793598, 44.7607673], [-94.05693233, 44.76072738], [-94.05694842, 44.76008746], [-94.05727246, 44.75988264], [-94.05752903, 44.75946416], [-94.05760288, 44.75923042], [-94.05802667, 44.75929136]]] ]) # Step 1: Create a farmer. print(f"Creating or updating farmer with Id {farmer_id}...", end=" ", flush=True) farmer = await client.farmers.create_or_update( farmer_id=farmer_id, farmer=Farmer(name=farmer_name, description=farmer_description)) print("Done") print("Details of farmer:") print("\tID:", farmer.id) print("\tName:", farmer.name) print("\tDescription:", farmer.description) # Step 2: Create a farm. print(f"Creating or updating farm with Id {farm_id}...", end=" ", flush=True) farm = await client.farms.create_or_update( farmer_id=farmer_id, farm_id=farm_id, farm=Farm(name=farm_name, description=farm_description)) print("Done") print("Details of farm:") print("\tID:", farm.id) print("\tName:", farm.name) print("\tFarmer Name:", farm.farmer_id) print("\tDescription:", farm.description) # Step 3: Create a field. print(f"Creating or updating field with Id {field_id}...", end=" ", flush=True) field = await client.fields.create_or_update( farmer_id=farmer_id, field_id=field_id, field=Field(name=field_name, farm_id=farm_id, description=field_description)) print("Done") print("Details of field:") print("\tID:", field.id) print("\tName:", field.name) print("\tFarmer Name:", field.farmer_id) print("\tFarm Name:", field.farm_id) print("\tName:", field.name) print("\tDescription:", field.description) # Step 4: Create a crop. print(f"Creating or updating crop with Id {crop_id}...", end=" ", flush=True) crop = await client.crops.create_or_update( crop_id=crop_id, crop=Crop(name=crop_name, description=crop_description)) print("Done") print("Details of crop:") print("\tID:", crop.id) print("\tName:", crop.name) print("\tDescription:", crop.description) # Step 5: Create a crop variety. print(f"Creating or updating crop variety with Id {crop_variety_id}...", end=" ", flush=True) crop_variety = await client.crop_varieties.create_or_update( crop_id=crop_id, crop_variety_id=crop_variety_id, crop_variety=CropVariety(name=crop_variety_name, description=crop_variety_description)) print("Done") print("Details of crop variety:") print("\tID:", crop_variety.id) print("\tCrop ID:", crop_variety.crop_id) print("\tName:", crop_variety.name) print("\tDescription:", crop_variety.description) # Step 6: Create a season. print(f"Creating or updating season with Id {season_id}...", end=" ", flush=True) season = await client.seasons.create_or_update( season_id=season_id, season=Season(name=season_name, year=year, start_date_time=start_date_time, end_date_time=end_date_time, description=season_description)) print("Done") print("Details of season:") print("\tID:", season.id) print("\tName:", season.name) print("\tDescription:", season.description) print("\tYear:", season.year) print("\tStart Date Time:", season.start_date_time) print("\tEnd Date Time:", season.end_date_time) # Step 7: Create a seasonal field. print( f"Creating or updating seasonal field with Id {seasonal_field_id}...", end=" ", flush=True) seasonal_field = await client.seasonal_fields.create_or_update( farmer_id=farmer_id, seasonal_field_id=seasonal_field_id, seasonal_field=SeasonalField(name=seasonal_field_name, farm_id=farm_id, field_id=field_id, season_id=season_id, crop_id=crop_id, crop_variety_ids=[crop_variety_id], description=seasonal_field_description)) print("Done") print("Details of seasonal field:") print("\tID:", seasonal_field.id) print("\tName:", seasonal_field.name) print("\tFarmer Name:", seasonal_field.farmer_id) print("\tFarm Name:", seasonal_field.farm_id) print("\tCrop Name:", seasonal_field.crop_id) print("\tSeason Name:", seasonal_field.season_id) print("\tField Name:", seasonal_field.field_id) print("\tCrop Variety Name:", seasonal_field.crop_variety_ids) print("\tName:", seasonal_field.name) print("\tDescription:", seasonal_field.description) # Step 8: Create a boundary. try: print(f"Trying to fetch boundary with id {boundary_id}...", end=" ", flush=True) boundary = await client.boundaries.get(farmer_id=farmer_id, boundary_id=boundary_id) print("Boundary already exists.") except ResourceNotFoundError: print(f"Doesn't exist. Creating boundary...", end=" ", flush=True) boundary = client.boundaries.create_or_update( farmer_id=farmer_id, boundary_id=boundary_id, boundary=Boundary(name=boundary_name, geometry=multi_polygon, parent_id=seasonal_field_id, description=boundary_description)) print("Done") print("Details of boundary:") print("\tID:", boundary.id) print("\tName:", boundary.name) print("\tDescription:", boundary.description) print("\tParentId:", boundary.parent_id) await client.close() await credential.close()