Go API framework to interact with the Docling Serve API server, capable of talking to to Python version of docling-serve and able to communicate with docling-rs version of its' docling-serve-rs implementation and alternative API
docling
go
golang
machine-learning
pdf
pdf-converter
pdf-document-processor
pdf-to-markdown
text-extraction
- Go 100%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| examples | ||
| pkg | ||
| references | ||
| .gitignore | ||
| .markdownlint-cli2.jsonc | ||
| base.go | ||
| chunker.go | ||
| chunker_response.go | ||
| constants.go | ||
| convert.go | ||
| COPYING.md | ||
| doc.go | ||
| docling.go | ||
| document.go | ||
| go.mod | ||
| go.sum | ||
| LICENSE | ||
| nullable.go | ||
| nullable_test.go | ||
| README.md | ||
| response.go | ||
| SECURITY.md | ||
| types.go | ||
| types_test.go | ||
| version.go | ||
GMS Docling Client Library
Introduction
Docling is a document extraction, deep learning document analysis and conversion framework, which can also be run as service.
This package is a framework for interfacing Go based applications with the API presented by the docling-serve service. The service implements an OpenAPI structured API however generated API libraries in Go tend to be cumbersome and this package aims to simplify interactions by implementing a concise Go based interface to the presented OpenAPI structured endpoints.
Features
- Implements both Asynchronous and Synchronous versions of the docling Convert API
- Provides DoclingDocument object for access to JSON based docling output, with the v1.10.0 schema
- Implements access to Asyncronous and Synchronous Chunker API
- Allows download via JSON based API response and handling of Zipfile output
- Enables use of custom options for docling-serve API
- Has limited implementation for the docling-rs implementation of the serve API
Example
Convert Async API
package main
import (
"context"
"os"
"os/signal"
"path/filepath"
"syscall"
"time"
"github.com/rs/zerolog/log"
docling "rtlabs.tech/gms-docling"
"rtlabs.tech/gms-docling/pkg/client"
"rtlabs.tech/gms-docling/pkg/convert"
"rtlabs.tech/gms-docling/pkg/document"
"rtlabs.tech/gms-docling/pkg/utils"
)
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
interruptChan := make(chan os.Signal, 1)
signal.Notify(interruptChan, syscall.SIGINT, syscall.SIGTERM)
go func() {
<-interruptChan
cancel()
signal.Stop(interruptChan)
log.Fatal().Msg("Execution Aborted...")
}()
asyncReqTicker := time.NewTicker(20 * time.Second)
defer asyncReqTicker.Stop()
c := convert.NewConvertClient(
os.Getenv("DOCLING_URL"), client.WithTenantID("default"),
client.WithTimeout(20*time.Minute), client.WithDoclingRSAPI(false),
)
task, err := c.AsyncConvertPath(ctx, "manual.pdf", docling.ConvertOptions{
FromFormats: []docling.FromFormat{"pdf"},
ToFormats: []docling.OutputFormat{
docling.FormatJSON,
},
DoOCR: docling.Ptr(true),
OCRLang: []string{"en"},
TableMode: docling.TableModeAccurate,
PDFBackend: docling.PDFBackendThreadedDoclingParse,
Pipeline: docling.PipelineVLM,
DoCodeEnrichment: docling.Ptr(true),
DoFormulaEnrichment: docling.Ptr(true),
DoTableStructure: docling.Ptr(true),
ImageExportMode: docling.ImageExportEmbedded,
IncludeImages: docling.Ptr(true),
OCRPreset: docling.OCRPresetDefault,
VLMPipelineModel: docling.Ptr(docling.VLMPipelineModelGraniteVision),
DoPDFHeadingHierarchy: docling.Ptr(true),
MarkdownPageBreakPlaceholder: "---",
})
if err != nil {
log.Fatal().Err(err).Msg("Error processing document")
}
log.Info().Msgf("Started Convertion Task ID: %s (Status: %s)", task.TaskID, task.TaskStatus)
var result *docling.ConvertResponse
var resp *docling.AsyncResponse
result = nil
for result == nil {
resp = nil
select {
case <-asyncReqTicker.C:
resp, err = c.PollTaskStatus(ctx, task.TaskID)
if err != nil {
log.Error().Err(err).Msg("Task Polling Error")
continue
}
log.Info().Msgf("Task ID: %s (Status: %s)", resp.TaskID, resp.TaskStatus)
if resp.TaskStatus == docling.StatusPending || resp.TaskStatus == docling.StatusStarted {
continue
} else if resp.TaskID == task.TaskID && (resp.TaskStatus == docling.StatusPartialSuccess || resp.TaskStatus == docling.StatusSuccess) {
result, err = c.GetConvertTaskResult(ctx, task.TaskID)
if err != nil {
log.Fatal().Err(err).Msgf("Error retrieving results for Task ID %s", task.TaskID)
}
} else {
result, err = c.GetConvertTaskResult(ctx, task.TaskID)
if err != nil {
log.Fatal().Err(err).Msgf("Error retrieving results for Task ID %s", task.TaskID)
}
}
case <-ctx.Done():
result = &docling.ConvertResponse{
Status: docling.StatusFailure,
}
}
}
if result.Status == docling.StatusFailure {
log.Fatal().Err(err).Msg("Conversion Failed")
}
outputDir, err := utils.CreateOutputDir("./async-doc", task.TaskID)
if err != nil {
log.Fatal().Err(err).Msg("Unable to create output directory")
}
utils.AtomicWriteJSON(filepath.Join(docling.Value(outputDir), "manual-convert-response.json"), result)
doc, err := result.Document.JSONContent().MarshalJSON()
if err != nil {
log.Fatal().Err(err).Msg("Unable to marshal Document")
}
doclingdoc, err := document.UnmarshalDoclingDocument(doc)
if err != nil {
log.Fatal().Err(err).Msg("Unable to unmarshal Document")
}
err = doclingdoc.SaveImages(docling.Value(outputDir))
if err != nil {
log.Fatal().Err(err).Msg("Failed to save images")
}
utils.AtomicWriteJSON(filepath.Join(docling.Value(outputDir), "manual-convert-doclingdocument.json"), &doclingdoc)
log.Info().Msgf("Task ID %s completed - output saved to %s", task.TaskID, docling.Value(outputDir))
}
Copyright and License
Code and Documentation Copyright © 1994-2026, Stephen Kapp and Reaper Technologies Limited. All Rights Reserved.