Add seed_insects.py (15 curated beneficial + pest insects)
This commit is contained in:
@@ -0,0 +1,134 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Seed a curated starter set of beneficial & pest insects relevant to a temperate
|
||||
permaculture farm. Conservative, widely-documented entomological facts.
|
||||
Idempotent: skips insects whose slug already exists.
|
||||
|
||||
Run: HERBAPI_TOKEN=... python3 seed_insects.py
|
||||
"""
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import urllib.error
|
||||
import urllib.request
|
||||
|
||||
BASE = os.environ.get("HERBAPI_BASE", "http://herbapi01.corp.sub-net.at:8080/api/v1")
|
||||
TOKEN = os.environ.get("HERBAPI_TOKEN", "")
|
||||
|
||||
|
||||
def api(path, method="GET", data=None):
|
||||
r = urllib.request.Request(
|
||||
BASE + path,
|
||||
data=json.dumps(data).encode() if data is not None else None,
|
||||
method=method,
|
||||
)
|
||||
r.add_header("Authorization", "Bearer " + TOKEN)
|
||||
r.add_header("Content-Type", "application/json")
|
||||
try:
|
||||
with urllib.request.urlopen(r) as resp:
|
||||
return resp.status, json.loads(resp.read().decode())
|
||||
except urllib.error.HTTPError as e:
|
||||
return e.code, e.read().decode()[:200]
|
||||
|
||||
|
||||
INSECTS = [
|
||||
# ── Beneficials ──
|
||||
{"name_scientific": "Apis mellifera", "name_de": "Westliche Honigbiene", "name_en": "Western honey bee",
|
||||
"order_scientific": "Hymenoptera", "family_scientific": "Apidae", "role": "beneficial",
|
||||
"beneficial_roles": ["pollinator"], "life_cycle": "holometabolous", "overwinters_as": "adult",
|
||||
"active_months": [3, 4, 5, 6, 7, 8, 9, 10],
|
||||
"description": "Eusocial honey bee; the principal managed pollinator of orchards and field crops.",
|
||||
"native_range": "Europe, Africa, Western Asia"},
|
||||
{"name_scientific": "Bombus terrestris", "name_de": "Dunkle Erdhummel", "name_en": "Buff-tailed bumblebee",
|
||||
"order_scientific": "Hymenoptera", "family_scientific": "Apidae", "role": "beneficial",
|
||||
"beneficial_roles": ["pollinator"], "life_cycle": "holometabolous", "overwinters_as": "adult",
|
||||
"active_months": [3, 4, 5, 6, 7, 8, 9],
|
||||
"description": "Buzz-pollinator, effective on tomatoes and early-season fruit in cool weather.",
|
||||
"native_range": "Europe"},
|
||||
{"name_scientific": "Osmia bicornis", "name_de": "Rote Mauerbiene", "name_en": "Red mason bee",
|
||||
"order_scientific": "Hymenoptera", "family_scientific": "Megachilidae", "role": "beneficial",
|
||||
"beneficial_roles": ["pollinator"], "life_cycle": "holometabolous", "overwinters_as": "adult",
|
||||
"active_months": [4, 5, 6],
|
||||
"description": "Solitary spring bee; excellent orchard pollinator, readily uses bee hotels.",
|
||||
"native_range": "Europe"},
|
||||
{"name_scientific": "Coccinella septempunctata", "name_de": "Siebenpunkt-Marienkäfer", "name_en": "Seven-spot ladybird",
|
||||
"order_scientific": "Coleoptera", "family_scientific": "Coccinellidae", "role": "beneficial",
|
||||
"beneficial_roles": ["predator"], "preys_on": ["myzus-persicae"], "life_cycle": "holometabolous",
|
||||
"overwinters_as": "adult", "active_months": [4, 5, 6, 7, 8, 9],
|
||||
"description": "Adults and larvae are voracious aphid predators.", "native_range": "Palearctic"},
|
||||
{"name_scientific": "Chrysoperla carnea", "name_de": "Gemeine Florfliege", "name_en": "Green lacewing",
|
||||
"order_scientific": "Neuroptera", "family_scientific": "Chrysopidae", "role": "beneficial",
|
||||
"beneficial_roles": ["predator"], "preys_on": ["myzus-persicae"], "life_cycle": "holometabolous",
|
||||
"overwinters_as": "adult", "active_months": [4, 5, 6, 7, 8, 9],
|
||||
"description": "Larvae ('aphid lions') prey on aphids, mites and small caterpillars.", "native_range": "Europe"},
|
||||
{"name_scientific": "Episyrphus balteatus", "name_de": "Hainschwebfliege", "name_en": "Marmalade hoverfly",
|
||||
"order_scientific": "Diptera", "family_scientific": "Syrphidae", "role": "beneficial",
|
||||
"beneficial_roles": ["pollinator", "predator"], "preys_on": ["myzus-persicae"], "life_cycle": "holometabolous",
|
||||
"overwinters_as": "adult", "active_months": [3, 4, 5, 6, 7, 8, 9, 10],
|
||||
"description": "Adults pollinate; larvae are major aphid predators.", "native_range": "Palearctic"},
|
||||
{"name_scientific": "Aphidius colemani", "name_de": "Blattlaus-Schlupfwespe", "name_en": "Aphid parasitoid wasp",
|
||||
"order_scientific": "Hymenoptera", "family_scientific": "Braconidae", "role": "beneficial",
|
||||
"beneficial_roles": ["parasitoid"], "preys_on": ["myzus-persicae"], "life_cycle": "holometabolous",
|
||||
"description": "Tiny wasp that parasitises aphids; widely used in biocontrol.", "native_range": "Cosmopolitan (biocontrol)"},
|
||||
{"name_scientific": "Carabus auratus", "name_de": "Goldlaufkäfer", "name_en": "Golden ground beetle",
|
||||
"order_scientific": "Coleoptera", "family_scientific": "Carabidae", "role": "beneficial",
|
||||
"beneficial_roles": ["predator"], "life_cycle": "holometabolous", "overwinters_as": "adult",
|
||||
"active_months": [4, 5, 6, 7, 8],
|
||||
"description": "Ground-dwelling predator of slugs, caterpillars and other soil pests.", "native_range": "Western Europe"},
|
||||
# ── Pests ──
|
||||
{"name_scientific": "Myzus persicae", "name_de": "Grüne Pfirsichblattlaus", "name_en": "Green peach aphid",
|
||||
"order_scientific": "Hemiptera", "family_scientific": "Aphididae", "role": "pest", "pest_severity": "major",
|
||||
"life_cycle": "hemimetabolous", "active_months": [4, 5, 6, 7, 8, 9, 10],
|
||||
"description": "Highly polyphagous aphid; sap-sucker and major virus vector.", "native_range": "Cosmopolitan"},
|
||||
{"name_scientific": "Leptinotarsa decemlineata", "name_de": "Kartoffelkäfer", "name_en": "Colorado potato beetle",
|
||||
"order_scientific": "Coleoptera", "family_scientific": "Chrysomelidae", "role": "pest", "pest_severity": "major",
|
||||
"life_cycle": "holometabolous", "overwinters_as": "adult", "active_months": [5, 6, 7, 8],
|
||||
"description": "Defoliates potato and other solanaceous crops; rapid resistance to insecticides.", "native_range": "North America (invasive in Europe)"},
|
||||
{"name_scientific": "Pieris brassicae", "name_de": "Großer Kohlweißling", "name_en": "Large white",
|
||||
"order_scientific": "Lepidoptera", "family_scientific": "Pieridae", "role": "pest", "pest_severity": "moderate",
|
||||
"life_cycle": "holometabolous", "overwinters_as": "pupa", "active_months": [4, 5, 6, 7, 8, 9],
|
||||
"description": "Caterpillars defoliate brassicas (cabbage, kale, broccoli).", "native_range": "Europe, North Africa, Asia"},
|
||||
{"name_scientific": "Plutella xylostella", "name_de": "Kohlmotte", "name_en": "Diamondback moth",
|
||||
"order_scientific": "Lepidoptera", "family_scientific": "Plutellidae", "role": "pest", "pest_severity": "moderate",
|
||||
"life_cycle": "holometabolous", "active_months": [5, 6, 7, 8, 9],
|
||||
"description": "Small moth whose larvae mine and skeletonise brassica leaves; resistance-prone.", "native_range": "Cosmopolitan"},
|
||||
{"name_scientific": "Delia radicum", "name_de": "Kleine Kohlfliege", "name_en": "Cabbage root fly",
|
||||
"order_scientific": "Diptera", "family_scientific": "Anthomyiidae", "role": "pest", "pest_severity": "moderate",
|
||||
"life_cycle": "holometabolous", "overwinters_as": "pupa", "active_months": [4, 5, 6, 7, 8],
|
||||
"description": "Larvae feed on brassica roots, wilting and killing transplants.", "native_range": "Holarctic"},
|
||||
{"name_scientific": "Phyllotreta nemorum", "name_de": "Gelbstreifiger Kohlerdfloh", "name_en": "Turnip flea beetle",
|
||||
"order_scientific": "Coleoptera", "family_scientific": "Chrysomelidae", "role": "pest", "pest_severity": "minor",
|
||||
"life_cycle": "holometabolous", "overwinters_as": "adult", "active_months": [4, 5, 6, 7],
|
||||
"description": "Adults shot-hole brassica seedlings; worst in warm dry spells.", "native_range": "Europe, Asia"},
|
||||
{"name_scientific": "Forficula auricularia", "name_de": "Gemeiner Ohrwurm", "name_en": "European earwig",
|
||||
"order_scientific": "Dermaptera", "family_scientific": "Forficulidae", "role": "both",
|
||||
"beneficial_roles": ["predator"], "pest_severity": "minor", "preys_on": ["myzus-persicae"],
|
||||
"life_cycle": "hemimetabolous", "overwinters_as": "adult", "active_months": [5, 6, 7, 8, 9, 10],
|
||||
"description": "Eats aphids and codling-moth eggs (beneficial) but can damage soft fruit and seedlings.",
|
||||
"native_range": "Europe"},
|
||||
]
|
||||
|
||||
|
||||
def main():
|
||||
if not TOKEN:
|
||||
raise SystemExit("HERBAPI_TOKEN not set")
|
||||
existing = {i["slug"] for i in api("/insects?per_page=100")[1]["data"]}
|
||||
created = skipped = errors = 0
|
||||
for ins in INSECTS:
|
||||
slug = re.sub(r"[^a-z0-9]+", "-", ins["name_scientific"].lower()).strip("-")
|
||||
if slug in existing:
|
||||
print(f"skip {slug} (exists)")
|
||||
skipped += 1
|
||||
continue
|
||||
code, resp = api("/insects", "POST", ins)
|
||||
if code == 200:
|
||||
print(f"created {slug}")
|
||||
created += 1
|
||||
else:
|
||||
print(f"ERROR {slug}: {code} {resp}")
|
||||
errors += 1
|
||||
print(f"\ncreated={created} skipped={skipped} errors={errors}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user