pdfx 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 125dd0c7576da8187166eb9764471eff0eae685a051243b34b81efa38e037ee8
4
+ data.tar.gz: 16845fc743aff9ba65790b1017625de2f915ab5a61d557da7d5693935bec5a46
5
+ SHA512:
6
+ metadata.gz: 3770b595eb79c8b0ddb64c8aa3457f546c886b5bd6f382aceebb885fa3b9d14148025d859a955dd771ee122d2e9b7be5b319ccf3023a063c25b12be5ffcbe6ac
7
+ data.tar.gz: '048946256d8d7cf96c81facc3c15a803df3f6a9bf15e9e17735b72ad2c4eb4d12e71da52514eebbd75d99f154bb6932440eb9609be36d569474fc76a695c358c'
data/CHANGELOG.md ADDED
@@ -0,0 +1,18 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.1.0] - 2025-11-30
9
+
10
+ ### Added
11
+ - Initial release
12
+ - `Pdfx::Client` class for API interactions
13
+ - Support for template-based PDF generation
14
+ - Data interpolation support
15
+ - X-Api-Key authentication
16
+ - Comprehensive error handling with custom exception classes
17
+ - Configuration module for global settings
18
+ - Documentation and examples
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Olivier Bonnaure
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,175 @@
1
+ # Pdfx Ruby Gem
2
+
3
+ A Ruby wrapper for the [pdfx.fr](https://pdfx.fr) API - the fastest, most eco-friendly PDF generation service for developers.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'pdfx'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ ```bash
16
+ bundle install
17
+ ```
18
+
19
+ Or install it yourself as:
20
+
21
+ ```bash
22
+ gem install pdfx
23
+ ```
24
+
25
+ ## Configuration
26
+
27
+ Configure the gem with your API key:
28
+
29
+ ```ruby
30
+ require 'pdfx'
31
+
32
+ Pdfx.configure do |config|
33
+ config.api_key = "your-api-key-here"
34
+ end
35
+ ```
36
+
37
+ You can also set a custom base URL (useful for testing):
38
+
39
+ ```ruby
40
+ Pdfx.configure do |config|
41
+ config.api_key = "your-api-key-here"
42
+ config.base_url = "https://custom-pdfx-instance.com"
43
+ end
44
+ ```
45
+
46
+ ## Usage
47
+
48
+ ### Basic Usage
49
+
50
+ ```ruby
51
+ require 'pdfx'
52
+
53
+ # Configure globally
54
+ Pdfx.configure do |config|
55
+ config.api_key = "your-api-key"
56
+ end
57
+
58
+ # Create a client
59
+ client = Pdfx::Client.new
60
+
61
+ # Generate a PDF
62
+ pdf_data = client.generate_pdf(
63
+ template_uuid: "ea99e8b9-1234-5678-90ab-cdef12345678",
64
+ data: {
65
+ invoice: "001",
66
+ customer: "Acme Corp",
67
+ amount: 1299
68
+ }
69
+ )
70
+
71
+ # Save to file
72
+ File.write("invoice.pdf", pdf_data)
73
+ ```
74
+
75
+ ### Using Client-Specific API Key
76
+
77
+ You can override the global API key for specific clients:
78
+
79
+ ```ruby
80
+ client = Pdfx::Client.new(api_key: "different-api-key")
81
+
82
+ pdf_data = client.generate_pdf(
83
+ template_uuid: "ea99e8b9-1234-5678-90ab-cdef12345678",
84
+ data: { invoice: "002", customer: "Beta Inc", amount: 2500 }
85
+ )
86
+ ```
87
+
88
+ ### Error Handling
89
+
90
+ The gem provides specific error classes for different scenarios:
91
+
92
+ ```ruby
93
+ begin
94
+ pdf_data = client.generate_pdf(
95
+ template_uuid: "ea99e8b9-1234-5678-90ab-cdef12345678",
96
+ data: { invoice: "003" }
97
+ )
98
+ File.write("output.pdf", pdf_data)
99
+ rescue Pdfx::AuthenticationError => e
100
+ puts "Invalid API key: #{e.message}"
101
+ rescue Pdfx::RequestError => e
102
+ puts "Bad request: #{e.message}"
103
+ rescue Pdfx::ServerError => e
104
+ puts "Server error: #{e.message}"
105
+ rescue Pdfx::NetworkError => e
106
+ puts "Network error: #{e.message}"
107
+ rescue Pdfx::Error => e
108
+ puts "General error: #{e.message}"
109
+ end
110
+ ```
111
+
112
+ ## API Reference
113
+
114
+ ### `Pdfx.configure`
115
+
116
+ Configure the gem globally.
117
+
118
+ **Parameters:**
119
+ - `api_key` (String): Your pdfx.fr API key
120
+ - `base_url` (String): Base URL for the API (default: "https://pdfx.fr")
121
+
122
+ ### `Pdfx::Client.new`
123
+
124
+ Create a new client instance.
125
+
126
+ **Parameters:**
127
+ - `api_key` (String, optional): Override the global API key
128
+ - `base_url` (String, optional): Override the global base URL
129
+
130
+ ### `client.generate_pdf`
131
+
132
+ Generate a PDF using a template.
133
+
134
+ **Parameters:**
135
+ - `template_uuid` (String, required): The UUID of your template
136
+ - `data` (Hash, optional): Data to interpolate into the template
137
+
138
+ **Returns:** String (PDF binary data)
139
+
140
+ **Raises:**
141
+ - `Pdfx::AuthenticationError`: Invalid API key
142
+ - `Pdfx::RequestError`: Invalid request parameters
143
+ - `Pdfx::ServerError`: Server error (5xx)
144
+ - `Pdfx::NetworkError`: Network connectivity issues
145
+
146
+ ## Error Classes
147
+
148
+ - `Pdfx::Error` - Base error class
149
+ - `Pdfx::AuthenticationError` - Invalid API key (401)
150
+ - `Pdfx::RequestError` - Bad request (400)
151
+ - `Pdfx::ServerError` - Server error (5xx)
152
+ - `Pdfx::NetworkError` - Network connectivity issues
153
+
154
+ ## Development
155
+
156
+ After checking out the repo, run `bundle install` to install dependencies.
157
+
158
+ ## Contributing
159
+
160
+ Bug reports and pull requests are welcome on GitHub at https://github.com/solisoft/ruby-pdfx.
161
+
162
+ ## License
163
+
164
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
165
+
166
+ ## About pdfx.fr
167
+
168
+ [pdfx.fr](https://pdfx.fr) is a blazing-fast PDF generation API that:
169
+ - Generates PDFs in sub-100ms
170
+ - Supports Factur-X/ZUGFeRD e-invoicing
171
+ - Stores zero data (privacy by design)
172
+ - Runs on 100% renewable energy
173
+ - Offers 200 free PDFs per month
174
+
175
+ Visit [pdfx.fr](https://pdfx.fr) to create your account and get your API key.
@@ -0,0 +1,105 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "net/http"
4
+ require "json"
5
+ require "uri"
6
+
7
+ module Pdfx
8
+ # Main client class for interacting with the pdfx.fr API
9
+ class Client
10
+ attr_reader :api_key, :base_url
11
+
12
+ # Initialize a new Pdfx client
13
+ #
14
+ # @param api_key [String] Your pdfx.fr API key (optional if configured globally)
15
+ # @param base_url [String] The base URL for the API (defaults to https://pdfx.fr)
16
+ def initialize(api_key: nil, base_url: nil)
17
+ @api_key = api_key || Pdfx.api_key
18
+ @base_url = base_url || Pdfx.base_url
19
+
20
+ raise ArgumentError, "API key is required" if @api_key.nil? || @api_key.empty?
21
+ end
22
+
23
+ # Generate a PDF using a template and data
24
+ #
25
+ # @param template_uuid [String] The UUID of the template to use
26
+ # @param data [Hash] The data to interpolate into the template
27
+ # @return [String] The PDF binary data
28
+ # @raise [Pdfx::AuthenticationError] If the API key is invalid
29
+ # @raise [Pdfx::RequestError] If the request parameters are invalid
30
+ # @raise [Pdfx::ServerError] If the server returns an error
31
+ # @raise [Pdfx::NetworkError] If a network error occurs
32
+ #
33
+ # @example Generate a PDF
34
+ # client = Pdfx::Client.new(api_key: "your-api-key")
35
+ # pdf_data = client.generate_pdf(
36
+ # template_uuid: "ea99e8b9-...",
37
+ # data: { invoice: "001", customer: "Acme", amount: 1299 }
38
+ # )
39
+ # File.write("invoice.pdf", pdf_data)
40
+ def generate_pdf(template_uuid:, data: {})
41
+ raise ArgumentError, "template_uuid is required" if template_uuid.nil? || template_uuid.empty?
42
+
43
+ payload = {
44
+ template_uuid: template_uuid,
45
+ data: data
46
+ }
47
+
48
+ make_request(payload)
49
+ end
50
+
51
+ private
52
+
53
+ # Make an HTTP POST request to the pdfx.fr API
54
+ #
55
+ # @param payload [Hash] The request payload
56
+ # @return [String] The PDF binary data
57
+ def make_request(payload)
58
+ uri = URI.join(@base_url, "/v1")
59
+ http = Net::HTTP.new(uri.host, uri.port)
60
+ http.use_ssl = uri.scheme == "https"
61
+ http.read_timeout = 30 # 30 seconds timeout
62
+
63
+ request = Net::HTTP::Post.new(uri.path)
64
+ request["Content-Type"] = "application/json"
65
+ request["X-Api-Key"] = @api_key
66
+ request.body = JSON.generate(payload)
67
+
68
+ response = http.request(request)
69
+
70
+ handle_response(response)
71
+ rescue SocketError, Net::OpenTimeout, Net::ReadTimeout => e
72
+ raise NetworkError, "Network error: #{e.message}"
73
+ end
74
+
75
+ # Handle the HTTP response
76
+ #
77
+ # @param response [Net::HTTPResponse] The HTTP response
78
+ # @return [String] The PDF binary data
79
+ def handle_response(response)
80
+ case response.code.to_i
81
+ when 200
82
+ response.body
83
+ when 401
84
+ raise AuthenticationError, "Invalid API key"
85
+ when 400
86
+ error_message = extract_error_message(response.body)
87
+ raise RequestError, "Bad request: #{error_message}"
88
+ when 500..599
89
+ raise ServerError, "Server error: #{response.code}"
90
+ else
91
+ raise Error, "Unexpected response: #{response.code}"
92
+ end
93
+ end
94
+
95
+ # Extract error message from response body
96
+ #
97
+ # @param body [String] The response body
98
+ # @return [String] The error message
99
+ def extract_error_message(body)
100
+ JSON.parse(body)["error"] || body
101
+ rescue JSON::ParserError
102
+ body
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pdfx
4
+ # Base error class for all Pdfx errors
5
+ class Error < StandardError; end
6
+
7
+ # Raised when authentication fails (invalid API key)
8
+ class AuthenticationError < Error; end
9
+
10
+ # Raised when the request is invalid (bad parameters)
11
+ class RequestError < Error; end
12
+
13
+ # Raised when the server returns a 5xx error
14
+ class ServerError < Error; end
15
+
16
+ # Raised when a network error occurs
17
+ class NetworkError < Error; end
18
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pdfx
4
+ VERSION = "0.1.0"
5
+ end
data/lib/pdfx.rb ADDED
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "pdfx/version"
4
+ require_relative "pdfx/errors"
5
+ require_relative "pdfx/client"
6
+
7
+ # Main module for the Pdfx gem
8
+ module Pdfx
9
+ class << self
10
+ attr_accessor :api_key, :base_url
11
+
12
+ # Configure the Pdfx gem
13
+ #
14
+ # @yield [self] Configuration block
15
+ #
16
+ # @example Configure with a block
17
+ # Pdfx.configure do |config|
18
+ # config.api_key = "your-api-key"
19
+ # config.base_url = "https://pdfx.fr"
20
+ # end
21
+ def configure
22
+ yield self if block_given?
23
+ end
24
+ end
25
+
26
+ # Set default configuration
27
+ self.base_url = "https://pdfx.fr"
28
+ end
metadata ADDED
@@ -0,0 +1,54 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pdfx
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Olivier Bonnaure
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2025-11-30 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: A simple and efficient Ruby gem for generating PDFs using the pdfx.fr
14
+ API with template-based data interpolation
15
+ email:
16
+ - olivier@solisoft.net
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - CHANGELOG.md
22
+ - LICENSE
23
+ - README.md
24
+ - lib/pdfx.rb
25
+ - lib/pdfx/client.rb
26
+ - lib/pdfx/errors.rb
27
+ - lib/pdfx/version.rb
28
+ homepage: https://github.com/solisoft/ruby-pdfx
29
+ licenses:
30
+ - MIT
31
+ metadata:
32
+ homepage_uri: https://github.com/solisoft/ruby-pdfx
33
+ source_code_uri: https://github.com/solisoft/ruby-pdfx
34
+ changelog_uri: https://github.com/solisoft/ruby-pdfx/blob/main/CHANGELOG.md
35
+ post_install_message:
36
+ rdoc_options: []
37
+ require_paths:
38
+ - lib
39
+ required_ruby_version: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: 2.7.0
44
+ required_rubygems_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ requirements: []
50
+ rubygems_version: 3.5.9
51
+ signing_key:
52
+ specification_version: 4
53
+ summary: Ruby wrapper for the pdfx.fr API
54
+ test_files: []