salad 0.0.1

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: 42dc06590c443b26abb03fc922c20cd33bd4e98b8e6c1f1ea712f2f28c2876bd
4
+ data.tar.gz: 3e052ddf1ef6c281b21526b87889dfac0800102866c88658c58a8853ef9007bd
5
+ SHA512:
6
+ metadata.gz: 684e41e46f78e3989541df37d955a48b3f03fd2f0e55792b3169dd913b89483d08a82f74994562debf015e9e5c41fe4ab5b4a2a83d8156a174e6a7751318e405
7
+ data.tar.gz: c224a4919a4ea9a8b8507708efee64ea4917726a85c1632e0ea446dc9f343ce075f8f4ea396d8e1e767148b4fc840af3fa5bd0eba833907594b9575813462752
data/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ ## [Unreleased]
2
+
3
+ ## [0.0.1] - 2026-06-04
4
+
5
+ - Initial release
data/LICENSE.txt ADDED
@@ -0,0 +1,9 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright © 2026 Species File Group
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,123 @@
1
+ # Salad
2
+
3
+ <img width="200" height="200" alt="TaxonWorks Labs" src="https://github.com/user-attachments/assets/aed6a9d3-e737-4954-861c-99dfc3f89040" />
4
+
5
+ TaxonWorks Labs Product
6
+
7
+ `salad` is a meta-gem that bundles the [SpeciesFileGroup](https://github.com/SpeciesFileGroup) Ruby API wrappers into a single package and ships a `salad` executable that drops you into a [Pry](https://github.com/pry/pry) console with every service pre-loaded. It's a one-stop REPL for exploring biodiversity informatics APIs without bouncing between repos or firing up the full TaxonWorks Rails app.
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ ```ruby
14
+ gem 'salad'
15
+ ```
16
+
17
+ And then execute:
18
+
19
+ $ bundle install
20
+
21
+ Or install it yourself as:
22
+
23
+ $ gem install salad
24
+
25
+ ## Usage
26
+
27
+ Launch the console from your terminal:
28
+
29
+ ```
30
+ $ salad
31
+ salad v0.0.1 — type `help` to list services, `hints` for tips.
32
+ salad>
33
+ ```
34
+
35
+ List every bundled service and the two ways to access it:
36
+
37
+ ```
38
+ help Salad
39
+ ```
40
+
41
+ ```
42
+ === Salad Services ===
43
+ Access bundled biodiversity informatics API wrappers by service name or gem name:
44
+ Salad.bels Salad.bell_pepper -> BellPepper
45
+ Salad.bhlnames Salad.bok_choy -> BokChoy
46
+ Salad.bionomia Salad.bananomia -> Bananomia
47
+ Salad.catalogue_of_life Salad.colrapi -> Colrapi
48
+ Salad.checklistbank Salad.colrapi -> Colrapi
49
+ Salad.clb Salad.colrapi -> Colrapi
50
+ Salad.col Salad.colrapi -> Colrapi
51
+ Salad.gnverifier Salad.checkerberry -> Checkerberry
52
+ Salad.inaturalist Salad.nasturtium -> Nasturtium
53
+ Salad.openalex Salad.syconium -> Syconium
54
+ Salad.owl Salad.hookkaido -> Hookkaido
55
+ Salad.plazi Salad.plazucchini -> Plazucchini
56
+ Salad.wikidata Salad.wikimelon -> Wikimelon
57
+ Salad.worms Salad.crawlyflower -> Crawlyflower
58
+ ```
59
+
60
+ Each wrapper is also available under its own top-level constant, so anything you'd do in an individual gem's console works here too:
61
+
62
+ ```ruby
63
+ Crawlyflower.record(127160)
64
+ Nasturtium::Observation.find(42)
65
+ BellPepper.georeference("University of Illinois, Urbana, IL")
66
+ ```
67
+
68
+ ### Accessing services
69
+
70
+ Three equivalent styles are supported — pick whichever you find most readable:
71
+
72
+ ```ruby
73
+ Salad.inaturalist # service name
74
+ Salad.nasturtium # gem name (keeps the produce pun alive)
75
+ Nasturtium # raw top-level constant
76
+ ```
77
+
78
+ All three return the same module.
79
+
80
+ ### Using `salad` as a library
81
+
82
+ You can also `require 'salad'` from your own code to load all wrappers at once:
83
+
84
+ ```ruby
85
+ require 'salad'
86
+
87
+ Salad.worms.record(127160)
88
+ Salad.openalex.works(filter: { "authorships.author.id" => "A5023888391" })
89
+ ```
90
+
91
+ ## Included gems
92
+
93
+ | Service | Gem | API |
94
+ | -------------------- | ---------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
95
+ | `Salad.bels` | [`bell_pepper`](https://github.com/SpeciesFileGroup/bell_pepper) | [BELS Georeference](https://bels.geo-vocab.org/) |
96
+ | `Salad.bhlnames` | [`bok_choy`](https://github.com/SpeciesFileGroup/bok_choy) | [BHLnames](https://bhlnames.globalnames.org/) |
97
+ | `Salad.bionomia` | [`bananomia`](https://github.com/SpeciesFileGroup/bananomia) | [Bionomia](https://bionomia.net/) |
98
+ | `Salad.col` | [`colrapi`](https://github.com/SpeciesFileGroup/colrapi) | [Catalogue of Life / ChecklistBank](https://www.checklistbank.org/) |
99
+ | `Salad.gnverifier` | [`checkerberry`](https://github.com/SpeciesFileGroup/checkerberry) | [GNverifier](https://verifier.globalnames.org/) |
100
+ | `Salad.inaturalist` | [`nasturtium`](https://github.com/SpeciesFileGroup/nasturtium) | [iNaturalist](https://www.inaturalist.org/) |
101
+ | `Salad.openalex` | [`syconium`](https://github.com/SpeciesFileGroup/syconium) | [OpenAlex](https://openalex.org/) |
102
+ | `Salad.owl` | [`hookkaido`](https://github.com/SpeciesFileGroup/hookkaido) | [Ontology Lookup Service (OLS)](https://www.ebi.ac.uk/ols4/) |
103
+ | `Salad.plazi` | [`plazucchini`](https://github.com/SpeciesFileGroup/plazucchini) | [Plazi TreatmentBank](https://www.plazi.org/) |
104
+ | `Salad.wikidata` | [`wikimelon`](https://github.com/SpeciesFileGroup/wikimelon) | [Wikidata](https://www.wikidata.org/) |
105
+ | `Salad.worms` | [`crawlyflower`](https://github.com/SpeciesFileGroup/crawlyflower) | [WoRMS](https://www.marinespecies.org/rest/) |
106
+
107
+ Because `salad` installs each wrapper as a normal runtime dependency, you can freely mix it into a project that already depends on individual wrappers — Bundler will resolve them to compatible versions.
108
+
109
+ ## Development
110
+
111
+ After checking out the repo, run `bundle install` to install dependencies. Run `bin/console` for an interactive prompt that will allow you to experiment (this is the same console shipped by the `salad` executable, but it uses your local working copy of the gem).
112
+
113
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `lib/salad/version.rb`, update the CHANGELOG.md, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the .gem file to rubygems.org.
114
+
115
+ ## License
116
+
117
+ The gem is available as open source under the terms of the [MIT license](https://github.com/SpeciesFileGroup/salad/blob/main/LICENSE.txt). You can learn more about the MIT license on [Wikipedia](https://en.wikipedia.org/wiki/MIT_License) and compare it with other open source licenses at the [Open Source Initiative](https://opensource.org/license/mit/).
118
+
119
+ Third-party licensing and attribution details for vendored code are listed in [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md).
120
+
121
+ ## Code of Conduct
122
+
123
+ Everyone interacting in the Salad project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/SpeciesFileGroup/salad/blob/main/CODE_OF_CONDUCT.md).
data/exe/salad ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'salad/console'
5
+ Salad.console
@@ -0,0 +1,104 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Vendored from pry-bond 0.0.1 (https://github.com/pry/pry-bond), modified for
4
+ # compatibility with current Pry. Only the Pry <-> Bond completer shim is kept;
5
+ # pry-bond's enable-bond!/disable-bond! commands are dropped (Salad always uses
6
+ # Bond) and the readline integration is replaced with a no-op shim because Pry
7
+ # drives Readline itself.
8
+ #
9
+ # Original copyright notice from pry-bond/LICENSE.txt:
10
+ # ---------------------------------------------------------------------------
11
+ # (The MIT License)
12
+ #
13
+ # Copyright (c) 2014 The Pry Team
14
+ #
15
+ # Permission is hereby granted, free of charge, to any person obtaining
16
+ # a copy of this software and associated documentation files (the
17
+ # 'Software'), to deal in the Software without restriction, including
18
+ # without limitation the rights to use, copy, modify, merge, publish,
19
+ # distribute, sublicense, and/or sell copies of the Software, and to
20
+ # permit persons to whom the Software is furnished to do so, subject to
21
+ # the following conditions:
22
+ #
23
+ # The above copyright notice and this permission notice shall be
24
+ # included in all copies or substantial portions of the Software.
25
+ #
26
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
27
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
29
+ # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
30
+ # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
31
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
32
+ # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33
+ # ---------------------------------------------------------------------------
34
+
35
+ # Loaded before 'pry' so that Pry's `require 'readline'` resolves to
36
+ # rb-readline's pure-Ruby Readline rather than Reline. Reline's tab-completion
37
+ # display differs (e.g. TAB-TAB on an empty prefix doesn't list candidates),
38
+ # which would break Salad's param completion at `Salad.x.method(<TAB><TAB>`.
39
+ require 'rb-readline'
40
+ require 'pry'
41
+ require 'bond'
42
+
43
+ # Pry drives Readline itself and feeds the line buffer to Bond via
44
+ # Pry::BondCompleter#get_full_line_input, so Bond's Agent never needs to set up
45
+ # Readline on its own. Without a plugin here, Agent#setup_readline(nil) rescues
46
+ # internally and prints "Bond Error: Failed setup with 'undefined method
47
+ # 'setup' for nil'" on first complete() call. A no-op plugin silences it.
48
+ Bond::M.config[:readline] = Module.new do
49
+ def self.setup(_agent); end
50
+ def self.line_buffer; ''; end
51
+ end
52
+
53
+ class Pry::BondCompleter
54
+ class << self
55
+ attr_reader :bond
56
+ end
57
+
58
+ def self.setup(config = {})
59
+ @lock ||= Mutex.new
60
+ return if @bond
61
+
62
+ @bond = Bond::M
63
+ @bond.config.merge!(config)
64
+ @current_pry_instance = nil
65
+ # Don't call start here - Bond will initialize when needed
66
+ end
67
+
68
+ def self.with_pry(instance)
69
+ @lock ||= Mutex.new
70
+ @lock.synchronize do
71
+ begin
72
+ @current_pry_instance = instance
73
+ yield
74
+ ensure
75
+ @current_pry_instance = nil
76
+ end
77
+ end
78
+ end
79
+
80
+ def initialize(input, pry = nil)
81
+ @pry = pry
82
+ @input = input
83
+ end
84
+
85
+ def call(str, _options)
86
+ Pry::BondCompleter.setup if Pry::BondCompleter.bond.nil?
87
+
88
+ Pry::BondCompleter.with_pry(@pry) do
89
+ Pry::BondCompleter.bond.agent.call(str, get_full_line_input || str)
90
+ end
91
+ end
92
+
93
+ protected
94
+
95
+ def get_full_line_input
96
+ if @input.respond_to?(:line_buffer)
97
+ @input.line_buffer
98
+ elsif @input.respond_to?(:line)
99
+ @input.line
100
+ end
101
+ end
102
+ end
103
+
104
+ Pry.config.completer = Pry::BondCompleter
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Salad
4
+ # Wraps Colrapi so calls are scoped to a Catalogue of Life dataset by default.
5
+ # Users override by passing dataset_id explicitly — as a positional arg for
6
+ # methods that take it positionally, or as a kwarg otherwise.
7
+ class CatalogueOfLife
8
+ DEFAULT_DATASET_ID = '3LR'
9
+
10
+ def initialize(mod = Colrapi)
11
+ @mod = mod
12
+ end
13
+
14
+ def method_missing(name, *args, **kwargs, &block)
15
+ return super unless @mod.respond_to?(name)
16
+
17
+ ds_param = @mod.method(name).parameters.find { |_, pname| pname == :dataset_id }
18
+
19
+ if ds_param
20
+ case ds_param[0]
21
+ when :req
22
+ args = [DEFAULT_DATASET_ID] if args.empty?
23
+ when :key, :keyreq
24
+ kwargs[:dataset_id] = DEFAULT_DATASET_ID unless kwargs.key?(:dataset_id)
25
+ end
26
+ end
27
+
28
+ @mod.public_send(name, *args, **kwargs, &block)
29
+ end
30
+
31
+ def respond_to_missing?(name, include_private = false)
32
+ @mod.respond_to?(name, include_private) || super
33
+ end
34
+
35
+ def to_s
36
+ @mod.to_s
37
+ end
38
+
39
+ def inspect
40
+ "#<Salad::CatalogueOfLife(default dataset_id=#{DEFAULT_DATASET_ID})>"
41
+ end
42
+ end
43
+ end