SDK Ruby de conversion de fichiers#
enconvert est la gem Ruby officielle de l'API EnConvert. Elle convertit des URL, des images et des documents à travers 43 endpoints de conversion implémentés, et expose un second espace de noms, client.v2, qui lit des pages web en direct sous forme de Markdown, de JSON, de captures d'écran et de PDF prêts pour un agent. Chaque lecture V2 porte un score render_quality, si bien qu'une page bloquée ou une coquille SPA vide ne passe jamais pour du vrai contenu. La gem cible Ruby 3.0+ et n'a aucune dépendance à l'exécution : elle s'appuie sur net/http, json et securerandom de la bibliothèque standard. Les réponses reviennent sous forme de Structs avec des accesseurs en snake_case.
enconvert · Source : conversionapi/ruby-sdk · Ruby : 3.0.0 ou plus récent · Dépendances à l'exécution : aucune
Installation#
gem install enconvert
Ou ajoutez-la à votre Gemfile :
gem "enconvert"
bundle install
Démarrage rapide#
require "enconvert"
client = Enconvert::Client.new(api_key: ENV.fetch("ENCONVERT_API_KEY"))
# Convertir une page en direct en PDF et l'écrire sur le disque.
result = client.convert_url_to_pdf("https://example.com", save_to: "page.pdf")
puts result.presigned_url
# Lire la même page comme un agent devrait le faire, avec un score de qualité attaché.
op = client.v2.perceive("https://example.com", outputs: %w[markdown structured])
puts op.outputs["markdown"].url, op.render_quality # par ex. 0.93
La gem est côté serveur uniquement. Votre clé API privée doit rester sur le serveur : lisez-la depuis une variable d'environnement ou un gestionnaire de secrets, et ne la livrez jamais à un navigateur ni à un binaire mobile.
Ce que le client expose#
Enconvert::Client porte directement la surface de conversion de fichiers, et toute la surface de web intelligence est accrochée à client.v2.
| Groupe | Méthodes | Renvoie |
|---|---|---|
| URL unique | convert_url_to_pdf, convert_url_to_screenshot, convert_url_to_markdown |
ConversionResult |
| Fichier envoyé | convert_image, convert_document, convert_to_markdown, convert_to_pdf |
ConversionResult |
| Lot sur un site entier | convert_website_to_pdf, convert_website_to_screenshot |
BatchSubmission |
| Statut et interrogation | get_job_status, get_batch_status, wait_for_batch |
JobStatus, BatchStatus |
| Web intelligence | client.v2.*, 23 méthodes réparties sur six capacités |
Structs V2 |
| Aides sur les formats | Enconvert.valid_outputs_for, Enconvert::IMPLEMENTED_CONVERSIONS |
Array, Set |
Chaque type de réponse est un Struct créé avec keyword_init: true : vous lisez donc les champs comme de simples méthodes, par exemple result.presigned_url, op.render_quality, job.total_chunks.
Conversion de fichiers#
convert_url_to_pdf#
Rend n'importe quelle URL publique en PDF.
result = client.convert_url_to_pdf(
"https://example.com",
single_page: false,
pdf_options: { page_size: "A4", orientation: "landscape" },
viewport_width: 1440,
save_to: "report.pdf"
)
puts result.filename, result.file_size
| Option | Type | Par défaut | Description |
|---|---|---|---|
save_to |
String |
nil |
Chemin local vers lequel télécharger le PDF. Les répertoires parents sont créés pour vous. |
single_page |
Boolean |
true |
true produit une seule page continue. false pagine en utilisant pdf_options[:page_size]. |
pdf_options |
Hash |
nil |
Géométrie de page. Voir Options PDF. |
viewport_width |
Integer |
1920 |
Largeur de la fenêtre d'affichage du navigateur, en pixels. |
viewport_height |
Integer |
1080 |
Hauteur de la fenêtre d'affichage du navigateur, en pixels. |
load_media |
Boolean |
true |
Attend les images et les vidéos avant la capture. |
enable_scroll |
Boolean |
true |
Fait défiler la page de haut en bas pour déclencher les chargements différés. |
output_filename |
String |
nil |
Remplace le nom de fichier généré. |
auth |
Hash |
nil |
Identifiants HTTP basic, par exemple { username: "user", password: "pass" }. |
cookies, headers |
Array, Hash |
nil |
Cookies à définir et en-têtes de requête supplémentaires. Les trois champs d'accès navigateur sont transmis sans modification. |
auth avec un en-tête Authorization. L'API rejette ce conflit, choisissez donc l'un ou l'autre.
convert_url_to_screenshot#
Capture un PNG pleine page de n'importe quelle URL.
client.convert_url_to_screenshot("https://example.com", viewport_width: 1440, save_to: "shot.png")
Accepte les mêmes options de fenêtre d'affichage, de médias, de défilement, de nom de fichier et d'accès navigateur que convert_url_to_pdf. Elle ne prend pas single_page ni pdf_options.
convert_url_to_markdown#
Extrait du Markdown GitHub-Flavored propre depuis n'importe quelle URL. Le convertisseur supprime la navigation, les pieds de page, les publicités et les scripts, conserve le corps principal de l'article, et ajoute en tête un frontmatter YAML avec le titre, la description, l'url, les liens et les images.
client.convert_url_to_markdown("https://example.com/article", save_to: "article.md")
Utile pour alimenter un pipeline RAG, importer du contenu tiers dans un CMS, ou constituer un corpus d'entraînement.
convert_image#
Convertit entre jpeg, png, svg, heic et webp dans n'importe quel sens, ou rastérise un PDF en JPEG.
# Depuis un chemin sur le disque.
client.convert_image("photo.heic", output_format: "webp", save_to: "photo.webp")
# Depuis des octets que vous détenez déjà.
bytes = File.binread("photo.heic")
client.convert_image({ data: bytes, filename: "photo.heic" }, output_format: "webp", save_to: "photo.webp")
# Rastériser la première page d'un PDF.
client.convert_image("invoice.pdf", output_format: "jpeg", save_to: "invoice.jpg")
Le format d'entrée est déduit de l'extension du nom de fichier : un IO brut sans nom de fichier ne peut donc pas être utilisé ici. Passez plutôt un chemin ou un Hash { data:, filename: }.
| Option | Type | Requis | Description |
|---|---|---|---|
output_format |
String |
Oui | Format cible. Les alias jpg, yml, htm et md sont normalisés pour vous. |
save_to |
String |
Non | Chemin local vers lequel télécharger le résultat. |
output_filename |
String |
Non | Remplace le nom de fichier généré. |
convert_document#
Convertit des documents et des formats de données. output_format vaut "pdf" par défaut.
# docx vers pdf
client.convert_document("report.docx", save_to: "report.pdf")
# json vers yaml
client.convert_document("data.json", output_format: "yaml", save_to: "data.yaml")
# markdown vers pdf avec une mise en page personnalisée
client.convert_document(
"README.md",
output_format: "pdf",
pdf_options: { page_size: "A4", margins: { top: 20, bottom: 20, left: 25, right: 25 } },
save_to: "readme.pdf"
)
Extensions d'entrée reconnues : .doc, .docx, .xls, .xlsx, .ppt, .pptx, .html, .htm, .odt, .ods, .odp, .ots, .pages, .numbers, .md, .markdown, .csv, .json, .xml, .yaml, .yml, .toml.
L'EPUB n'a pas de paire de conversion documentaire dédiée. Faites plutôt passer les fichiers .epub par convert_to_pdf ou convert_to_markdown.
| Option | Type | Par défaut | Description |
|---|---|---|---|
output_format |
String |
"pdf" |
Format cible. |
save_to |
String |
nil |
Chemin local vers lequel télécharger le résultat. |
output_filename |
String |
nil |
Remplace le nom de fichier généré. |
pdf_options |
Hash |
nil |
Mise en page, prise en compte lorsque la sortie est un PDF. |
convert_to_markdown#
Convertit en Markdown propre un fichier envoyé, dans presque n'importe quel format de document. Le format est détecté sur le serveur.
client.convert_to_markdown("handbook.docx", save_to: "handbook.md")
Entrées acceptées : PDF, DOCX, PPTX, XLSX, CSV, HTML, EPUB, TXT et MD, ainsi que les formats bureautiques hérités et ODF. Les images ne sont pas prises en charge sur cet endpoint.
La sortie est un unique fichier .md qui respecte la hiérarchie des titres, ce qui en fait une bonne brique pour l'ingestion RAG : un découpeur sémantique peut segmenter sur la hiérarchie de titres du document plutôt que sur un nombre de caractères arbitraire. Les seules options sont save_to: et output_filename:.
convert_to_pdf#
Convertit en PDF un fichier envoyé, dans presque n'importe quel format.
# pptx vers pdf
client.convert_to_pdf("slides.pptx", save_to: "slides.pdf")
# pdf transmis tel quel, normalisé en niveaux de gris
client.convert_to_pdf("scan.pdf", pdf_options: { grayscale: true }, save_to: "gray.pdf")
Entrées acceptées : formats bureautiques, ODF, Pages, Numbers, RTF, CSV, HTML, Markdown, texte brut, images matricielles, SVG, EPUB, ou un PDF existant qui est transmis tel quel et normalisé.
pdf_options[:grayscale] est pris en compte ici. Les autres champs de géométrie de page sont ignorés sur cet endpoint. Lorsque vous avez besoin d'un contrôle complet sur la taille de page, l'orientation et les marges, utilisez convert_document ou convert_url_to_pdf.
Les options sont save_to:, output_filename: et pdf_options: (niveaux de gris uniquement).
convert_website_to_pdf et convert_website_to_screenshot#
Découvrent chaque page d'un site web, convertissent chacune d'elles en arrière-plan, et rassemblent les résultats dans une seule archive ZIP. Les deux méthodes sont asynchrones et renvoient immédiatement un BatchSubmission.
batch = client.convert_website_to_pdf(
"https://example.com",
crawl_mode: "sitemap",
exclude_patterns: ["/tag/"],
notification_email: "[email protected]"
)
status = client.wait_for_batch(batch.batch_id, save_to: "site.zip")
puts "#{status.completed} of #{status.total} pages converted"
status.items.each { |item| puts "#{item.status}\t#{item.source_url}" }
convert_website_to_screenshot fonctionne à l'identique et produit un ZIP de PNG.
| Option | Type | Description |
|---|---|---|
crawl_mode |
String |
Manière dont les pages sont découvertes, par exemple "sitemap". |
include_patterns, exclude_patterns |
Array |
Ne crawler, ou au contraire ignorer, que les URL correspondant à ces motifs. |
notification_email |
String |
Adresse e-mail à prévenir à la fin du lot. |
callback_url |
String |
Webhook appelé à la fin du traitement. |
output_filename |
String |
Remplace le nom de fichier ZIP généré. |
viewport_width, viewport_height, load_media, enable_scroll |
Integer, Boolean |
Comportement de rendu par page. Envoyé uniquement si vous le définissez, sinon la passerelle applique ses propres valeurs par défaut. |
auth, cookies, headers |
Hash, Array, Hash |
Accès navigateur pour les pages protégées. |
single_page, pdf_options |
Boolean, Hash |
Lots PDF uniquement. |
wait_for_batch(batch_id, interval: 5, timeout: 1800, save_to: nil) interroge jusqu'à ce que le lot quitte l'état "processing", puis renvoie le BatchStatus final. Avec save_to, elle télécharge aussi le ZIP. Elle lève Enconvert::APIError avec le statut 504 quand le délai est atteint, et le statut 500 quand un lot se termine sans ZIP à enregistrer.
get_job_status#
Interroge un job de conversion unique par son identifiant.
status = client.get_job_status("job_abc123")
case status.status
when "success" then puts status.presigned_url
when "failed" then warn status.error
else puts "still processing"
end
Renvoie un JobStatus avec status, presigned_url, object_key et error. Vous avez rarement besoin de l'appeler vous-même, puisque le SDK l'interroge déjà pour vous. Voir Récupération des timeouts.
Conversions prises en charge#
La gem embarque le tableau complet des endpoints {input}-to-{output} implémentés et valide chaque paire localement : une paire non prise en charge lève donc Enconvert::Error avant qu'aucune requête ne quitte votre processus.
Enconvert.valid_outputs_for("json") # => ["csv", "toml", "xml", "yaml"]
Enconvert.valid_outputs_for("pdf") # => ["jpeg"]
Enconvert::IMPLEMENTED_CONVERSIONS.size # => 43
| Entrée | Sorties |
|---|---|
json |
csv, toml, xml, yaml |
xml |
csv, json |
yaml |
json |
csv |
json, xml |
toml |
json |
markdown |
html, pdf |
html |
pdf |
doc, excel, ppt, odt, ods, odp, ots, pages, numbers |
pdf |
jpeg, png, svg, heic, webp |
les uns vers les autres, les 20 paires |
pdf |
jpeg |
Cela fait 43 endpoints : 13 conversions de texte structuré, 9 conversions de documents et 21 conversions d'images.
Web intelligence (V2)#
client.v2 transforme des pages web en direct en données prêtes pour un agent : rendre, énumérer, rechercher, extraire, ingérer et surveiller. Chaque rendu porte render_quality, un score de 0.0 à 1.0 attaché à chaque lecture. Un score bas signifie que la page ne s'est pas rendue proprement, typiquement une page de challenge, un mur de cookies, une barrière de connexion ou une coquille JavaScript vide. Le contenu est tout de même renvoyé, mais signalé, avec un tableau warnings et un Hash deductions qui indique quels contrôles se sont déclenchés. Lisez le score avant de placer le contenu où que ce soit, et une mauvaise lecture n'entrera jamais silencieusement dans le contexte de votre agent.
Tous les endpoints V2 exigent une clé API privée. Voir la vue d'ensemble V2 pour la référence au niveau des endpoints.
Perceive#
Rend une URL vers les artefacts que vous demandez. perceive est synchrone et renvoie l'opération terminée avec des URL d'artefacts fraîchement signées.
op = client.v2.perceive(
"https://example.com",
outputs: %w[markdown screenshot structured],
extract: %w[tables metadata],
only_main_content: true
)
puts op.operation_id, op.render_quality # "per_...", puis de 0.0 à 1.0
puts op.outputs["markdown"].url # URL d'artefact signée
puts op.outputs["markdown"].expires_in # secondes avant qu'elle cesse de fonctionner
puts op.structured, op.warnings.inspect # Hash Ruby simple, puis Array de String
Resignez à tout moment les URL d'artefacts d'une opération antérieure :
again = client.v2.get_perceive_operation(op.operation_id)
Percevez jusqu'à 1000 URL avec un seul bloc d'options partagé. Les petits lots s'exécutent en ligne et reviennent terminés. Les plus gros reviennent avec le statut "queued", il faut donc les interroger par job_id :
batch = client.v2.perceive_batch(
["https://a.example.com", "https://b.example.com"],
outputs: %w[markdown],
output_mode: "zip"
)
done = client.v2.get_perceive_batch(batch.job_id)
puts "#{done.completed}/#{done.total} complete, #{done.failed} failed"
puts done.zip&.url
Évitez complètement l'aller-retour par URL signée avec perceive_direct, où le corps de la réponse HTTP est l'artefact lui-même :
direct = client.v2.perceive_direct("https://example.com", outputs: %w[markdown])
puts direct.filename, direct.content_type, direct.content.bytesize
File.binwrite("page.md", direct.content)
# Retélécharger un artefact stocké d'une opération antérieure.
raw = client.v2.download_perceive_artifact(op.operation_id, output: "markdown")
perceive_direct a besoin d'exactement une sortie produisant un artefact et lève sinon Enconvert::Error localement. structured peut accompagner la demande, car il reste en ligne côté serveur et n'est jamais diffusé. download_perceive_artifact prend un output: facultatif, que vous pouvez omettre lorsque l'opération n'a produit qu'un seul artefact et que vous devez nommer lorsqu'elle en a produit plusieurs, et elle renvoie 410 une fois l'artefact sorti de sa fenêtre de rétention.
| Option | Type | Description |
|---|---|---|
outputs |
Array |
Une valeur parmi markdown, html_cleaned, html_raw, screenshot, screenshot_full_page, pdf, links, images, structured. Vaut ["markdown", "structured"] par défaut côté serveur. |
extract |
Array |
Une valeur parmi tables, prices, contacts, metadata, main_content, headings, structured_data, technologies, all. |
schema |
Hash |
Descriptions de champs pour l'extraction structurée. |
wait_for, wait_timeout_ms |
String, Integer |
Sélecteur CSS à attendre avant la capture, et plafond de cette attente. |
js_code |
String |
JavaScript à exécuter dans la page avant la capture. |
viewport, mobile |
Hash, Boolean |
Dimensions de la fenêtre d'affichage, et rendu ou non avec un profil mobile. |
headers, cookies, auth |
Hash, Array, Hash |
Accès navigateur pour les pages protégées. |
proxy_url |
String |
Fait passer le rendu par votre propre proxy. |
geolocation |
Hash |
Géolocalisation simulée pour le contexte navigateur. |
action_chain |
Array |
Clics, défilements et saisies scriptés avant la capture. |
cache_mode |
String |
enabled, bypass ou refresh. |
pdf_options |
Hash |
Géométrie de page lorsque pdf figure parmi les sorties. |
block_resources |
Array |
Types de ressources à bloquer, par exemple image, font, script. |
respect_robots |
Boolean |
Respecte robots.txt. |
only_main_content |
Boolean |
Supprime la navigation et l'habillage de la sortie Markdown. |
direct_download |
Boolean |
Accepté par perceive uniquement. perceive_batch le rejette. |
La sémantique complète des paramètres est détaillée dans Perceive et Paramètres et options.
Discover#
Énumère les URL d'un site sans rien rendre. Aucun navigateur n'intervient, c'est donc rapide et peu coûteux.
found = client.v2.discover(
"https://example.com",
mode: "hybrid", # "sitemap", "crawl" ou "hybrid"
max_urls: 200,
max_depth: 3,
exclude_patterns: ["/tag/"],
same_domain_only: true,
respect_robots: true
)
puts found.total, found.urls.first(10)
puts found.truncated # true quand max_urls a plafonné le résultat
puts found.sources.inspect # d'où vient chaque URL
Voir Discover pour le comportement mode par mode.
Lookup#
Lance une recherche web catégorisée, et perçoit éventuellement les meilleurs résultats dans le même appel.
search = client.v2.lookup(
"best static site generators",
category: "web", # web, news, images, scholar, patents, maps
num_results: 10,
time_filter: "month", # hour, day, week, month, year
perceive_top: 3
)
search.results.each do |hit|
puts hit.position, hit.title, hit.url
puts hit.perceive&.render_quality # présent pour les résultats perçus automatiquement
end
puts search.answer_box.inspect, search.knowledge_graph.inspect
Avec perceive_top: 3, les trois premières URL de résultats sont rendues et portent un PerceiveResult complet en ligne sur hit.perceive. Leurs identifiants d'opération sont également rassemblés dans search.perceive_operation_ids. Plus de détails dans Lookup.
Distill#
Extraction structurée pilotée par schéma. Fournissez exactement l'un de urls: ou discover_from:, et schema: est toujours obligatoire. Le SDK lève Enconvert::Error localement si vous vous trompez.
extraction = client.v2.distill(
urls: ["https://example.com/pricing"],
schema: { plans: "list of plan names with monthly prices" },
css_schema: {
base_selector: ".plan-card",
fields: [
{ name: "name", type: "text", selector: "h3" },
{ name: "price", type: "text", selector: ".price" }
]
}
)
item = extraction.results.first
puts item.data.inspect
puts item.extraction_tier # "css", "llm", "mixed" ou "none"
puts item.fields_from_css, item.fields_from_llm
Le css_schema facultatif s'exécute en premier et répond à tout ce qu'il peut à partir des seuls sélecteurs. Seuls les champs qu'il manque escaladent vers le niveau modèle de langage, ce qui explique pourquoi fields_from_css et fields_from_llm sont rapportés séparément.
Découvrir et distiller en un seul appel :
client.v2.distill(
discover_from: { url: "https://example.com", mode: "sitemap", max_pages: 10 },
schema: { title: "page title", summary: "one-line summary" }
)
Les types de champs CSS sont text, attribute, html, regex, nested, list et nested_list. Les listes de champs imbriquées sont sérialisées récursivement. Voir Distill.
Ingest#
Transforme un site entier, ou un ensemble de documents envoyés, en JSONL découpé et prêt pour le RAG, à travers un seul pipeline. Ingest est toujours asynchrone.
job = client.v2.ingest(
mode: "sitemap", # urls, sitemap, crawl
url: "https://docs.example.com",
max_pages: 100,
chunk: { max_words: 512, sentence_overlap: 1 },
webhook_url: "https://my.app/hooks/enconvert"
)
status = client.v2.get_ingest_job(job.job_id)
puts status.status # queued, discovering, processing, completed, failed, canceled
puts status.pages_processed, status.total_chunks
puts status.output_url if status.status == "completed" # JSONL
Le mode "urls" prend une liste urls: et rejette url:. Tous les autres modes prennent une url: de départ et rejettent urls:. Les deux règles sont appliquées localement avant l'envoi de la requête.
Envoyer des fichiers plutôt que crawler :
file_job = client.v2.ingest_files(
["handbook.pdf", "notes.docx"],
chunk: { max_words: 512, sentence_overlap: 1 }
)
ingest_files accepte les formats PDF, DOCX, PPTX, XLSX, CSV, HTML, EPUB, TXT et MD, ainsi que les formats bureautiques hérités et ODF. Chaque entrée peut être un chemin, un objet de type IO, ou un Hash { data:, filename: }.
Gérer les jobs et la livraison des webhooks :
list = client.v2.list_ingest_jobs(limit: 20)
list.jobs.each { |j| puts "#{j.job_id}\t#{j.status}\t#{j.total_chunks}" }
puts list.has_more
client.v2.cancel_ingest_job(job.job_id) # idempotent
secret = client.v2.get_webhook_secret
puts secret.secret, secret.signature_header, secret.timestamp_header,
secret.signature_scheme, secret.replay_tolerance_seconds
client.v2.rotate_webhook_secret # les anciennes signatures cessent aussitôt d'être valides
client.v2.retry_ingest_webhook(job.job_id) # relivrer le webhook d'un job terminé
retry_ingest_webhook renvoie un WebhookRetryResult avec delivered, attempts, status_code et detail. Elle répond 409 lorsque le job n'est pas terminé et 400 lorsque le job n'a aucun webhook configuré. Voir Ingest.
Watch#
Refait le rendu d'une URL à intervalle fixe et vous prévient quand elle change.
watcher = client.v2.create_watcher(
"https://example.com/pricing",
frequency_minutes: 60, # plancher horaire
diff_mode: "auto", # auto, text, structured, tables, metadata
webhook_url: "https://my.app/hooks/changes",
notify_email: true
)
puts watcher.watcher_id, watcher.next_check_at
history = client.v2.get_watcher_snapshots(watcher.watcher_id, limit: 10)
history.snapshots.each do |snap|
puts snap.checked_at, snap.has_changes, snap.similarity, snap.change_count, snap.changes.inspect
end
client.v2.list_watchers(limit: 20)
client.v2.get_watcher(watcher.watcher_id)
client.v2.update_watcher(watcher.watcher_id, status: "paused")
client.v2.update_watcher(watcher.watcher_id, webhook_url: "") # efface le webhook
client.v2.delete_watcher(watcher.watcher_id) # suppression logique, idempotente
update_watcher lève Enconvert::Error si vous l'appelez sans aucun champ à mettre à jour. delete_watcher renvoie le watcher marqué avec le statut "deleted", et un watcher supprimé se relit en 404. Sémantique complète dans Watch.
Options PDF#
pdf_options est un simple Hash à clés symboles, accepté par convert_url_to_pdf, convert_website_to_pdf, convert_document, convert_to_pdf (niveaux de gris uniquement), et client.v2.perceive lorsque pdf figure parmi les sorties. Seules les clés que vous définissez sont envoyées sur le réseau.
client.convert_url_to_pdf(
"https://example.com",
pdf_options: { page_size: "A4", orientation: "landscape", scale: 0.9,
margins: { top: 10, bottom: 10, left: 15, right: 15 } },
save_to: "report.pdf"
)
| Clé | Type | Description |
|---|---|---|
page_size |
String |
"A4", "A3", "Letter", "Legal", et similaires. |
page_width |
Number |
Largeur de page explicite, comme alternative à page_size. |
page_height |
Number |
Hauteur de page explicite. |
orientation |
String |
"portrait" ou "landscape". |
margins |
Hash |
{ top:, bottom:, left:, right: }, tous facultatifs. |
scale |
Number |
Échelle de rendu, par exemple 0.9 pour 90 pour cent. |
grayscale |
Boolean |
Post-traite le PDF en niveaux de gris. |
header |
Hash |
Texte d'en-tête par zone de page. |
footer |
Hash |
Texte de pied de page par zone de page. |
Gestion des erreurs#
Chaque échec est une Enconvert::Error ou l'une de ses sous-classes : vos clauses rescue peuvent donc être aussi larges ou aussi étroites que vous le souhaitez. Les échecs de validation côté client, comme une paire de conversion non prise en charge ou un schema manquant, lèvent la classe de base Enconvert::Error avant qu'aucune requête HTTP ne soit émise.
begin
client.v2.perceive("https://example.com")
rescue Enconvert::AuthenticationError
warn "Invalid or missing API key"
rescue Enconvert::QuotaError
warn "Request was rejected with 402"
rescue Enconvert::RateLimitError
warn "Too many requests, back off and retry"
rescue Enconvert::APIError => e
warn "API error [#{e.status_code}]: #{e.message}"
rescue Enconvert::Error => e
warn "Client-side validation failed: #{e.message}"
end
| Classe | Déclenchée sur | Code de statut |
|---|---|---|
Enconvert::AuthenticationError |
Clé API invalide, manquante ou révoquée | 401, 403 |
Enconvert::QuotaError |
Déclenchée sur un HTTP 402 | 402 |
Enconvert::RateLimitError |
Trop de requêtes | 429 |
Enconvert::APIError |
Toute autre réponse de 400 ou plus | le code réel |
Enconvert::Error |
Classe de base, plus tous les échecs de validation locale | aucun |
APIError#status_code vous donne le statut HTTP, et le message est extrait du champ detail ou error du corps de la réponse lorsque celui-ci est en JSON. La table complète des messages se trouve dans Codes d'erreur.
Récupération des timeouts#
Un rendu URL-vers-PDF long ou une conversion de document volumineux peut survivre au timeout du reverse proxy même quand la conversion elle-même réussit sur le serveur. Le SDK s'en remet de façon transparente, sans aucun code de votre côté.
- Avant chaque requête de conversion, le client génère un identifiant de job de 32 caractères et l'envoie comme
job_iddans le corps ou dans le formulaire multipart. - Si la requête revient avec un statut de 500 ou plus, le client bascule vers le polling de
GET /v1/convert/status/{job_id}toutes les 3 secondes. Un404obtenu pendant que la ligne du job s'écrit encore est ignoré, et l'interrogation continue. - Dès que le job affiche
success, le résultat est renvoyé. Dès qu'il affichefailed,Enconvert::APIErrorest levée avec le statut500et le message d'erreur du serveur. - Le délai maximal de polling est de 300 secondes. Au-delà, le client lève
Enconvert::APIErroravec le statut504et le messageConversion timed out.
Le job_id généré par le client est également fusionné dans chaque réponse réussie : result.job_id est donc toujours renseigné et vous pouvez interroger get_job_status vous-même plus tard si vous le souhaitez.
convert_website_to_pdf et convert_website_to_screenshot ne créent pas de ligne de job : un 5xx y signifie donc que la soumission elle-même a échoué, et l'erreur remonte immédiatement au lieu d'être interrogée.
Configuration#
client = Enconvert::Client.new(
api_key: ENV.fetch("ENCONVERT_API_KEY"),
timeout: 300,
base_url: "https://api.enconvert.com"
)
| Option | Type | Par défaut | Description |
|---|---|---|---|
api_key |
String |
obligatoire | Votre clé API privée. Une valeur nil ou vide lève Enconvert::Error à la construction. |
timeout |
Integer |
300 |
Timeout d'ouverture et de lecture en secondes, appliqué à chaque requête. |
base_url |
String |
"https://api.enconvert.com" |
URL de base de l'API. Les barres obliques finales sont supprimées. À remplacer pour une passerelle auto-hébergée. |
Les requêtes s'authentifient avec l'en-tête X-API-Key. Lorsque vous passez save_to, le téléchargement contourne volontairement cet en-tête, car l'URL de stockage présignée ne doit pas recevoir votre clé API.
Structure du résultat#
Chaque conversion de fichier unique et de page unique renvoie un Enconvert::ConversionResult :
result = client.convert_document("report.docx", save_to: "report.pdf")
result.presigned_url # URL signée pour la sortie convertie
result.object_key # clé de l'objet de stockage
result.filename # nom de fichier côté serveur
result.file_size # octets, ou nil
result.conversion_time_seconds # secondes, ou nil
result.job_id # toujours renseigné par le client
Les autres Structs V1 sont JobStatus (status, presigned_url, object_key, error), BatchSubmission (batch_id, status, url_count, total_discovered, discovery_method, output_format), BatchStatus (batch_id, status, total, completed, failed, in_progress, output_mode, zip_download_url, items), et BatchItem (source_url, status, download_url, output_file_size, duration).
Côté V2, PerceiveResult est celui à connaître :
op.operation_id # "per_..."
op.status # queued, processing, completed, failed
op.url, op.url_final, op.content_hash
op.render_quality, op.cache_hit # de 0.0 à 1.0 (ou nil), et s'il vient du cache
op.outputs # Hash de nom => V2OutputArtifact
op.structured, op.extraction_tier # Hash (ou nil), et comment il a été extrait
op.tokens.input, op.tokens.output, op.cost_cents, op.duration_ms
op.error, op.warnings # String ou nil, et Array de String
op.status_code # statut HTTP amont de la page
op.deductions, op.options_echo # pourquoi render_quality a baissé, et les options utilisées
Un V2OutputArtifact porte url, object_key, size_bytes, content_type et expires_in (900 secondes par défaut) : les URL d'artefacts signées sont donc de courte durée. Resignez-les avec get_perceive_operation, ou téléchargez les octets avec download_perceive_artifact. Les charges utiles fournies par l'utilisateur, comme les schémas, les données extraites, les champs suivis et les changements de diff, passent sans modification sous forme de simples Hash Ruby.
Les URL présignées des conversions V1 sont elles aussi temporaires. Passez save_to quand vous voulez les octets sur le disque, ou copiez-les dans votre propre bucket pour un stockage permanent.
Source et problèmes#
- RubyGems : enconvert
- GitHub : conversionapi/ruby-sdk
- Ruby : 3.0.0 ou plus récent, aucune dépendance à l'exécution
- Licence : MIT
- Autres langages : Tous les SDK
- Référence de l'API : Vue d'ensemble des endpoints, Authentification
Questions fréquentes#
Comment convertir des fichiers en Ruby avec une gem ?#
Exécutez gem install enconvert, construisez un client avec Enconvert::Client.new(api_key: ENV.fetch("ENCONVERT_API_KEY")), et appelez une méthode comme convert_document, convert_image ou convert_url_to_pdf. Passez save_to: et le SDK télécharge le résultat vers ce chemin pour vous, en créant les répertoires parents au besoin.
Comment convertir un DOCX en PDF en Ruby ?#
client.convert_document("report.docx", save_to: "report.pdf"). Le format de sortie vaut "pdf" par défaut, vous n'avez donc besoin d'output_format: que lorsque vous voulez autre chose. Le même appel fonctionne pour .doc, .xls, .xlsx, .ppt, .pptx, .odt, .ods, .odp, .ots, .pages et .numbers.
Comment convertir une URL en PDF en Ruby ?#
client.convert_url_to_pdf("https://example.com", save_to: "page.pdf"). Définissez single_page: false pour paginer au lieu de produire une seule page continue, et passez pdf_options: pour la taille de page, l'orientation, les marges et l'échelle. Pour une page derrière une authentification HTTP basic, ajoutez auth: { username: ..., password: ... }.
Comment convertir du HEIC en WebP en Ruby ?#
client.convert_image("photo.heic", output_format: "webp", save_to: "photo.webp"). Le format d'entrée vient de l'extension du nom de fichier, et la gem convertit librement entre jpeg, png, svg, heic et webp. Elle rastérise également un PDF en JPEG avec output_format: "jpeg".
Comment récupérer une page web en Markdown depuis Ruby ?#
Deux options. client.convert_url_to_markdown(url, save_to: "article.md") vous donne du Markdown GitHub-Flavored propre avec un frontmatter YAML. client.v2.perceive(url, outputs: %w[markdown]) vous donne le même contenu plus un score render_quality, des avertissements et une extraction structurée facultative, ce qui est exactement ce qu'il vous faut quand un agent va lire le résultat.
Que signifie render_quality et pourquoi devrais-je le vérifier ?#
C'est un score de 0.0 à 1.0 attaché à chaque lecture V2, qui reflète à quel point la page s'est réellement rendue proprement. Une page de challenge, un mur de cookies, une barrière de connexion, une page d'erreur HTTP ou une coquille JavaScript vide obtiennent toutes un score bas. Le contenu est tout de même renvoyé pour que vous puissiez l'inspecter, avec warnings et deductions qui expliquent le score. Filtrez dessus avant de stocker le texte ou de l'envoyer à un modèle.
Le SDK Ruby réessaie-t-il quand une conversion longue arrive à expiration ?#
Oui. Chaque requête de conversion porte un job_id généré par le client, et si la requête échoue avec un statut de 500 ou plus, le SDK interroge GET /v1/convert/status/{job_id} toutes les 3 secondes pendant 300 secondes au maximum. Il renvoie le résultat une fois le job réussi et lève Enconvert::APIError avec le statut 504 si le délai expire. Les soumissions de lots de site entier sont exclues, parce qu'elles n'ont pas de ligne de job.
Que se passe-t-il si je demande une paire de conversion que l'API n'implémente pas ?#
La gem lève Enconvert::Error localement, avant tout appel réseau, et le message liste les sorties valides pour cette entrée. Vous pouvez consulter la même table vous-même avec Enconvert.valid_outputs_for("json"), qui renvoie ["csv", "toml", "xml", "yaml"].
Puis-je utiliser la gem enconvert dans Rails ou dans un job en arrière-plan ?#
Oui, et un job en arrière-plan est le bon endroit pour cela. La gem repose sur net/http nu, sans dépendance à l'exécution ni état global : une instance d'Enconvert::Client peut donc être construite par job ou mémoïsée par processus en toute sécurité. Les conversions longues bloquent le thread appelant jusqu'au timeout configuré, qui vaut 300 secondes par défaut : gardez-les donc hors du cycle d'une requête web.
Quelles versions de Ruby le SDK prend-il en charge ?#
Ruby 3.0.0 et plus récent, comme déclaré par required_ruby_version dans le gemspec. Il n'y a aucune dépendance de gem à l'exécution : la gem s'installe donc dans n'importe quel groupe Bundler sans traîner tout un arbre de dépendances derrière elle.
Comment vérifier la signature d'un webhook ingest ?#
Appelez client.v2.get_webhook_secret, qui crée le secret de signature du projet à la première utilisation et le renvoie avec signature_header, timestamp_header, signature_scheme et replay_tolerance_seconds. Calculez le HMAC sur le corps livré et comparez-le à l'en-tête de signature. Utilisez rotate_webhook_secret pour invalider l'ancien secret, et retry_ingest_webhook(job_id) pour relivrer la notification d'un job terminé.