Erste Schritte
Alle Aufrufe stammen aus derselben Datenbank und geben JSON zurück. Öffentliche Endpunkte erfordern keine Authentifizierung; Private benötigen Ihren Zugangsschlüssel.
Basisadresse
/de-at/api Das Sprachpräfix ist Teil der URL (de-at), die zurückgegebenen Daten werden dadurch jedoch nicht geändert – die Datensätze stammen von der Bank genau so, wie sie im Feld registriert wurden.
curl -G -d "municipality=Ponta Pora" --data-urlencode "country=Brasil" \
/de-at/api/lastcountingpublic Wenn die Antwort eine JSON-Liste ist, funktioniert die Integration bereits.
key wird aus der Abfragezeichenfolge gelesen (?key=SUA_CHAVE). Senden Sie es nur im Hauptteil der Formularrückgabe 404 "Wrong key". Die anderen Felder erscheinen weiterhin im Hauptteil der Anfrage. Konsultieren Sie öffentliche Daten
Der Endpunkt /api/lastcountingpublic Gibt die neuesten Eierzahlen mit epidemiologischem Breitengrad, Längengrad, Woche und Jahr zurück. Es ist Ausgangspunkt für Karten, Tafeln und Studien.
/api/lastcountingpublicÖffentlichcurl -G \
--data-urlencode "municipality=Ponta Pora" \
--data-urlencode "date_start=2025-01-01" \
--data-urlencode "date_end=2025-12-31" \
/de-at/api/lastcountingpublic import requests
BASE = "/de-at/api"
resposta = requests.get(
BASE + "/lastcountingpublic",
params={
"municipality": "Ponta Pora",
"date_start": "2025-01-01",
"date_end": "2025-12-31",
},
timeout=60,
)
resposta.raise_for_status()
for contagem in resposta.json():
print(contagem["date"], contagem["ovitrap_id"], contagem["eggs"]) const BASE = "/de-at/api";
const params = new URLSearchParams({
state: "MS",
date_start: "2025-01-01",
});
const resposta = await fetch(BASE + "/lastcountingpublic?" + params);
const contagens = await resposta.json();
console.log(contagens.length, "contagens"); Die gleichen Standortparameter (country, state, municipality) Sie gelten für andere öffentliche Endpunkte: Ovitraps, Blöcke, EDLs, EDL-Wartung und strategische Punkte. Allein die Änderung des Endpunktpfads ändert bereits den Datensatz.
Durchsuchen Sie alle Seiten
Unterstützung für paginierte Endpunkte page von 1 bis 100. Darüber antwortet die API mit dem Text "Maximum pagination is 100" und Status 200 – das heißt, der Körper ist keine Liste mehr. Überprüfen Sie immer den Typ, bevor Sie iterieren.
import requests
BASE = "/de-at/api"
def baixar_tudo(endpoint, **filtros):
"""Percorre as paginas ate a API devolver uma pagina vazia."""
registros = []
for pagina in range(1, 101):
resposta = requests.get(
BASE + endpoint,
params=dict(filtros, page=pagina),
timeout=60,
)
resposta.raise_for_status()
dados = resposta.json()
# limite de paginacao atingido: a API devolve uma string, nao uma lista
if not isinstance(dados, list):
print("Aviso:", dados)
break
if not dados:
break
registros.extend(dados)
return registros
ovitrampas = baixar_tudo("/getmunicipalityovitrapspublic", municipality="Ponta Pora")
print(len(ovitrampas), "ovitrampas") date_start e date_end den Zeitraum in kleinere Intervalle zu unterteilen. Inkrementelle Synchronisierung
Um eine gespiegelte Basis aufrechtzuerhalten, laden Sie nicht bei jedem Lauf alles erneut herunter. Der Endpunkt /api/lastcountingpublic akzeptiert id, was nur die Anzahlen von diesem Bezeichner zurückgibt, und auch date (Aufnahmedatum) e date_collect (data de coleta).
import json
import os
import requests
BASE = "/de-at/api"
ESTADO = "ultimo_id.json"
def ultimo_id_lido():
if os.path.exists(ESTADO):
with open(ESTADO) as arquivo:
return json.load(arquivo)["counting_id"]
return 0
def sincronizar():
ultimo = ultimo_id_lido()
novas = []
for pagina in range(1, 101):
resposta = requests.get(
BASE + "/lastcountingpublic",
params={"municipality": "Ponta Pora", "id": ultimo, "page": pagina},
timeout=60,
)
resposta.raise_for_status()
dados = resposta.json()
if not isinstance(dados, list) or not dados:
break
novas.extend(dados)
if novas:
maior = max(item["counting_id"] for item in novas)
with open(ESTADO, "w") as arquivo:
json.dump({"counting_id": maior}, arquivo)
return novas
print(len(sincronizar()), "contagens novas") Behalten Sie immer das Größte counting_id empfangen, nicht das Datum der Ausführung: Eine in das Feld heute eingegebene Zählung kann sich auf eine vorherige Woche beziehen, und der Filter nach ID lässt diese Datensätze nicht entkommen.
Als CSV exportieren
Öffentliche Zählungen enthalten bereits Koordinaten, sodass Sie ohne zusätzliche Verknüpfung eine Tabelle erstellen oder eine Karte einspeisen können.
import csv
import requests
BASE = "/de-at/api"
COLUNAS = [
"counting_id",
"municipality",
"state_code",
"ovitrap_id",
"latitude",
"longitude",
"week",
"year",
"eggs",
"date",
"date_collect",
]
resposta = requests.get(
BASE + "/lastcountingpublic",
params={"state": "MS", "date_start": "2025-01-01"},
timeout=60,
)
contagens = resposta.json()
with open("contagens.csv", "w", newline="", encoding="utf-8") as arquivo:
escritor = csv.DictWriter(arquivo, fieldnames=COLUNAS, extrasaction="ignore")
escritor.writeheader()
escritor.writerows(contagens)
print("Arquivo contagens.csv gerado com", len(contagens), "linhas") Daten senden
Die folgenden Beispiele verwenden die private API und erfordern einen Schlüssel. Der geografische Geltungsbereich des Schlüssels definiert, was er aufzeichnen kann – ein Gemeindeschlüssel zeichnet nur in der Gemeinde selbst auf.
/api/postcountingPrivatSenden Sie den Messwert einer vorhandenen Ovitrap
Sendet die Eizahl einer bereits registrierten Ovitrap. Die Ovitrap befindet sich am ovitrap_group_id innerhalb der Gemeinde des Schlüssels, und die epidemiologische Woche wird aus dem Feld berechnet date.
curl -X POST \
-d "ovitrap_group_id=97" \
-d "ovitrap_lat=-7.000000" \
-d "ovitrap_lng=-8.000000" \
-d "date=2025-01-20" \
-d "counting_observation_id=1" \
-d "counting_eggs=5" \
"/de-at/api/postcounting?key=SUA_CHAVE" import requests
BASE = "/de-at/api"
CHAVE = "SUA_CHAVE"
resposta = requests.post(
BASE + "/postcounting",
params={"key": CHAVE}, # a chave vai na URL
data={ # os dados vao no corpo
"ovitrap_group_id": 97,
"ovitrap_lat": -7.000000,
"ovitrap_lng": -8.000000,
"date": "2025-01-20",
"counting_observation_id": 1,
"counting_eggs": 5,
},
timeout=60,
)
print(resposta.status_code, resposta.json())
# 200 "Contagem registrada" /api/postcountingPrivatInstallieren Sie eine neue Ovitrap neben der Lesung
Wenn die ovitrap_group_id in der Gemeinde noch nicht existiert, wird die Ovitrap im selben Antrag angelegt. Senden Sie auch die Adresse und ggf. den Typ mit (ovitrap_type_id: 1 urban, Muster; 2 rural).
import requests
BASE = "/de-at/api"
CHAVE = "SUA_CHAVE"
resposta = requests.post(
BASE + "/postcounting",
params={"key": CHAVE},
data={
"ovitrap_group_id": 96,
"ovitrap_address_district": "Centro",
"ovitrap_address_street": "Rua das Flores",
"ovitrap_address_number": "123",
"ovitrap_address_complement": "",
"ovitrap_address_sector": "Setor 04",
"ovitrap_responsable": "Maria Souza",
"ovitrap_block_id": "12",
"ovitrap_type_id": 2, # 1 = urbana (padrao), 2 = rural
"ovitrap_lat": -7.000000,
"ovitrap_lng": -8.000000,
"date": "2025-01-20",
"counting_date_collect": "2025-01-27",
"counting_observation_id": 1,
"counting_eggs": 5,
},
timeout=60,
)
print(resposta.status_code, resposta.json()) 400— Mangelovitrap_lat,ovitrap_lngouovitrap_group_id.400—ovitrap_type_idverschieden von 1 oder 2.404— Für diese Ovitrap gibt es bereits eine Zählung, Jahr und Woche.500— Das gesendete Datum liegt in einer zukünftigen oder ungültigen epidemiologischen Woche.
/api/postactionPrivatMelden Sie einen Blockbesuch an
Verwenden block_id um den Besuch in einem bereits registrierten Block zu starten. Wenn der Block noch nicht existiert, senden Sie ihn block_group_id mit den Blockdaten und wird automatisch innerhalb der Schlüsselgemeinde erstellt.
import requests
BASE = "/de-at/api"
CHAVE = "SUA_CHAVE"
visita = {
"block_id": 97,
"date": "2025-01-20",
"block_land_residence": 10,
"action_land_residence_out": 2,
"action_land_residence_breedings": 1,
"action_land_residence_treated": 1,
"action_deposit_a1_quantity": 4,
"action_deposit_a1_eliminated": 2,
"action_deposit_a1_treated": 1,
"action_deposit_a1_larvicid": 10,
"action_observation": "Foco encontrado em pneus nos fundos do imovel.",
}
resposta = requests.post(
BASE + "/postaction", params={"key": CHAVE}, data=visita, timeout=60
)
if resposta.status_code == 409:
print("Ja existe visita para esse quarteirao nessa semana")
else:
print(resposta.status_code, resposta.json()) visita = {
"block_group_id": 97,
"date": "2025-01-20",
"block_address_district": "Centro Historico",
"block_address_sector": "Setor 04 - Norte",
"block_coordinates": "[[-7.123, -34.845], [-7.124, -34.846]]",
"block_lat": -7.123456,
"block_lng": -34.845678,
"block_responsable": "Joao da Silva",
"block_land_residence": 10,
"action_land_residence_out": 2,
"action_land_residence_breedings": 1,
"action_land_residence_treated": 1,
"action_observation": "Area com alta densidade de recipientes descartaveis.",
}
resposta = requests.post(
BASE + "/postaction", params={"key": CHAVE}, data=visita, timeout=60
)
print(resposta.status_code, resposta.json()) Die vollständige Liste der Immobilien- und Depotfelder (a1, a2, b, c, d1, d2, e) ist drin Endpunktreferenz. Nicht gesendete numerische Felder gehen von Null aus, aber jeder Wert, der keine Zahl ist, gibt 400 zurück.
Datensätze entfernen
Umzüge sind endgültig und immer auf die maßgebliche Gemeinde beschränkt.
# leitura de uma ovitrampa (identificada pela ovitrampa + data)
curl -X POST -d "ovitrap_group_id=97" -d "date=2025-01-20" \
"/de-at/api/postdeletecounting?key=SUA_CHAVE"
# a ovitrampa inteira
curl -X POST -d "ovitrap_group_id=97" \
"/de-at/api/postdeleteovitrap?key=SUA_CHAVE"
# visita de um quarteirao (quarteirao + data)
curl -X POST -d "block_group_id=97" -d "date=2025-01-20" \
"/de-at/api/postdeleteaction?key=SUA_CHAVE"
# o quarteirao inteiro
curl -X POST -d "block_group_id=97" \
"/de-at/api/postdeleteblock?key=SUA_CHAVE" /api/postdeletecounting und senden Sie es erneut mit /api/postcounting — Beim erneuten Senden wird ein Duplizierungsfehler zurückgegeben.Fehlerbehandlung
Der Antworttext ist immer eine JSON-Zeichenfolge mit der Nachricht. Es lohnt sich, sich mit jedem Einzelfall auseinanderzusetzen, denn nicht jeder Fehler verdient einen weiteren Versuch:
| Situation | Code | Was zu tun |
|---|---|---|
"Wrong key" | 404 | Stellen Sie sicher, dass sich der Schlüssel in der Abfragezeichenfolge und nicht im Textkörper befindet. |
| Doppelzählung | 404 | Diese Woche gibt es bereits Lesestoff für die Ovitrap; Bitte entfernen Sie es vor dem erneuten Senden. |
| Doppelter Besuch | 409 | Diese Woche gibt es bereits einen Besuch im Block. |
| Außerhalb des Gültigkeitsbereichs | 403 | Der Block gehört nicht zur Gemeinde Chave. Nicht wiederholen. |
| Fehlendes Pflichtfeld | 400 | Korrigieren Sie die Einreichung. Das Wiederholen gibt den gleichen Fehler zurück. |
| Ungültige Woche oder ungültiges Jahr | 500 | Das Datum liegt außerhalb der akzeptierten epidemiologischen Woche. Korrigieren Sie das Feld date. |
import time
import requests
NAO_REPETIR = {400, 403, 404, 409}
def enviar(url, chave, dados, tentativas=3):
for tentativa in range(tentativas):
try:
resposta = requests.post(
url, params={"key": chave}, data=dados, timeout=60
)
except requests.RequestException as erro:
print("Falha de rede:", erro)
time.sleep(5 * (tentativa + 1))
continue
if resposta.status_code in NAO_REPETIR:
print("Erro definitivo:", resposta.status_code, resposta.json())
return None
if resposta.ok:
return resposta.json()
# 500 e demais erros de servidor: espera progressiva e tenta de novo
time.sleep(5 * (tentativa + 1))
return None Gute Praktiken
- Filtern Sie nach Möglichkeit nach Gemeinde oder Bundesland – ohne Filterung durchsucht die Abfrage das gesamte Land.
- Bevorzugen Sie die inkrementelle Synchronisierung durch
idTägliches Absenken der gesamten Basis. - Senden Sie Anfragen nacheinander. Die API ist nicht für Dutzende gleichzeitiger Aufrufe pro Client ausgelegt.
- Überprüfen Sie vor der Iteration, ob es sich bei der Antwort um eine Liste handelt: Paging-Limit-Nachrichten haben den Status 200.
- Speichern Sie die
counting_idund dieblock_iderhalten – sie ermöglichen es Ihnen, Conta Ovos-Datensätze mit denen in Ihrem System abzugleichen. - Behandeln Sie die epidemiologische Woche als bestimmendes Feld: Conta Ovos akzeptiert nur eine Messung pro Ovitrap und Woche und einen Besuch pro Block und Woche.
- Folgen Sie der Seite mudanças bevor Sie Ihre Integration aktualisieren.