Gem Version License Build Status

Fetch and parse ASME (American Society of Mechanical Engineers) standards and codes from the official ASME website.

Purpose

Relaton for ASME provides a programmatic interface to fetch ASME standards and codes publications.

It accesses the ASME JSON API for publication listings and parses JSON-LD structured data from publication pages to extract complete bibliographic metadata.

Features

Architecture

General

RelatonAsme uses a two-stage data pipeline with object-oriented, model-driven architecture:

Data Pipeline
Stage 1: ASME JSON API
    │
    └─► IndexPage fetches from /api/products
        │
        └─► Returns publication URLs
            │
            ▼
Stage 2: JSON-LD Parsing
    │
    └─► PublicationPage parses <script type="application/ld+json">
        │
        └─► Extracts Schema.org Product data
            │
            ▼
Stage 3: Data Models
    │
    └─► AsmePublicationEdition (with URL, metadata, pricing)

Data model hierarchy

AsmePublication (Container)
    │
    └── AsmePublicationEdition[] (Primary Model - Array)
            │
            ├── url: String (publication page URL)
            ├── document_type: String ("standard")
            ├── title: String (WITHOUT designator prefix)
            ├── document_identifier: String (e.g., "BPVC.I-2025")
            ├── designator: String (e.g., "BPVC.I")
            ├── edition_year: String (e.g., "2025")
            ├── publisher: String ("ASME")
            ├── publish_date: String
            ├── language: String ("EN")
            ├── number_of_pages: Integer (optional)
            ├── description: String (optional)
            ├── topics: String[] (optional)
            └── formats: AsmeFormat[] (optional)
                    │
                    ├── format_type: String (e.g., "PDF", "Print Book")
                    ├── price: String (e.g., "$675.00")
                    └── isbn: String (optional)

Installation

Add this line to your application’s Gemfile:

gem "relaton-asme"

And then execute:

bundle install

Or install it yourself as:

gem install relaton-asme

Usage

Fetching publication listings

General

The IndexPage class fetches publication listings from the ASME JSON API at https://www.asme.org/api/products.

Fetching publication URLs from API

Syntax:

index = RelatonAsme::Fetcher::IndexPage.new(
  page_number: {page_number}, <b class="conum">(1)</b>
  per_page: {per_page} <b class="conum">(2)</b>
)
urls = index.publication_urls <b class="conum">(3)</b>
  1. Page number to fetch (1-based, default: 1)

  2. Number of results per page (default: 100, max: 100)

  3. Returns array of publication URLs

Where,

page_number

The page number to fetch, starting from 1. Default is 1.

per_page

Number of publications to fetch per page. Default is 100.

publication_urls

Returns an array of publication URLs for each edition/format combination.

Example 1. Fetching URLs from the first page of API
require "relaton_asme"

index = RelatonAsme::Fetcher::IndexPage.new(page_number: 1, per_page: 10)
urls = index.publication_urls

puts "Found #{urls.size} publication URLs"
urls.first(5).each { |url| puts url }

This queries the ASME API and returns URLs for each edition/format combination.

Example output:

Found 30 publication URLs
https://www.asme.org/codes-standards/find-codes-standards/bpvc-i-.../2025/print-book
https://www.asme.org/codes-standards/find-codes-standards/bpvc-i-.../2023/print-book

Parsing publication metadata

General

The PublicationPage class parses JSON-LD structured data from individual publication pages. Each page may contain multiple editions (different years) as separate offers.

Fetching publication data from JSON-LD

Syntax:

page = RelatonAsme::Fetcher::PublicationPage.new({url}) <b class="conum">(1)</b>
publication = page.to_data <b class="conum">(2)</b>
  1. Publication URL to fetch

  2. Returns AsmePublication object with editions extracted from JSON-LD offers

Where,

url

The full URL to the publication page on asme.org

to_data

Returns an AsmePublication object containing all editions from the page’s JSON-LD data

Example 2. Fetching a publication via JSON-LD
url = "https://www.asme.org/codes-standards/find-codes-standards/" \
      "temperature-measurement/2024/pdf"

page = RelatonAsme::Fetcher::PublicationPage.new(url)
publication = page.to_data

if publication
  publication.editions.each do |edition|
    puts "Title: #{edition.title}"
    puts "Year: #{edition.edition_year}"
    puts "URL: #{edition.url}"
    puts "Identifier: #{edition.document_identifier}"
  end
end

This parses the JSON-LD structured data and may return multiple editions (e.g., 2024 and 1974 versions) from a single page.

Example output:

Title: Temperature Measurement (2024)
Year: 2024
URL: https://www.asme.org/.../2024/pdf/
Identifier: PTC 19.3-2024

Title: Temperature Measurement (1974)
Year: 1974
URL: https://www.asme.org/.../1974/pdf/
Identifier: PTC 19.3-1974

Batch processing with Runner

General

The Runner class orchestrates batch fetching of publications from the API.

Fetching all publications

Syntax:

runner = RelatonAsme::Fetcher::Runner.new <b class="conum">(1)</b>
editions = runner.fetch_all(
  max_pages: {max_pages}, <b class="conum">(2)</b>
  per_page: {per_page} <b class="conum">(3)</b>
)
  1. Create a new runner instance

  2. Maximum number of API pages to fetch (nil for all pages)

  3. Number of publications per page (default: 100)

Where,

max_pages

Optional limit on the number of API pages to process. Pass nil to fetch all 671 publications (135 pages).

per_page

Number of publications to fetch per API page. Default is 100, maximum is 100.

editions

Returns an array of AsmePublicationEdition objects from all fetched publications.

Example 3. Fetching publications from first 2 pages
runner = RelatonAsme::Fetcher::Runner.new
editions = runner.fetch_all(max_pages: 2, per_page: 10)

puts "Fetched #{editions.size} editions"
editions.first(3).each do |edition|
  puts "#{edition.document_identifier} - #{edition.title}"
end

This fetches publications from the first 2 API pages and parses their JSON-LD data.

Fetching and saving to file

Syntax:

runner = RelatonAsme::Fetcher::Runner.new
runner.fetch_all_editions(
  {output_file}, <b class="conum">(1)</b>
  format: {format}, <b class="conum">(2)</b>
  max_pages: {max_pages} <b class="conum">(3)</b>
)
  1. Path to output file

  2. Output format (:json or :yaml)

  3. Optional maximum number of pages

Example 4. Saving publications to YAML
runner = RelatonAsme::Fetcher::Runner.new
runner.fetch_all_editions(
  "asme_publications.yml",
  format: :yaml,
  max_pages: 1
)

This fetches publications from the first API page, parses their JSON-LD data, and saves them as YAML to asme_publications.yml.

Data serialization

General

All data models support JSON and YAML serialization through lutaml-model.

Serializing to JSON

Example 5. Converting an edition to JSON
edition = RelatonAsme::Fetcher::AsmePublicationEdition.new(
  url: "https://www.asme.org/...",
  document_type: "standard",
  title: "BPVC Section I",
  document_identifier: "BPVC.I-2025",
  designator: "BPVC.I",
  edition_year: "2025",
  publisher: "ASME",
  publish_date: "2025",
  language: "EN"
)

json = edition.to_json
puts json

Note: edition_year is a String, not an Integer.

Pre-scraped database

General

A complete database of ASME publications has been pre-scraped and is available in data/asme_publication_editions.yml.

Database contents

The database contains:

  • 4,928 ASME publication editions

  • 269 unique ASME publications

  • Year range: 1967 - 2025 (58 years)

  • Formats: Print Book, PDF, Bundle

Loading the database

Example 6. Loading pre-scraped ASME data
require "yaml"

data = YAML.load_file(
  "data/asme_publication_editions.yml",
  permitted_classes: [Symbol]
)

puts "Loaded #{data.size} ASME editions"

# Find all editions for a specific designator
bpvc_editions = data.select { |e| e["designator"] == "BPVC.I" }
puts "BPVC.I has #{bpvc_editions.size} editions"

# Find editions by year
recent = data.select { |e| e["edition_year"].to_i >= 2020 }
puts "#{recent.size} editions from 2020 onwards"

Data model details

AsmePublicationEdition (Primary Model)

The primary data model containing all publication metadata for a specific edition.

Table 1. Attributes
Attribute Type Description

url

String

Direct link to publication page on asme.org

document_type

String

Type of document (typically "standard")

title

String

Edition title WITHOUT designator prefix, with year in parentheses

document_identifier

String

Edition-specific identifier (e.g., "BPVC.I-2025")

designator

String

ASME code/SKU (e.g., "BPVC.I", "B31.3", "Y14.5")

edition_year

String

Publication year as string (e.g., "2025", "2023")

publisher

String

Publisher name (always "ASME")

publish_date

String

Publication date (typically same as edition_year)

language

String

Language code (typically "EN")

number_of_pages

Integer

Page count (optional, not available in JSON-LD)

description

String

Detailed description (optional, not available in JSON-LD)

topics

Array<String>

Array of topic names (optional, not available in JSON-LD)

formats

Array<AsmeFormat>

Available formats and pricing from JSON-LD offers

AsmeFormat

Represents a publication format with pricing information extracted from JSON-LD offers.

Table 2. Attributes
Attribute Type Description

format_type

String

Format type (e.g., "PDF", "Print Book", "Bundle")

price

String

Price formatted as string (e.g., "$675.00")

isbn

String

ISBN number if available (optional, not in JSON-LD)

AsmePublication (Container)

Container model for grouping related publication editions.

Table 3. Attributes
Attribute Type Description

publication_group

String

Publication designator/SKU used for grouping

editions

Array<AsmePublicationEdition>

Array of publication editions with different years/formats

Development

After checking out the repo, run bundle install to install dependencies.

Run tests:

bundle exec rake spec

Run RuboCop:

bundle exec rake rubocop

Run all checks (tests + RuboCop):

bundle exec rake

Scraping ASME Publications

To scrape ASME publications and save to a file:

require "relaton_asme"

runner = RelatonAsme::Fetcher::Runner.new

# Fetch all publications (671 total, takes ~2 hours)
runner.fetch_all_editions(
  "data/asme_publications.yml",
  format: :yaml
)

# Or fetch just a few pages for testing
runner.fetch_all_editions(
  "data/sample.yml",
  format: :yaml,
  max_pages: 2
)

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/relaton/relaton-asme.

Copyright Ribose.

The gem is available as open source under the terms of the BSD-2-Clause License.