Go
Un programa en Go que usa la API solo con la biblioteca estándar: net/http y encoding/json. Enumera las variables etiquetadas de una plantilla, mide el dibujo que genera con los valores dados y lo exporta como PDF.
Descárguelo: main.go.
// main.go: list a template's inputs, measure it and export it as a PDF with the PiQ SaaS API.
// Go 1.18 or later; the standard library only.
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"strings"
)
const template = "L=400,\"Length\"\nW=300,\"Width\"\nP1=[L,0]\nP2=[L,W]\nP3=[0,W]\nPOLYLINE @1,[P0,P1,P2,P3],TRUE,0"
var key, base = os.Getenv("PIQ_API_KEY"), strings.TrimSuffix(os.Getenv("PIQ_URL"), "/")
// Request is the JSON body of a request: a template (or its source), values and, to save, where to.
type Request struct {
Template string `json:"template,omitempty"`
Source *Object `json:"source,omitempty"`
Values map[string]any `json:"values,omitempty"`
Destination *Object `json:"destination,omitempty"`
Overwrite bool `json:"overwrite,omitempty"`
}
// Object is an object in one of your registered storages.
type Object struct {
Storage string `json:"storage"`
Key string `json:"key"`
}
func post(path string, body Request) *http.Response {
data, _ := json.Marshal(body)
req, _ := http.NewRequest("POST", base+path, bytes.NewReader(data))
req.Header.Set("X-API-KEY", key)
req.Header.Set("Content-Type", "application/json")
response, err := http.DefaultClient.Do(req)
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
if response.StatusCode >= 300 {
fmt.Fprintln(os.Stderr, "Error", response.Status)
var problem struct {
Title, Detail string
Errors map[string][]string
}
text, _ := io.ReadAll(response.Body) // a 401 has no body
if len(text) > 0 && json.Unmarshal(text, &problem) != nil {
problem.Detail = string(text)
}
for _, line := range []string{problem.Title, problem.Detail} {
if line != "" {
fmt.Fprintln(os.Stderr, line)
}
}
for field, messages := range problem.Errors {
fmt.Fprintf(os.Stderr, " %s: %s\n", field, strings.Join(messages, " "))
}
os.Exit(1)
}
return response
}
func postFor(path string, body Request, result any) {
response := post(path, body)
defer response.Body.Close()
json.NewDecoder(response.Body).Decode(result)
}
func main() {
if key == "" {
fmt.Fprintln(os.Stderr, "Set PIQ_API_KEY to your API key.")
os.Exit(1)
}
if base == "" {
base = "https://saas.parametriq.co.uk"
}
storage := os.Getenv("PIQ_STORAGE") // optional: a registered storage's name
// the template itself, or (optional) where it is kept in your storage
request := Request{Template: template}
if storage != "" {
request = Request{Source: &Object{storage, "templates/box.piq"}}
}
// 1. The template's labelled variables
var inputs struct {
Inputs []struct {
Name, Label, Kind string
Value any
}
}
postFor("/inputs", request, &inputs)
for _, i := range inputs.Inputs {
fmt.Printf("%s: %s (%s, %v)\n", i.Name, i.Label, i.Kind, i.Value)
}
// 2. The drawing measured, with the values given
var m struct {
Width, Height float64
Layers []struct {
Layer string
Length float64
}
}
request.Values = map[string]any{"L": 500, "W": 250}
postFor("/measure", request, &m)
cut := 0.0
for _, layer := range m.Layers {
if layer.Layer == "Cut" {
cut = layer.Length
}
}
fmt.Printf("Size: %v x %v, cut length: %v\n", m.Width, m.Height, cut)
// 3. The drawing as a PDF
pdf := post("/export/pdf", request)
data, _ := io.ReadAll(pdf.Body)
if err := os.WriteFile("box.pdf", data, 0o644); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
fmt.Printf("Saved box.pdf (%s warnings)\n", pdf.Header.Get("X-PiQ-Warnings"))
// 4. Optional: the PDF saved to your storage instead of downloaded
if storage != "" {
request.Destination, request.Overwrite = &Object{storage, "drawings/box.pdf"}, true
var saved struct {
Storage, Key string
Size int64
}
postFor("/save/pdf", request, &saved)
fmt.Printf("Saved %s to %s (%d bytes)\n", saved.Key, saved.Storage, saved.Size)
}
}
Cómo funciona
- Configuración. La clave se toma de
PIQ_API_KEY, la dirección dePIQ_URL(el propio servicio si no está definida) y, opcionalmente, el nombre de un almacenamiento dePIQ_STORAGE. Sin clave, el programa se detiene de inmediato. Requestes el cuerpo JSON de cada solicitud. Sus campos están etiquetados con los nombres en camelCase de la API yomitempty, de modo que solo se envían los que tienen valor:Template(el texto de la plantilla) o, cuandoPIQ_STORAGEestá definida,Source(dónde está guardada en su almacenamiento), despuésValuesy, para guardar,DestinationyOverwrite.postenvía una solicitud a una operación como JSON, con la clave en el encabezadoX-API-KEY. Una respuesta correcta se devuelve para leerla. De cualquier otra respuesta se imprime el estado y después la descripción del problema: suTitle, suDetaily cada entrada deErrors, el campo y qué está mal en él. Un401no tiene cuerpo, así que no hay nada más que imprimir; un cuerpo que no es JSON se imprime tal cual. Después, el programa termina con1.postForenvía la solicitud y decodifica la respuesta JSON en una struct que solo tiene los campos que se usan aquí (encoding/jsonasociawidthconWidthsin etiquetas).- Inputs.
POST /inputssolo necesita la plantilla. Cada uno de susInputstiene un nombre, una etiqueta, un tipo y un valor; el valor esany, ya que puede ser un número, un texto, otrueofalse. - Measure. Los valores se añaden a la solicitud, y
POST /measureda el ancho y el alto del dibujo, y las longitudes de sus líneas por capa; la longitud de corte es la longitud en la capaCut. - Export.
POST /export/pdfresponde con el propio PDF, no con JSON: su cuerpo se escribe enbox.pdf. El encabezadoX-PiQ-Warningsindica cuántas cosas no pudieron exportarse tal cual. - Save (opcional). Con un almacenamiento, se añaden
DestinationyOverwrite, yPOST /save/pdfexporta el mismo dibujo y lo guarda en su almacenamiento, reemplazando un archivo que ya exista. Responde con dónde lo ha guardado y su tamaño.
Cómo ejecutarlo
Guarde el programa como main.go en una carpeta propia y, a continuación:
export PIQ_API_KEY=XXXX-XXXX-XXXX-XXXXX
go run main.go
Imprime las variables etiquetadas de la plantilla, el tamaño del dibujo y su longitud de corte, y guarda box.pdf:
L: Length (Number, 400)
W: Width (Number, 300)
D: Depth (Number, 300)
Size: 500 x 250, cut length: 1500
Saved box.pdf (0 warnings)
Con un valor que la plantilla no puede usar (por ejemplo, "L": "long"), imprime el problema y se detiene:
Error 400 Bad Request
One or more validation errors occurred.
Some of the values given can't be used.
L: L is a number.
Con una clave incorrecta, solo imprime Error 401 Unauthorized: un 401 no tiene
descripción del problema.
Para probar la parte del almacenamiento, registre un almacenamiento (consulte
Registrar un almacenamiento), coloque en él una plantilla como templates/box.piq y
establezca PIQ_STORAGE con el nombre del almacenamiento. La plantilla se lee entonces desde su almacenamiento, y el
PDF también se guarda en él como drawings/box.pdf, reemplazando cualquier archivo que ya exista.
Consulte también: API, Inputs, Measure, Exportar un dibujo, Guardar en su almacenamiento, Registrar un almacenamiento, Clientes.