Class: Nfe::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/nfe/client.rb,
sig/nfe/client.rbs

Overview

Primary entry point for the SDK.

client = Nfe::Client.new(api_key: "...")
client.service_invoices.create(company_id: "...", data: { ... })

Resources are exposed as lazy, memoized snake_case accessors, each guarded by a Mutex so a single Client is safe to share across threads (Rails/Sidekiq/Puma). The class is the public surface and is NOT designed for subclassing; customization is achieved by composing Configuration and the injected transport.

Constant Summary collapse

RESOURCES =

The 17 core resource accessor names mapped to their resource classes.

Returns:

  • (Hash[Symbol, untyped])
{
  service_invoices: Resources::ServiceInvoices,
  product_invoices: Resources::ProductInvoices,
  consumer_invoices: Resources::ConsumerInvoices,
  transportation_invoices: Resources::TransportationInvoices,
  inbound_product_invoices: Resources::InboundProductInvoices,
  product_invoice_query: Resources::ProductInvoiceQuery,
  consumer_invoice_query: Resources::ConsumerInvoiceQuery,
  companies: Resources::Companies,
  legal_people: Resources::LegalPeople,
  natural_people: Resources::NaturalPeople,
  webhooks: Resources::Webhooks,
  addresses: Resources::Addresses,
  legal_entity_lookup: Resources::LegalEntityLookup,
  natural_person_lookup: Resources::NaturalPersonLookup,
  tax_calculation: Resources::TaxCalculation,
  tax_codes: Resources::TaxCodes,
  state_taxes: Resources::StateTaxes,
  # RTC (Reforma Tributária) emission — paridade-plus addons, not part of
  # the 17 canonical resources shared with the PHP/Node SDKs.
  service_invoices_rtc: Resources::ServiceInvoicesRtc,
  product_invoices_rtc: Resources::ProductInvoicesRtc
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(api_key: nil, data_api_key: nil, configuration: nil, environment: :production, timeout: 30, max_retries: 3, logger: nil, user_agent_suffix: nil) ⇒ Client

Returns a new instance of Client.

Parameters:

  • api_key (String, nil) (defaults to: nil)

    the main API key (overridden by configuration).

  • data_api_key (String, nil) (defaults to: nil)

    the data-services API key.

  • configuration (Nfe::Configuration, nil) (defaults to: nil)

    when supplied, the other convenience keyword arguments are ignored.

  • environment (Symbol) (defaults to: :production)

    :production (default) or :development.

  • timeout (Integer) (defaults to: 30)

    read timeout in seconds.

  • max_retries (Integer) (defaults to: 3)

    retries after the initial attempt.

  • logger (#info, #warn, #error, nil) (defaults to: nil)
  • user_agent_suffix (String, nil) (defaults to: nil)


81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/nfe/client.rb', line 81

def initialize(api_key: nil, data_api_key: nil, configuration: nil,
               environment: :production, timeout: 30, max_retries: 3,
               logger: nil, user_agent_suffix: nil)
  @configuration = configuration || Configuration.new(
    api_key: api_key,
    data_api_key: data_api_key,
    environment: environment,
    timeout: timeout,
    max_retries: max_retries,
    logger: logger,
    user_agent_suffix: user_agent_suffix
  )
  @resources = {}
  @transports = {}
  @resource_mutex = Mutex.new
  @transport_mutex = Mutex.new
end

Instance Attribute Details

#configurationNfe::Configuration (readonly)

Returns the active configuration.

Returns:



70
71
72
# File 'lib/nfe/client.rb', line 70

def configuration
  @configuration
end

Instance Method Details

#addressesNfe::Resources::Addresses



111
# File 'lib/nfe/client.rb', line 111

def addresses = resource(:addresses)

#build_request(method, family:, path:, query:, body:, headers:, idempotency_key:, request_options:) ⇒ Object

Compose the Http::Request, resolving host/key/timeout from the family (with per-call request_options overrides) and applying the standard headers.



151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/nfe/client.rb', line 151

def build_request(method, family:, path:, query:, body:, headers:,
                  idempotency_key:, request_options:)
  base_url = request_options&.base_url || configuration.base_url_for(family)
  api_key = request_options&.api_key || configuration.api_key_for(family)

  Http::Request.new(
    method: method.to_s.upcase,
    base_url: base_url,
    path: path,
    headers: default_headers(api_key).merge(headers),
    query: query,
    body: body,
    open_timeout: configuration.open_timeout,
    read_timeout: request_options&.timeout || configuration.timeout,
    idempotency_key: idempotency_key
  )
end

#build_transportNfe::Http::RetryingTransport



194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
# File 'lib/nfe/client.rb', line 194

def build_transport
  inner = Http::NetHttp.new(
    default_open_timeout: configuration.open_timeout,
    default_read_timeout: configuration.timeout,
    ca_file: configuration.ca_file
  )
  policy = Http::RetryPolicy.new(
    max_retries: configuration.max_retries,
    base_delay: 1.0,
    max_delay: 30.0,
    jitter: 0.3
  )
  Http::RetryingTransport.new(inner: inner, policy: policy,
                              logger: configuration.logger)
end

#companiesNfe::Resources::Companies



107
# File 'lib/nfe/client.rb', line 107

def companies = resource(:companies)

#consumer_invoice_queryNfe::Resources::ConsumerInvoiceQuery



106
# File 'lib/nfe/client.rb', line 106

def consumer_invoice_query = resource(:consumer_invoice_query)

#consumer_invoicesNfe::Resources::ConsumerInvoices



102
# File 'lib/nfe/client.rb', line 102

def consumer_invoices = resource(:consumer_invoices)

#default_headers(api_key) ⇒ Hash[String, untyped]

Standard headers applied to every outgoing request.

Parameters:

  • api_key (String, nil)

Returns:

  • (Hash[String, untyped])


170
171
172
173
174
175
176
# File 'lib/nfe/client.rb', line 170

def default_headers(api_key)
  {
    "X-NFE-APIKEY" => api_key,
    "User-Agent" => Http::UserAgent.build(configuration.user_agent_suffix),
    "Accept" => "application/json"
  }
end

#inbound_product_invoicesNfe::Resources::InboundProductInvoices



104
# File 'lib/nfe/client.rb', line 104

def inbound_product_invoices = resource(:inbound_product_invoices)


112
# File 'lib/nfe/client.rb', line 112

def legal_entity_lookup = resource(:legal_entity_lookup)


108
# File 'lib/nfe/client.rb', line 108

def legal_people = resource(:legal_people)

#natural_peopleNfe::Resources::NaturalPeople



109
# File 'lib/nfe/client.rb', line 109

def natural_people = resource(:natural_people)

#natural_person_lookupNfe::Resources::NaturalPersonLookup



113
# File 'lib/nfe/client.rb', line 113

def natural_person_lookup = resource(:natural_person_lookup)

#product_invoice_queryNfe::Resources::ProductInvoiceQuery



105
# File 'lib/nfe/client.rb', line 105

def product_invoice_query = resource(:product_invoice_query)

#product_invoicesNfe::Resources::ProductInvoices



101
# File 'lib/nfe/client.rb', line 101

def product_invoices = resource(:product_invoices)

#product_invoices_rtcNfe::Resources::ProductInvoicesRtc



118
# File 'lib/nfe/client.rb', line 118

def product_invoices_rtc = resource(:product_invoices_rtc)

#request(method, family:, path:, query: {}, body: nil, headers: {}, idempotency_key: nil, request_options: nil) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Issue an arbitrary request against family, applying the family's host and key plus the standard authorization and User-Agent headers. This is the low-level escape hatch shared by every resource.

When request_options is supplied, its non-nil api_key, base_url, and timeout override the family-resolved values for this single call (enabling multi-tenant per-call keys); nil fields fall back to family resolution.

Raises the appropriate Error subclass (via ErrorFactory) on a non-2xx response (note: 202 is a success); otherwise returns the Http::Response.



133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/nfe/client.rb', line 133

def request(method, family:, path:, query: {}, body: nil, headers: {},
            idempotency_key: nil, request_options: nil)
  request = build_request(method, family: family, path: path, query: query,
                                  body: body, headers: headers,
                                  idempotency_key: idempotency_key,
                                  request_options: request_options)

  response = transport_for(family).call(request)
  raise Nfe::ErrorFactory.from_response(response) unless response.success?

  response
end

#resource(name) ⇒ Object

Memoize (under a Mutex) the resource instance for name.

Parameters:

  • name (Symbol)

Returns:

  • (Object)


179
180
181
182
183
# File 'lib/nfe/client.rb', line 179

def resource(name)
  @resource_mutex.synchronize do
    @resources[name] ||= RESOURCES.fetch(name).new(self)
  end
end

#service_invoicesNfe::Resources::ServiceInvoices

The 17 core lazy resource accessors.



100
# File 'lib/nfe/client.rb', line 100

def service_invoices = resource(:service_invoices)

#service_invoices_rtcNfe::Resources::ServiceInvoicesRtc



117
# File 'lib/nfe/client.rb', line 117

def service_invoices_rtc = resource(:service_invoices_rtc)

#state_taxesNfe::Resources::StateTaxes



116
# File 'lib/nfe/client.rb', line 116

def state_taxes = resource(:state_taxes)

#tax_calculationNfe::Resources::TaxCalculation



114
# File 'lib/nfe/client.rb', line 114

def tax_calculation = resource(:tax_calculation)

#tax_codesNfe::Resources::TaxCodes



115
# File 'lib/nfe/client.rb', line 115

def tax_codes = resource(:tax_codes)

#transport_for(family) ⇒ Object

Memoize (under a Mutex) a RetryingTransport(NetHttp) per family. Families may differ in nothing transport-wise today, but memoizing per family keeps the door open for per-host tuning and matches the canonical contract.

Parameters:

  • family (Symbol)

Returns:

  • (Object)


188
189
190
191
192
# File 'lib/nfe/client.rb', line 188

def transport_for(family)
  @transport_mutex.synchronize do
    @transports[family] ||= build_transport
  end
end

#transportation_invoicesNfe::Resources::TransportationInvoices



103
# File 'lib/nfe/client.rb', line 103

def transportation_invoices = resource(:transportation_invoices)

#webhooksNfe::Resources::Webhooks



110
# File 'lib/nfe/client.rb', line 110

def webhooks = resource(:webhooks)