propublica-nonprofits 0.4.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9f22696c280743b8ad727b26a7e42d245a6860df751e93de02417ccec08f886d
4
- data.tar.gz: 633d7e23680142bb516fd2d5b5299fcd0c6db79a0162cfe5d4fb0d72f9961c77
3
+ metadata.gz: baea7efcfc907f93a2765cfff5c3343fdf17e817a09ac15160f1025990ceee5a
4
+ data.tar.gz: 1da616c76aa6cc85b49176018db027e75f5a7a39f9518abcc3a114190883fefe
5
5
  SHA512:
6
- metadata.gz: c7f1e635ba864223d2a962745d0643d67a77bc722dc1c07e8bd217e24ff80875a06ab9f9dbb12c03b5ca8ba6a2930ff94cdbb71773bd63b43bdf6dae993060fb
7
- data.tar.gz: 9a94138157fb0f95608cc181e1cb5fe071e42c1df9cec12004b6c0740b6f09b1f900689cade98616c88f41244613b258d17e0e03b462b38e38c898c341063fdb
6
+ metadata.gz: bf924b498d17cbea10dcf305ae1099359ebba0971d7f09cb6542d7c958be3e5309babd862be78e45674d93ec5d0d2c060374799f7daf9961c89b8aa441fd03fc
7
+ data.tar.gz: 93196885e1d02886c94e6b7e407b3ea552042dd348c3855fda889ad2a8c14992f681c115da932148934c731c9354844966f28c379c8f51a6135aad0d3811ed44
data/Gemfile.lock CHANGED
@@ -1,52 +1,38 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- propublica-nonprofits (0.4.1)
5
- faraday
4
+ propublica-nonprofits (1.1.0)
5
+ faraday (> 1.0, < 3.0)
6
6
  json
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
- addressable (2.8.0)
12
- public_suffix (>= 2.0.2, < 5.0)
11
+ addressable (2.8.1)
12
+ public_suffix (>= 2.0.2, < 6.0)
13
13
  coderay (1.1.2)
14
- crack (0.4.3)
15
- safe_yaml (~> 1.0.0)
16
- faraday (1.5.1)
17
- faraday-em_http (~> 1.0)
18
- faraday-em_synchrony (~> 1.0)
19
- faraday-excon (~> 1.1)
20
- faraday-httpclient (~> 1.0.1)
21
- faraday-net_http (~> 1.0)
22
- faraday-net_http_persistent (~> 1.1)
23
- faraday-patron (~> 1.0)
24
- multipart-post (>= 1.2, < 3)
14
+ crack (0.4.5)
15
+ rexml
16
+ faraday (2.7.2)
17
+ faraday-net_http (>= 2.0, < 3.1)
25
18
  ruby2_keywords (>= 0.0.4)
26
- faraday-em_http (1.0.0)
27
- faraday-em_synchrony (1.0.0)
28
- faraday-excon (1.1.0)
29
- faraday-httpclient (1.0.1)
30
- faraday-net_http (1.0.1)
31
- faraday-net_http_persistent (1.2.0)
32
- faraday-patron (1.0.0)
33
- hashdiff (1.0.0)
19
+ faraday-net_http (3.0.2)
20
+ hashdiff (1.0.1)
34
21
  json (2.5.1)
35
22
  method_source (0.9.0)
36
23
  minitest (5.11.3)
37
24
  minitest-line (0.6.5)
38
25
  minitest (~> 5.0)
39
- multipart-post (2.1.1)
40
26
  pry (0.11.3)
41
27
  coderay (~> 1.1.0)
42
28
  method_source (~> 0.9.0)
43
- public_suffix (4.0.6)
29
+ public_suffix (5.0.1)
44
30
  rake (13.0.1)
45
- ruby2_keywords (0.0.4)
46
- safe_yaml (1.0.5)
47
- vcr (4.0.0)
48
- webmock (3.7.6)
49
- addressable (>= 2.3.6)
31
+ rexml (3.2.5)
32
+ ruby2_keywords (0.0.5)
33
+ vcr (6.1.0)
34
+ webmock (3.18.1)
35
+ addressable (>= 2.8.0)
50
36
  crack (>= 0.3.2)
51
37
  hashdiff (>= 0.4.0, < 2.0.0)
52
38
 
@@ -60,8 +46,9 @@ DEPENDENCIES
60
46
  propublica-nonprofits!
61
47
  pry
62
48
  rake (~> 13.0)
49
+ rexml
63
50
  vcr
64
51
  webmock
65
52
 
66
53
  BUNDLED WITH
67
- 2.2.23
54
+ 2.3.10
data/README.md CHANGED
@@ -40,8 +40,11 @@ To search the API and return an array of Propublica::Nonprofits::Objects, use th
40
40
  result.details.deductibility_code
41
41
  result.filings_with_data.first.totassetsend
42
42
 
43
+ Want to be as memory and API efficient as possible? Be lazy!
44
+ `Propublica::Nonprofits.lazy_search("rural").first(10)` will only fetch first 10 items
45
+
43
46
  *Note: This will currently only return the first 100 organizations*
44
- *Note: This is returned as a Enumerator::Lazy, to be as memory efficient as possible, if you do something like `Propublica::Nonprofits.search("rural").first(10)`*
47
+ *Note: This is returned as an Array*
45
48
 
46
49
 
47
50
  ### EIN Lookup - As Organization
@@ -80,11 +83,6 @@ consider using the `find_attributes` method.
80
83
  attributes.dig("organization", "name")
81
84
  attributes.dig("filings_without_data").first.dig("pdf_url")
82
85
 
83
- ## TODO
84
-
85
- - Add more robust searching parameters https://projects.propublica.org/nonprofits/api/#endpoint-search-example
86
- - Handle paginated search results (with Enumerator::Lazy)
87
-
88
86
  ## Development
89
87
 
90
88
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -1,5 +1,5 @@
1
1
  module Propublica
2
2
  module Nonprofits
3
- VERSION = "0.4.1"
3
+ VERSION = "1.1.0"
4
4
  end
5
5
  end
@@ -5,62 +5,90 @@ require "faraday"
5
5
  require "json"
6
6
 
7
7
  API_BASE_URL = %(https://projects.propublica.org)
8
- API_SEARCH_PATH = %(/nonprofits/api/v2/search.json)
8
+ API_SEARCH_PATH = %(nonprofits/api/v2/search.json)
9
+
10
+ def self.results(column_names)
11
+ columns = column_names.each
12
+
13
+ Enumerator.new do |yielder|
14
+ loop do
15
+ yielder << Event.where(columns.next => query)
16
+ end
17
+
18
+ yielder << Event.fuzzy_search(query)
19
+ end
20
+ end
9
21
 
10
22
  module Propublica
11
23
  module Nonprofits
12
- def self.search(term, state: nil, page: nil, fetch_all: false)
13
- organizations = []
14
- more_pages = true
15
-
16
- page =
17
- case
18
- when page
19
- page
20
- when fetch_all && page
21
- raise "Page is set but we are fetching all, chose one or the other"
22
- else
23
- 0
24
- end
24
+ class DataNotFetched < StandardError
25
+ end
25
26
 
26
- while (more_pages)
27
- response = connection.get do |request|
28
- request.url(API_SEARCH_PATH)
27
+ def self.search(term, state: nil, ntee: nil, page: nil, fetch_all: false)
28
+ search_results(term, state: state, ntee: ntee, page: page, fetch_all: fetch_all)
29
+ .flat_map(&:itself)
30
+ end
29
31
 
30
- request.params["q"] = term
31
- request.params["state[id]"] = state if state
32
- request.params["page"] = page if page
33
- end
34
-
32
+ def self.lazy_search(term, state: nil, ntee: nil, page: nil, fetch_all: false)
33
+ search_results(term, state: state, ntee: ntee, page: page, fetch_all: fetch_all)
34
+ .lazy
35
+ .flat_map(&:itself)
36
+ end
35
37
 
36
- attributes = JSON.parse(response.body)
37
- new_organizations = attributes.fetch("organizations", [])
38
- organizations.push(*new_organizations)
38
+ def self.search_results(term, state: nil, ntee: nil, page: nil, fetch_all: false)
39
+ raise ArgumentError.new("`page` and `fetch_all` are both: choose one or the other") if fetch_all && page
40
+ page ||= 0
41
+ max_pages = nil
39
42
 
40
- more_pages = fetch_all && new_organizations.any?
41
- page += 1
42
- end
43
+ Enumerator.new do |yielder|
44
+ loop do
45
+ params = {}
46
+ params["q"] = term
47
+ params["state[id]"] = state if state
48
+ params["ntee[id]"] = ntee if ntee
49
+ params["page"] = page if page
43
50
 
44
- organizations.lazy.map do |basic_attrs|
45
- Propublica::Nonprofits::Organization.new("basic" => basic_attrs)
51
+ response = connection.get("/#{API_SEARCH_PATH}", params)
52
+ max_pages = response.body.dig("num_pages") || max_pages
53
+
54
+ yielder <<
55
+ response
56
+ .body
57
+ .fetch("organizations", [])
58
+ .map { |basic_attrs| Propublica::Nonprofits::Organization.new("basic" => basic_attrs) }
59
+
60
+ if fetch_all && page + 1 < max_pages
61
+ page += 1
62
+ else
63
+ raise(StopIteration)
64
+ end
65
+ end
46
66
  end
47
- end
48
67
 
49
- def self.find(ein)
50
- attributes = self.find_attributes(ein)
51
- Propublica::Nonprofits::Organization.new(attributes)
68
+ rescue JSON::ParserError => e
69
+ raise JSON::ParserError.new("Propublica API Parsing Error: #{e.message}")
52
70
  end
53
71
 
54
- def self.find_attributes(ein)
55
- response = connection.get("/nonprofits/api/v2/organizations/#{ein}.json")
56
- JSON.parse(response.body)
72
+ def self.find(ein)
73
+ Propublica::Nonprofits::Organization.new(
74
+ self.find_attributes(ein)
75
+ )
57
76
  end
58
77
 
59
78
  def self.connection
60
- @connection ||= Faraday.new(url: API_BASE_URL)
79
+ Faraday
80
+ .new(API_BASE_URL) do |f|
81
+ f.response :json
82
+ end
61
83
  end
62
84
 
63
- class Error < StandardError; end
64
- class DataNotFetched < Error; end
85
+ def self.find_attributes(ein)
86
+ connection
87
+ .get("/nonprofits/api/v2/organizations/#{ein}.json")
88
+ .body
89
+
90
+ rescue JSON::ParserError => e
91
+ raise JSON::ParserError.new("Propublica API Parsing Error: #{e.message}")
92
+ end
65
93
  end
66
94
  end
@@ -29,7 +29,8 @@ Gem::Specification.new do |spec|
29
29
  spec.add_development_dependency "rake", "~> 13.0"
30
30
  spec.add_development_dependency "vcr"
31
31
  spec.add_development_dependency "webmock"
32
+ spec.add_development_dependency "rexml"
32
33
 
33
- spec.add_dependency "faraday"
34
+ spec.add_dependency "faraday", "> 1.0", "< 3.0"
34
35
  spec.add_dependency "json"
35
36
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: propublica-nonprofits
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ricky Chilcott
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-07-13 00:00:00.000000000 Z
11
+ date: 2023-01-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -109,19 +109,39 @@ dependencies:
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
111
  - !ruby/object:Gem::Dependency
112
- name: faraday
112
+ name: rexml
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
115
  - - ">="
116
116
  - !ruby/object:Gem::Version
117
117
  version: '0'
118
- type: :runtime
118
+ type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - ">="
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: faraday
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">"
130
+ - !ruby/object:Gem::Version
131
+ version: '1.0'
132
+ - - "<"
133
+ - !ruby/object:Gem::Version
134
+ version: '3.0'
135
+ type: :runtime
136
+ prerelease: false
137
+ version_requirements: !ruby/object:Gem::Requirement
138
+ requirements:
139
+ - - ">"
140
+ - !ruby/object:Gem::Version
141
+ version: '1.0'
142
+ - - "<"
143
+ - !ruby/object:Gem::Version
144
+ version: '3.0'
125
145
  - !ruby/object:Gem::Dependency
126
146
  name: json
127
147
  requirement: !ruby/object:Gem::Requirement
@@ -183,7 +203,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
183
203
  - !ruby/object:Gem::Version
184
204
  version: '0'
185
205
  requirements: []
186
- rubygems_version: 3.1.2
206
+ rubygems_version: 3.2.32
187
207
  signing_key:
188
208
  specification_version: 4
189
209
  summary: Ruby wrapper for the Propublica Nonprofits API https://projects.propublica.org/nonprofits/api/v2