Επιστροφή στο ιστολόγιο
Maven coordinates for the PolyLingo Java SDK alongside a short Java client setup snippet.

Μετάφραση δομημένου περιεχομένου από Java με το PolyLingo SDK

By Robert

Μετάφραση δομημένου περιεχομένου από Java με το PolyLingo SDK

Το PolyLingo Java SDK είναι πλέον διαθέσιμο στο Maven Central. Καλύπτει ολόκληρο το API του PolyLingo: συγχρονισμένη μετάφραση, παρτίδες αιτημάτων, ασύγχρονα έργα με polling και όλα τα βοηθητικά endpoints. Απαιτεί Java 11 ή νεότερη, χρησιμοποιεί τον HTTP client της standard βιβλιοθήκης και έχει ακριβώς μία εξάρτηση χρόνου εκτέλεσης: το Jackson για JSON.


Εγκατάσταση

Maven

<dependency>
  <groupId>com.usepolylingo</groupId>
  <artifactId>polylingo</artifactId>
  <version>0.1.0</version>
</dependency>

Gradle

implementation 'com.usepolylingo:polylingo:0.1.0'

Δεν απαιτείται επιπλέον εξάρτηση HTTP client. Το SDK χρησιμοποιεί το java.net.http.HttpClient από τη standard βιβλιοθήκη Java 11.


Ρύθμιση του client

import com.usepolylingo.polylingo.PolyLingo;

PolyLingo client = PolyLingo.builder()
    .apiKey(System.getenv("POLYLINGO_API_KEY"))
    .build();

Διατίθενται δύο προαιρετικές παράμετροι builder:

PolyLingo client = PolyLingo.builder()
    .apiKey(System.getenv("POLYLINGO_API_KEY"))
    .baseUrl("https://api.usepolylingo.com/v1") // προεπιλογή, παρακαμφθείτε για self-hosted περιπτώσεις
    .timeout(Duration.ofSeconds(30))            // προεπιλογή είναι 120 δευτερόλεπτα
    .build();

Κρατήστε το API key σας σε μεταβλητή περιβάλλοντος. Μην το σκληροκωδικοποιείτε ή δεσμεύετε σε version control.

Το SDK χρησιμοποιεί το builder pattern παντού. Χωρίς constructors με θέσεις, χωρίς υποχρεωτική σειρά πεδίων. Όλα τα προαιρετικά πεδία έχουν λογικές προεπιλογές ώστε να ρυθμίζετε μόνο ό,τι χρειάζεται να αλλάξετε.


Μετάφραση περιεχομένου

Μονή αίτηση

import com.usepolylingo.polylingo.types.TranslateParams;
import com.usepolylingo.polylingo.types.TranslateResult;

TranslateResult result = client.translate(
    TranslateParams.builder()
        .content("Hello, world!")
        .targets(List.of("es", "fr", "de"))
        .build()
);

result.getTranslations().forEach((lang, text) ->
    System.out.println(lang + ": " + text)
);
// es: ¡Hola, mundo!
// fr: Bonjour le monde !
// de: Hallo Welt!

Ο builder TranslateParams δέχεται τα content και targets ως υποχρεωτικά πεδία. Προαιρετικές παράμετροι περιλαμβάνουν το format (plain, markdown, json ή html — αν παραλειφθεί ανιχνεύεται αυτόματα), source ως υπόδειξη γλώσσας και model είτε standard (προεπιλογή) είτε advanced.

Η διατήρηση μορφοποίησης λειτουργεί όπως και στο υπόλοιπο API του PolyLingo. Για περιεχόμενο json, μεταφράζονται μόνο οι τιμές string και τα κλειδιά, η εμφωλευμένη δομή και οι μη-string τύποι παραμένουν ανέπαφοι. Για markdown, οι επικεφαλίδες παραμένουν επικεφαλίδες και τα blocks κώδικα παραμένουν αυτούσια. Για html, οι ετικέτες και τα attributes διατηρούνται και μεταφράζονται μόνο οι κόμβοι κειμένου.

Μετάφραση αρχείου JSON τοπικής γλώσσας

import com.fasterxml.jackson.databind.ObjectMapper;
import java.nio.file.Files;
import java.nio.file.Path;

ObjectMapper mapper = new ObjectMapper();
String sourceJson = Files.readString(Path.of("messages/en.json"));

TranslateResult result = client.translate(
    TranslateParams.builder()
        .content(sourceJson)
        .format("json")
        .targets(List.of("fr", "de", "ja"))
        .build()
);

result.getTranslations().forEach((locale, translated) -> {
    try {
        Object parsed = mapper.readValue(translated, Object.class);
        String pretty = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(parsed);
        Files.writeString(Path.of("messages/" + locale + ".json"), pretty);
        System.out.println("Wrote messages/" + locale + ".json");
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
});

Μία αίτηση χειρίζεται και τις τρεις τοπικές γλώσσες. Τα κλειδιά είναι ίδια με την πηγή σε κάθε αρχείο εξόδου.


Αιτήσεις παρτίδας

Στείλτε έως 100 αντικείμενα περιεχομένου σε μία αίτηση, το καθένα με το δικό του id και προαιρετικό format:

import com.usepolylingo.polylingo.types.BatchParams;
import com.usepolylingo.polylingo.types.BatchItem;
import com.usepolylingo.polylingo.types.BatchResult;

BatchResult result = client.batch(
    BatchParams.builder()
        .targets(List.of("es", "ja"))
        .addItem(BatchItem.builder().id("title").content("Welcome").build())
        .addItem(BatchItem.builder().id("body").content("Get started today.").build())
        .build()
);

for (BatchItemResult item : result.getResults()) {
    System.out.println(item.getId() + ": " + item.getTranslations());
}

Όλα τα αντικείμενα μοιράζονται την ίδια λίστα targets. Το id που ορίζετε διατηρείται στην απάντηση ώστε να μπορείτε να αντιστοιχίσετε τα αποτελέσματα πίσω στα δεδομένα πηγής χωρίς να βασίζεστε στη σειρά.


Ασύγχρονα έργα

Για μεγάλα έγγραφα ή μεγάλα φορτία μετάφρασης, το API των jobs δέχεται αίτηση, επιστρέφει αμέσως με ένα job ID και σας επιτρέπει να κάνετε polling για το αποτέλεσμα. Το SDK το χειρίζεται με δύο τρόπους.

Μία κλήση που κάνει polling μέχρι να ολοκληρωθεί

import com.usepolylingo.polylingo.types.JobsTranslateParams;

TranslateResult result = client.jobs().translate(
    JobsTranslateParams.builder()
        .content(longArticleText)
        .targets(List.of("fr", "de", "ja", "zh"))
        .pollInterval(Duration.ofSeconds(3))
        .timeout(Duration.ofMinutes(10))
        .onProgress(queuePosition ->
            System.out.println("Queue position: " + queuePosition))
        .build()
);

result.getTranslations().forEach((lang, text) ->
    System.out.println(lang + ": " + text.substring(0, 100) + "...")
);

Η συνάρτηση onProgress καλείται σε κάθε polling με τη θέση στην ουρά ως ακέραιο ή null αν το API δεν επιστρέφει τέτοια τιμή. Χρησιμοποιήστε την για να καταγράψετε την πρόοδο ή να ενημερώσετε UI.

Εγγραφή και polling χειροκίνητα

import com.usepolylingo.polylingo.types.CreateJobParams;
import com.usepolylingo.polylingo.types.Job;

Job job = client.jobs().create(
    CreateJobParams.builder()
        .content("Translate this.")
        .targets(List.of("es"))
        .build()
);

// Κάντε polling μόνοι σας
Job status = client.jobs().get(job.getJobId());
System.out.println(status.getStatus()); // pending / processing / completed / failed

Βοηθητικά endpoints

// Έλεγχος υγείας API (δεν απαιτείται API key)
HealthResponse health = client.health();
System.out.println(health.getStatus()); // "ok"

// Λίστα υποστηριζόμενων γλωσσών (δεν απαιτείται API key)
LanguagesResponse langs = client.languages();
langs.getLanguages().forEach(l ->
    System.out.println(l.getCode() + " — " + l.getName())
);

// Έλεγχος χρήσης tokens για τον τρέχοντα μήνα χρέωσης
UsageResponse usage = client.usage();
System.out.println("Tokens used: " + usage.getUsage().getTokensUsed());
System.out.println("Tokens remaining: " + usage.getUsage().getTokensRemaining());

Διαχείριση σφαλμάτων

Όλες οι εξαιρέσεις είναι unchecked. Χωρίς υποχρεωτικές δηλώσεις throws, χωρίς αλυσιδωτές checked exceptions για ξεδίπλωμα:

import com.usepolylingo.polylingo.errors.*;

try {
    TranslateResult result = client.translate(
        TranslateParams.builder()
            .content("# Hello")
            .targets(List.of("es", "fr"))
            .format("markdown")
            .build()
    );
} catch (AuthException e) {
    // HTTP 401 — άκυρο, λείπει ή ανακληθέν API key
    System.out.println("Auth failed: " + e.getError());
} catch (RateLimitException e) {
    // HTTP 429 — όριο ανά λεπτό επιτεύχθηκε
    e.getRetryAfter().ifPresent(s ->
        System.out.println("Retry after: " + s + "s")
    );
} catch (JobFailedException e) {
    // Ασύγχρονο job έφτασε σε αποτυχημένη τελική κατάσταση ή το polling έληξε
    System.out.println("Job " + e.getJobId() + " failed: " + e.getError());
} catch (PolyLingoException e) {
    // Όλα τα άλλα σφάλματα API
    System.out.println(e.getStatus() + ": " + e.getMessage());
}

Το RateLimitException.getRetryAfter() επιστρέφει Optional<Integer> — παρόν με τον αριθμό δευτερολέπτων αναμονής αν το API το περιλαμβάνει, κενό αλλιώς. Το JobFailedException.getJobId() δίνει το ID του αποτυχημένου job για καταγραφή ή λογική επανάληψης.


Σημειώσεις σχεδιασμού

Μερικές αποφάσεις που αξίζει να γνωρίζετε αν αξιολογείτε το SDK:

Συγχρονισμένο API. Κάθε μέθοδος μπλοκάρει και επιστρέφει απευθείας αποτέλεσμα. Χωρίς Future, χωρίς CompletableFuture, χωρίς reactive streams. Το polling των jobs είναι η ασύγχρονη λύση του SDK για βαριά φορτία — υποβάλετε το job, το SDK κάνει polling στο νήμα σας και καλεί το callback onProgress καθώς ενημερώνεται η θέση στην ουρά.

Builder pattern παντού. Κάθε αντικείμενο παραμέτρων χρησιμοποιεί builder. Χωρίς constructors με θέσεις σημαίνει χωρίς εικασίες για τη σειρά των ορισμάτων, χωρίς τυχαίες ανταλλαγές πεδίων και καθαρό κώδικα στο σημείο κλήσης.

Μία εξάρτηση χρόνου εκτέλεσης. Jackson για σειριοποίηση JSON. Όλα τα άλλα είναι standard library. Χωρίς OkHttp, χωρίς Apache HttpClient, χωρίς Guava.

Java 11+. Χρησιμοποιεί java.net.http.HttpClient που εισήχθη στην Java 11. Αν το έργο σας στοχεύει Java 8 ή παλαιότερη, το SDK δεν είναι συμβατό.


Γρήγορη αναφορά

ΜέθοδοςEndpointΑπαιτεί Auth
client.health()GET /healthΌχι
client.languages()GET /languagesΌχι
client.translate(...)POST /translateΝαι
client.batch(...)POST /translate/batchΝαι
client.usage()GET /usageΝαι
client.jobs().create(...)POST /jobsΝαι
client.jobs().get(jobId)GET /jobs/:idΝαι
client.jobs().translate(...)POST /jobs + pollingΝαι

Ξεκινήστε

Το SDK είναι στο Maven Central στο central.sonatype.com/artifact/com.usepolylingo/polylingo. Ο πηγαίος κώδικας και το Javadoc είναι στο github.com/UsePolyLingo/polylingo-Java. Η πλήρης τεκμηρίωση API είναι στο usepolylingo.com/docs/sdk/java.

Το δωρεάν επίπεδο περιλαμβάνει 50.000 tokens ανά μήνα. Δεν απαιτείται πιστωτική κάρτα.

<dependency>
  <groupId>com.usepolylingo</groupId>
  <artifactId>polylingo</artifactId>
  <version>0.1.0</version>
</dependency>

Αποκτήστε το API key σας