""" Push the scraped iNaturalist bee photos to a Hugging Face dataset repo. Earns the "Sharing is Caring" badge. Run once after the scraper finishes: py scripts/push_dataset_to_hub.py --repo-id maryammeda/apiarist-bee-photos """ from __future__ import annotations import argparse import json import os from pathlib import Path from dotenv import load_dotenv from huggingface_hub import HfApi DEFAULT_DATA_DIR = Path("data/raw/inaturalist") README_TEMPLATE = """--- license: cc-by-4.0 tags: - bees - biology - nature - computer-vision - object-detection size_categories: - n<1K --- # Apiarist iNaturalist bee photos Honey-bee (*Apis mellifera*) photos scraped from the iNaturalist API as training context for **Apiarist**, a fully-offline AI hive frame inspector built for the [Build Small Hackathon](https://huggingface.co/build-small-hackathon). ## Composition - **{n_photos} photos** of Apis mellifera observations - Filtered to permissively-licensed images (CC0, CC-BY, CC-BY-SA, CC-BY-NC, etc.) - Most are forager bees on flowers; useful as bee context for VLM prompting ## Files - `images/`, JPEG photos, filenames are iNaturalist photo IDs - `metadata.jsonl`, one line per photo: license, observation ID, observed date, place, source URL ## License Each photo retains its original Creative Commons license (see `metadata.jsonl`). The collection layout is CC-BY-4.0. ## Citation > iNaturalist contributors. Apis mellifera observations. > Available from https://www.inaturalist.org """ def main() -> None: parser = argparse.ArgumentParser() parser.add_argument( "--repo-id", required=True, help="Target repo, e.g. 'maryammeda/apiarist-bee-photos'", ) parser.add_argument("--data-dir", type=Path, default=DEFAULT_DATA_DIR) parser.add_argument( "--private", action="store_true", help="Create repo as private (default public)", ) args = parser.parse_args() load_dotenv() token = os.environ.get("HF_TOKEN") or os.environ.get("HUGGING_FACE_HUB_TOKEN") if not token: raise SystemExit( "Need HF_TOKEN in .env (or HUGGING_FACE_HUB_TOKEN). " "Get one at https://huggingface.co/settings/tokens (write scope)." ) if not args.data_dir.exists(): raise SystemExit(f"Data dir not found: {args.data_dir}") meta_path = args.data_dir / "metadata.jsonl" if not meta_path.exists(): raise SystemExit(f"Missing {meta_path}") with open(meta_path) as f: n_photos = sum(1 for line in f if line.strip()) print(f"Found {n_photos} photos in {args.data_dir}") # Write README into the data dir before upload readme_path = args.data_dir / "README.md" readme_path.write_text( README_TEMPLATE.format(n_photos=n_photos), encoding="utf-8" ) api = HfApi(token=token) print(f"Creating dataset repo {args.repo_id} ...") api.create_repo( repo_id=args.repo_id, repo_type="dataset", private=args.private, exist_ok=True, ) print(f"Uploading {args.data_dir} -> {args.repo_id} ...") api.upload_folder( repo_id=args.repo_id, repo_type="dataset", folder_path=str(args.data_dir), commit_message="Initial upload of Apiarist iNaturalist bee photos", ) print( f"\n Dataset live at: https://huggingface.co/datasets/{args.repo_id}" ) if __name__ == "__main__": main()