refactor: Move script to dedicated folder
This commit is contained in:
		
							
								
								
									
										97
									
								
								scripts/upload_animal_shelters.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								scripts/upload_animal_shelters.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,97 @@
 | 
			
		||||
import argparse
 | 
			
		||||
import json
 | 
			
		||||
import os
 | 
			
		||||
 | 
			
		||||
import requests
 | 
			
		||||
 | 
			
		||||
DEFAULT_OSM_DATA_FILE = "osm_data.geojson"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def parse_args():
 | 
			
		||||
    """Parse command-line arguments."""
 | 
			
		||||
    parser = argparse.ArgumentParser(description="Upload animal shelter data to the Notfellchen API.")
 | 
			
		||||
    parser.add_argument("--api-token", type=str, help="API token for authentication.")
 | 
			
		||||
    parser.add_argument("--instance", type=str, help="API instance URL.")
 | 
			
		||||
    parser.add_argument("--data-file", type=str, help="Path to the GeoJSON file containing (only) animal shelters.")
 | 
			
		||||
    return parser.parse_args()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_config():
 | 
			
		||||
    """Get configuration from environment variables or command-line arguments."""
 | 
			
		||||
    args = parse_args()
 | 
			
		||||
 | 
			
		||||
    api_token = args.api_token or os.getenv("NOTFELLCHEN_API_TOKEN")
 | 
			
		||||
    instance = args.instance or os.getenv("NOTFELLCHEN_INSTANCE")
 | 
			
		||||
    data_file = args.data_file or os.getenv("NOTFELLCHEN_DATA_FILE", DEFAULT_OSM_DATA_FILE)
 | 
			
		||||
 | 
			
		||||
    if not api_token or not instance:
 | 
			
		||||
        raise ValueError("API token and instance URL must be provided via environment variables or CLI arguments.")
 | 
			
		||||
 | 
			
		||||
    return api_token, instance, data_file
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def load_osm_data(file_path):
 | 
			
		||||
    """Load OSM data from a GeoJSON file."""
 | 
			
		||||
    with open(file_path, "r", encoding="utf-8") as file:
 | 
			
		||||
        data = json.load(file)
 | 
			
		||||
    return data
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def load_osm_data(file_path):
 | 
			
		||||
    #Load OSM data from a GeoJSON file.
 | 
			
		||||
    with open(file_path, "r", encoding="utf-8") as file:
 | 
			
		||||
        data = json.load(file)
 | 
			
		||||
    return data
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def transform_osm_data(feature):
 | 
			
		||||
    #Transform a single OSM feature into the API payload format
 | 
			
		||||
    prop = feature.get("properties", {})
 | 
			
		||||
    geometry = feature.get("geometry", {})
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
        "name": prop.get("name", "Unnamed Shelter"),
 | 
			
		||||
        "phone": prop.get("phone"),
 | 
			
		||||
        "website": prop.get("website"),
 | 
			
		||||
        "opening_hours": prop.get("opening_hours"),
 | 
			
		||||
        "email": prop.get("email"),
 | 
			
		||||
        "location_string": f'{prop.get("addr:street", "")} {prop.get("addr:housenumber", "")} {prop.get("addr:postcode", "")} {prop.get("addr:city", "")}',
 | 
			
		||||
        "external_object_id": prop.get("@id"),
 | 
			
		||||
        "external_source_id": "OSM"
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def send_to_api(data, endpoint, headers):
 | 
			
		||||
    # Send transformed data to the Notfellchen API.
 | 
			
		||||
    response = requests.post(endpoint, headers=headers, json=data)
 | 
			
		||||
    if response.status_code == 201:
 | 
			
		||||
        print(f"Success: Shelter '{data['name']}' uploaded.")
 | 
			
		||||
    elif response.status_code == 400:
 | 
			
		||||
        print(f"Error: Shelter '{data['name']}' already exists or invalid data. {response.text}")
 | 
			
		||||
    else:
 | 
			
		||||
        print(f"Unexpected Error: {response.status_code} - {response.text}")
 | 
			
		||||
        raise ConnectionError
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def main():
 | 
			
		||||
    # Get configuration
 | 
			
		||||
    api_token, instance, data_file = get_config()
 | 
			
		||||
 | 
			
		||||
    # Set headers and endpoint
 | 
			
		||||
    endpoint = f"{instance}/api/organizations/"
 | 
			
		||||
    headers = {
 | 
			
		||||
        "Authorization": f"Token {api_token}",
 | 
			
		||||
        "Content-Type": "application/json"
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    # Step 1: Load OSM data
 | 
			
		||||
    osm_data = load_osm_data(data_file)
 | 
			
		||||
 | 
			
		||||
    # Step 2: Process each shelter and send it to the API
 | 
			
		||||
    for feature in osm_data.get("features", []):
 | 
			
		||||
        shelter_data = transform_osm_data(feature)
 | 
			
		||||
        send_to_api(shelter_data, endpoint, headers)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if __name__ == "__main__":
 | 
			
		||||
    main()
 | 
			
		||||
		Reference in New Issue
	
	Block a user