A Java client library for the Movebank REST API (v1).
Named mullet because Movebank is a bit dated — business in the front, party animal tracking in the back.
Gradle:
implementation 'de.firetail:mullet-rest-client:0.0.2'Maven:
<dependency>
<groupId>de.firetail</groupId>
<artifactId>mullet-rest-client</artifactId>
<version>0.0.2</version>
</dependency>MulletRestClient client = new MulletRestClient(
"https://www.movebank.org/movebank",
"your-username",
"your-password",
(LicenseChecker) html -> true // auto-accept licenses; see License Handling below
);
List<Record> studies = client.readAll(new RequestBuilderStudy());
for (Record study : studies) {
System.out.println(study.getStringValue(Constants.Attributes.ID)
+ " " + study.getStringValue(Constants.Attributes.NAME));
}Pass your Movebank username and password to the MulletRestClient constructor. Credentials are sent as HTTP headers on every request. The client maintains a session cookie automatically after the first successful response.
Each Movebank entity type has its own RequestBuilder subclass. Build a request, optionally configure filters, then pass it to the client.
| Class | Entity |
|---|---|
RequestBuilderStudy |
Studies |
RequestBuilderSensor |
Sensors (requires study ID) |
RequestBuilderTag |
Tags (requires study ID) |
RequestBuilderIndividual |
Individuals (requires study ID) |
RequestBuilderDeployment |
Deployments (requires study ID) |
RequestBuilderEvent |
Events / tracking data (requires study ID + sensor type) |
RequestBuilderStudyAttribute |
Study attributes (requires study ID + sensor type) |
RequestBuilderSensorType |
Sensor type lookup table |
All builders support optional attribute selection, sorting, and result limits:
RequestBuilderStudy request = new RequestBuilderStudy();
request.setSelectAttributes(List.of(
Constants.Attributes.ID,
Constants.Attributes.NAME
));
request.setLimit(100);Query responses are rows of CSV data. Each Record gives typed access to fields by attribute name:
record.getStringValue("name");
record.getLongValue("id");
record.getDoubleValue("location_lat");
record.getDateValue("timestamp"); // parsed as UTC
record.getBooleanValue("i_am_owner");Collect all records into a list:
List<Record> records = client.readAll(request);Stream records via callback (better for large result sets):
client.sendRequest(request, new RecordCallbackDefault() {
protected void record() throws Exception {
System.out.println(getStringValue(Constants.Attributes.TIMESTAMP));
}
});Download raw response to a stream (e.g. to save a file):
try (OutputStream out = new FileOutputStream("events.csv")) {
client.sendRequest(request, out);
}A download progress listener can be supplied as an optional third argument.
List<Record> studies = client.readAll(new RequestBuilderStudy());RequestBuilderStudy request = new RequestBuilderStudy();
request.setName("My Study");
List<Record> studies = client.readAll(request);StudyBrowser is a convenience wrapper that loads a study's metadata and builds correctly configured event requests for you:
StudyBrowser browser = new StudyBrowser("12345678", client);
// Sensor type IDs are numeric strings in Movebank.
// Use StaticDataBrowser to resolve the readable name to an ID.
StaticDataBrowser staticData = new StaticDataBrowser(client);
String gpsTypeId = staticData.getSensorTypeId(Constants.SensorTypes.GPS);
RequestBuilderEvent eventRequest = browser.getRequestBuilderEvent(
gpsTypeId,
Constants.Attributes.TIMESTAMP,
Constants.Attributes.LOCATION_LAT,
Constants.Attributes.LOCATION_LONG
);
List<Record> events = client.readAll(eventRequest);eventRequest.setIndividualId("987654");
// or
eventRequest.setTagId("111222");List<Record> tags = client.readAll(new RequestBuilderTag(studyId));
List<Record> individuals = client.readAll(new RequestBuilderIndividual(studyId));
List<Record> deployments = client.readAll(new RequestBuilderDeployment(studyId));Some Movebank studies require you to accept a license agreement before data is returned. The API signals this with an accept-license response header, and sends the license text as the response body.
The MulletRestClient constructor accepts a LicenseChecker that decides whether to accept:
// Programmatic acceptance (e.g. in batch jobs after prior review)
LicenseChecker checker = html -> true;
// Swing dialog (prompts the user interactively)
MulletRestClient client = new MulletRestClient(baseUrl, user, password, ownerFrame);If the license is declined, a LicenseException is thrown.
Both http:// and https:// base URLs are supported. The live Movebank API requires HTTPS; plain HTTP is useful when pointing the client at a local mirror such as mullet-server.
// Live Movebank (HTTPS)
MulletRestClient client = new MulletRestClient(
"https://www.movebank.org/movebank", user, password, licenseChecker);
// Local mirror (plain HTTP)
MulletRestClient client = new MulletRestClient(
"http://localhost:8080/movebank", user, password, licenseChecker);For test environments with self-signed certificates, SSL verification can be disabled:
client.disableSslChecks(); // never use in productionRequires Java 21 and Gradle (or use the included wrapper).
./gradlew buildGNU Lesser General Public License v2.1 — see LICENSE.
