Class: Mathpix::Client
- Inherits:
-
Object
- Object
- Mathpix::Client
- Defined in:
- lib/mathpix/client.rb
Overview
Core HTTP client for Mathpix API
Instance Attribute Summary collapse
-
#config ⇒ Object
readonly
Returns the value of attribute config.
Instance Method Summary collapse
-
#convert_document(document_path:, document_type:, **options) ⇒ String
Convert document (PDF, DOCX, PPTX) asynchronously.
-
#convert_strokes(strokes, **options) ⇒ Result
Convert handwritten strokes to text/LaTeX via /v3/strokes.
-
#download(url) ⇒ String
Download file from URL.
-
#get(path, params: {}) ⇒ Hash
Make GET request.
-
#get_document_output(conversion_id, format) ⇒ String
Fetch a rendered document output (e.g. 'mmd', 'md', 'html', 'tex').
-
#get_document_status(conversion_id) ⇒ Hash
Get document conversion status.
-
#initialize(config = Mathpix.configuration) ⇒ Client
constructor
A new instance of Client.
-
#post(path, body) ⇒ Hash
Make POST request.
-
#recent(limit: 10) ⇒ Array<Result>
Get recent captures.
-
#snap(image_path_or_url, **options) ⇒ Result
Snap image to equation (core method).
Constructor Details
#initialize(config = Mathpix.configuration) ⇒ Client
Returns a new instance of Client.
8 9 10 11 |
# File 'lib/mathpix/client.rb', line 8 def initialize(config = Mathpix.configuration) @config = config config.validate! end |
Instance Attribute Details
#config ⇒ Object (readonly)
Returns the value of attribute config.
6 7 8 |
# File 'lib/mathpix/client.rb', line 6 def config @config end |
Instance Method Details
#convert_document(document_path:, document_type:, **options) ⇒ String
Convert document (PDF, DOCX, PPTX) asynchronously
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/mathpix/client.rb', line 106 def convert_document(document_path:, document_type:, **) conversion_formats = build_conversion_formats() = () # The /v3/pdf endpoint takes a remote PDF via the `url` field, or a local # file via multipart upload — NOT the base64 `src` field used by the image # (/v3/text) endpoint. Sending `src` made Mathpix reply "Missing URL in # request body", which previously surfaced as a useless generic # "Client error". response = if url?(document_path) post('/pdf', { url: document_path, conversion_formats: conversion_formats }.merge()) else post_multipart('/pdf', document_path, { conversion_formats: conversion_formats }.merge()) end pdf_id = response['pdf_id'] return pdf_id if pdf_id # 200 OK with an error body (missing/invalid fields, etc.) raise APIError.new( "Document submission failed: #{(response) || 'no pdf_id returned by Mathpix'}", status: 200, details: response.is_a?(Hash) ? response : {} ) end |
#convert_strokes(strokes, **options) ⇒ Result
Convert handwritten strokes to text/LaTeX via /v3/strokes. Strokes arrive as [[[x,y],...], ...]; Mathpix wants parallel x/y arrays, so we transpose.
45 46 47 48 49 50 51 52 53 |
# File 'lib/mathpix/client.rb', line 45 def convert_strokes(strokes, **) pts = Array(strokes).map { |stroke| Array(stroke) } response = post('/strokes', strokes: { strokes: { x: pts.map { |s| s.map { |p| p[0] } }, y: pts.map { |s| s.map { |p| p[1] } } } }, formats: ([:formats] || config.default_formats).map(&:to_s), **()) Result.new(response) end |
#download(url) ⇒ String
Download file from URL
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/mathpix/client.rb', line 73 def download(url) uri = URI(url) request = Net::HTTP::Get.new(uri) request['app_id'] = config.app_id request['app_key'] = config.app_key request['User-Agent'] = config.user_agent response = make_request(uri, request) case response when Net::HTTPSuccess response.body else raise APIError.new( "Download failed: #{response.code}", status: response.code.to_i ) end end |
#get(path, params: {}) ⇒ Hash
Make GET request
419 420 421 422 423 424 425 426 427 428 429 430 |
# File 'lib/mathpix/client.rb', line 419 def get(path, params: {}) uri = URI("#{config.endpoint}#{path}") uri.query = URI.encode_www_form(params) unless params.empty? request = Net::HTTP::Get.new(uri) request['app_id'] = config.app_id request['app_key'] = config.app_key request['User-Agent'] = config.user_agent response = make_request(uri, request) handle_response(response) end |
#get_document_output(conversion_id, format) ⇒ String
Fetch a rendered document output (e.g. 'mmd', 'md', 'html', 'tex')
The /v3/pdf/id.ext endpoints return the raw converted content; the status endpoint (get_document_status) never contains it.
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
# File 'lib/mathpix/client.rb', line 149 def get_document_output(conversion_id, format) uri = URI("#{config.endpoint}/pdf/#{conversion_id}.#{format}") request = Net::HTTP::Get.new(uri) request['app_id'] = config.app_id request['app_key'] = config.app_key request['User-Agent'] = config.user_agent response = make_request(uri, request) # Net::HTTP returns ASCII-8BIT bodies; Mathpix text outputs are UTF-8. return response.body.to_s.dup.force_encoding(Encoding::UTF_8) if response.is_a?(Net::HTTPSuccess) error_data = begin JSON.parse(response.body) rescue StandardError {} end raise APIError.new( "Failed to fetch '#{format}' output: #{(error_data) || "HTTP #{response.code}"}", status: response.code.to_i, details: error_data.is_a?(Hash) ? error_data : {} ) end |
#get_document_status(conversion_id) ⇒ Hash
Get document conversion status
137 138 139 |
# File 'lib/mathpix/client.rb', line 137 def get_document_status(conversion_id) get("/pdf/#{conversion_id}") end |
#post(path, body) ⇒ Hash
Make POST request
374 375 376 377 378 379 380 381 382 383 384 385 |
# File 'lib/mathpix/client.rb', line 374 def post(path, body) uri = URI("#{config.endpoint}#{path}") request = Net::HTTP::Post.new(uri) request['Content-Type'] = 'application/json' request['app_id'] = config.app_id request['app_key'] = config.app_key request['User-Agent'] = config.user_agent request.body = JSON.generate(body) response = make_request(uri, request) handle_response(response) end |
#recent(limit: 10) ⇒ Array<Result>
Get recent captures. /v3/ocr-results returns rows under "ocr_results", each nesting the OCR payload under "result" with the timestamp on top.
60 61 62 63 64 65 66 67 |
# File 'lib/mathpix/client.rb', line 60 def recent(limit: 10) rows = get('/ocr-results', params: { per_page: limit })['ocr_results'] || [] rows.map do |row| payload = row['result'] || row payload = payload.merge('timestamp' => row['timestamp']) if payload.is_a?(Hash) && row['timestamp'] Result.new(payload) end end |
#snap(image_path_or_url, **options) ⇒ Result
Snap image to equation (core method)
Supports both local file paths and remote URLs
27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/mathpix/client.rb', line 27 def snap(image_path_or_url, **) src, source_ref = prepare_image_source(image_path_or_url, ) response = post('/text', { src: src, formats: ([:formats] || config.default_formats).map(&:to_s), include_line_data: [:include_line_data] || false, **() }) Result.new(response, source_ref) end |