def test_create_observation_fail(requests_mock): params = { "species_guess": "Pieris rapae", # Some invalid data so the observation is rejected... "observed_on_string": (datetime.now() + timedelta(days=1)).isoformat(), "latitude": 200, } requests_mock.post( urljoin(INAT_BASE_URL, "observations.json"), json=load_sample_data("create_observation_fail.json"), status_code=422, ) with pytest.raises(HTTPError) as excinfo: create_observation(access_token="valid token", **params) assert excinfo.value.response.status_code == 422 assert "errors" in excinfo.value.response.json() # iNat also give details about the errors
def test_create_observation(requests_mock): requests_mock.post( urljoin(INAT_BASE_URL, "observations.json"), json=load_sample_data("create_observation_result.json"), status_code=200, ) r = create_observation(species_guess="Pieris rapae", access_token="valid token") assert len(r) == 1 # We added a single one assert r[0]["latitude"] is None assert r[0]["taxon_id"] == 55626 # Pieris Rapae @ iNaturalist
def create_test_obs(token): response = create_observation( taxon_id=54327, observed_on_string=datetime.now().isoformat(), description= "This is a test observation used by pyinaturalist, and will be deleted shortly.", tag_list="wasp, Belgium", latitude=50.647143, longitude=4.360216, positional_accuracy=50, geoprivacy="open", access_token=token, observation_fields={297: 1}, ) test_obs_id = response[0]["id"] print("Created new observation: {}".format(test_obs_id)) obs = get_observation(test_obs_id) print("Fetched new observation:") pprint(obs, indent=2) return test_obs_id
def test_create_observation__local_photo(post, ensure_file_objs): create_observation(access_token="token", local_photos="photo.jpg") # Make sure local_photos is replaced with the output of ensure_file_objs called_params = post.call_args[1]["json"]["observation"] assert called_params["local_photos"] == ensure_file_objs.return_value
def inaturalist_api(): json_data = json.loads(request.data) print(json_data) utc_key = json_data['utc_key'] print(f'utc_key: {utc_key}') if utc_key is None: return print(f'key: {utc_key}') conn = sqlite3.connect(DB_PATH, timeout=15) query = '''SELECT datetime, file_name, prediction, true_label, inaturalist_id FROM results WHERE utc_datetime = ? LIMIT 1;''' c = conn.cursor() c.execute(query, (utc_key, )) row = c.fetchone() if row is None: return else: obs_timestamp = row[0] img_fn = row[1] pred_label = row[2] true_label = row[3] existing_inat_id = row[4] if true_label is not None: obs_label = true_label else: obs_label = pred_label # Get a token for the inaturalist API token = get_access_token( username=INAT_USERNAME, password=INAT_PASSWORD, app_id=INAT_APP_ID, app_secret=INAT_APP_SECRET, ) obs_file_name = f'{DATA_DIR}/imgs/{img_fn}' # Upload the observation to iNaturalist if existing_inat_id is None: # Check if there's an existing inat id within 5 minutes of this image # upload this image to that observation if so. window_timestamp = dt.datetime.fromisoformat(utc_key) - dt.timedelta( minutes=10) window_timestamp = window_timestamp.strftime(dt_fmt) query = '''SELECT inaturalist_id FROM results WHERE utc_datetime <= :utc_dt AND utc_datetime >= :prev_dt AND inaturalist_id IS NOT NULL AND (true_label = :lab OR (true_label IS NULL AND prediction = :lab)) ORDER BY utc_datetime DESC LIMIT 1;''' c.execute(query, { 'utc_dt': utc_key, 'prev_dt': window_timestamp, 'lab': obs_label }) row = c.fetchone() if row is None or row[0] is None: response = create_observation( taxon_id=species_map[obs_label]['taxa_id'], observed_on_string=obs_timestamp, time_zone='Mountain Time (US & Canada)', description= 'Birb Cam image upload: https://github.com/evjrob/birbcam', tag_list=f'{obs_label}, Canada', latitude=INAT_LATITUDE, longitude=INAT_LONGITUDE, positional_accuracy=INAT_POSITIONAL_ACCURACY, # meters, access_token=token, ) inat_observation_id = response[0]['id'] print( f'No iNaturalist id found in previous ten minutes, creating new row with id {inat_observation_id}.' ) else: inat_observation_id = row[0] print( f'Found iNaturalist id in previous ten minutes, adding to id {inat_observation_id}.' ) # Upload the image captured r = add_photo_to_observation( inat_observation_id, access_token=token, photo=obs_file_name, ) # Update the row in the database with the inaturalist id c.execute("UPDATE results SET inaturalist_id=? WHERE utc_datetime=?;", (inat_observation_id, utc_key)) else: # This image had already been uploaded, we do not want to upload it again inat_observation_id = existing_inat_id print( f'Found existing iNaturalist id {inat_observation_id} for row, skipping.' ) conn.commit() conn.close() return jsonify({'inat_id': inat_observation_id})