Class: DurableHuggingfaceHub::RepoCard

Inherits:
Object
  • Object
show all
Defined in:
lib/durable_huggingface_hub/repo_card.rb

Overview

Base class for repository cards (README.md files with YAML frontmatter).

Repository cards contain metadata and documentation for models, datasets, and spaces on the HuggingFace Hub. They consist of YAML frontmatter followed by markdown content.

Examples:

Load a model card from the Hub

card = DurableHuggingfaceHub::ModelCard.load("bert-base-uncased")
puts card.data["license"]
puts card.text

Create and save a new model card

card = DurableHuggingfaceHub::ModelCard.new(
  text: "# My Model\n\nThis is my model.",
  data: { "license" => "mit", "language" => "en" }
)
card.save("my-model/README.md")

Direct Known Subclasses

DatasetCard, ModelCard, SpaceCard

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(text: "", data: {}) ⇒ RepoCard

Initialize a new RepoCard

Parameters:

  • text (String) (defaults to: "")

    Markdown content

  • data (Hash) (defaults to: {})

    Metadata dictionary



37
38
39
40
# File 'lib/durable_huggingface_hub/repo_card.rb', line 37

def initialize(text: "", data: {})
  @text = text || ""
  @data = data || {}
end

Instance Attribute Details

#dataHash

Returns Metadata from YAML frontmatter.

Returns:

  • (Hash)

    Metadata from YAML frontmatter



28
29
30
# File 'lib/durable_huggingface_hub/repo_card.rb', line 28

def data
  @data
end

#textString

Returns Markdown content (without frontmatter).

Returns:

  • (String)

    Markdown content (without frontmatter)



31
32
33
# File 'lib/durable_huggingface_hub/repo_card.rb', line 31

def text
  @text
end

Class Method Details

.default_repo_typeString

Default repository type for this card class. Subclasses should override this.

Returns:

  • (String)

    Default repository type



216
217
218
# File 'lib/durable_huggingface_hub/repo_card.rb', line 216

def self.default_repo_type
  "model"
end

.from_hub(repo_id, repo_type: nil, revision: nil, token: nil, timeout: nil) ⇒ RepoCard

Load a repository card from the HuggingFace Hub.

Examples:

Load model card from Hub

card = ModelCard.from_hub("bert-base-uncased")

Parameters:

  • repo_id (String)

    Repository ID

  • repo_type (String, Symbol) (defaults to: nil)

    Type of repository (“model”, “dataset”, or “space”)

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

    Git revision (branch, tag, or commit SHA)

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

    HuggingFace API token

  • timeout (Numeric, nil) (defaults to: nil)

    Request timeout in seconds

Returns:

  • (RepoCard)

    The loaded repository card

Raises:



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/durable_huggingface_hub/repo_card.rb', line 71

def self.from_hub(repo_id, repo_type: nil, revision: nil, token: nil, timeout: nil)
  Utils::Validators.validate_repo_id(repo_id)
  repo_type ||= self.default_repo_type
  repo_type = Utils::Validators.validate_repo_type(repo_type)

  api = HfApi.new(token: token)

  # Build URL for README.md
  url_path = "/#{repo_type}s/#{repo_id}/resolve/#{revision || 'main'}/README.md"

  begin
    response = api.http_client.get(url_path, timeout: timeout)
    content = response.body
    parse(content)
  rescue HfHubHTTPError => e
    if e.status_code == 404
      raise EntryNotFoundError, "README.md not found in #{repo_id}"
    else
      raise
    end
  end
end

.load(file_path) ⇒ RepoCard

Load a repository card from a file.

Examples:

Load from local file

card = RepoCard.load("path/to/README.md")

Parameters:

  • file_path (String, Pathname)

    Path to the README.md file

Returns:

  • (RepoCard)

    The loaded repository card

Raises:

  • (ArgumentError)


49
50
51
52
53
54
55
# File 'lib/durable_huggingface_hub/repo_card.rb', line 49

def self.load(file_path)
  file_path = Pathname(file_path)
  raise ArgumentError, "File not found: #{file_path}" unless file_path.exist?

  content = file_path.read
  parse(content)
end

.parse(content) ⇒ RepoCard

Parse repository card content (YAML frontmatter + markdown).

Examples:

Parse content string

content = "---\nlicense: mit\n---\n# My Model"
card = RepoCard.parse(content)

Parameters:

  • content (String)

    Full content of README.md

Returns:



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/durable_huggingface_hub/repo_card.rb', line 102

def self.parse(content)
  # Check for YAML frontmatter (starts with ---)
  if content.start_with?("---\n")
    # Find the closing ---
    end_index = content.index("\n---\n", 4)

    if end_index
      # Extract YAML frontmatter
      yaml_content = content[4...end_index]
      markdown_content = content[(end_index + 5)..-1] || ""

      begin
         = YAML.safe_load(yaml_content, permitted_classes: [Date, Time]) || {}
      rescue Psych::SyntaxError => e
        warn "Failed to parse YAML frontmatter: #{e.message}"
         = {}
      end

      new(text: markdown_content.strip, data: )
    else
      # No closing ---, treat everything as content
      new(text: content)
    end
  else
    # No frontmatter
    new(text: content)
  end
end

Instance Method Details

#push_to_hub(repo_id, repo_type: self.class.default_repo_type, revision: nil, commit_message: nil, commit_description: nil, token: nil, timeout: nil) ⇒ String

Push the repository card to the HuggingFace Hub.

Examples:

Push to Hub

card.push_to_hub("my-username/my-model")

Parameters:

  • repo_id (String)

    Repository ID

  • repo_type (String, Symbol) (defaults to: self.class.default_repo_type)

    Type of repository

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

    Git revision to push to

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

    Commit message

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

    Commit description

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

    HuggingFace API token

  • timeout (Numeric, nil) (defaults to: nil)

    Request timeout in seconds

Returns:

  • (String)

    URL of the uploaded README.md



172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
# File 'lib/durable_huggingface_hub/repo_card.rb', line 172

def push_to_hub(
  repo_id,
  repo_type: self.class.default_repo_type,
  revision: nil,
  commit_message: nil,
  commit_description: nil,
  token: nil,
  timeout: nil
)
  api = HfApi.new(token: token)

  # Create a temporary file with the content
  require "tempfile"
  Tempfile.create(["README", ".md"]) do |temp_file|
    temp_file.write(to_s)
    temp_file.flush

    api.upload_file(
      repo_id: repo_id,
      path_or_fileobj: temp_file.path,
      path_in_repo: "README.md",
      repo_type: repo_type,
      revision: revision,
      commit_message: commit_message || "Update README.md",
      commit_description: commit_description,
      timeout: timeout
    )
  end
end

#save(file_path) ⇒ Object

Save the repository card to a file.

Examples:

Save to local file

card.save("my-model/README.md")

Parameters:

  • file_path (String, Pathname)

    Path to save the README.md file



153
154
155
156
157
# File 'lib/durable_huggingface_hub/repo_card.rb', line 153

def save(file_path)
  file_path = Pathname(file_path)
  file_path.dirname.mkpath # Create parent directories if needed
  file_path.write(to_s)
end

#to_sString

Convert the repository card to a string (YAML frontmatter + markdown).

Examples:

Convert to string

content = card.to_s
File.write("README.md", content)

Returns:

  • (String)

    Full content with frontmatter



138
139
140
141
142
143
144
145
# File 'lib/durable_huggingface_hub/repo_card.rb', line 138

def to_s
  if @data.empty?
    @text
  else
    yaml_str = YAML.dump(@data).sub(/^---\n/, "")
    "---\n#{yaml_str}---\n\n#{@text}"
  end
end

#update_metadata(updates) ⇒ Object

Update the metadata in the repository card.

Examples:

Update metadata

card.({ "license" => "apache-2.0" })

Parameters:

  • updates (Hash)

    Metadata updates to merge



208
209
210
# File 'lib/durable_huggingface_hub/repo_card.rb', line 208

def (updates)
  @data.merge!(updates)
end

#validateArray<String>

Validate the repository card metadata. Subclasses can override this to add specific validation.

Returns:

  • (Array<String>)

    List of validation errors (empty if valid)



224
225
226
# File 'lib/durable_huggingface_hub/repo_card.rb', line 224

def validate
  []
end