Skip to content

Commit 8bcac0d

Browse files
authored
Merge pull request #34 from TheEmeraldBee/enrichment_etag
Add etag to us_enrichment_api Add geo reference data Add secondary data set
2 parents 839a176 + c37ff8d commit 8bcac0d

File tree

13 files changed

+453
-200
lines changed

13 files changed

+453
-200
lines changed

.gitignore

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,18 @@
1414
*.swp
1515
*.iml
1616
__MACOSX
17+
18+
# Devenv
19+
.devenv*
20+
devenv.local.nix
21+
22+
# direnv
23+
.direnv
24+
25+
# pre-commit
26+
.pre-commit-config.yaml
27+
28+
devenv.lock
29+
devenv.nix
30+
devenv.yaml
31+
.envrc

Makefile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ us_street_api:
4747
us_zipcode_api:
4848
RUST_LOG=trace cargo run --example us_zipcode_api
4949

50+
us_enrichment_api:
51+
RUST_LOG=trace cargo run --example us_enrichment_api
52+
5053
examples: international_autocomplete_api international_street_api logger us_autocomplete_pro_api us_extract_api us_reverse_geo_api us_street_api us_zipcode_api
5154

52-
.PHONY: clean test dependencies package examples clippy international_autocomplete_api international_street_api logger us_autocomplete_pro_api us_extract_api us_reverse_geo_api us_street_api us_zipcode_api
55+
.PHONY: clean test dependencies package examples clippy international_autocomplete_api international_street_api logger us_autocomplete_pro_api us_extract_api us_reverse_geo_api us_street_api us_zipcode_api us_enrichment_api

smarty-rust-sdk/examples/us_enrichment_api.rs

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
use smarty_rust_sdk::sdk::authentication::SecretKeyCredential;
22
use smarty_rust_sdk::sdk::options::OptionsBuilder;
3-
use smarty_rust_sdk::us_enrichment_api::client::USEnrichmentClient;
3+
4+
use smarty_rust_sdk::us_enrichment_api::client::*;
5+
use smarty_rust_sdk::us_enrichment_api::financial::*;
6+
use smarty_rust_sdk::us_enrichment_api::geo::*;
7+
use smarty_rust_sdk::us_enrichment_api::principal::*;
8+
49
use smarty_rust_sdk::us_enrichment_api::lookup::EnrichmentLookup;
5-
use smarty_rust_sdk::us_enrichment_api::results::{
6-
EnrichmentResponse, FinancialResponse, PrincipalResponse,
7-
};
10+
use smarty_rust_sdk::us_enrichment_api::response::EnrichmentResponse;
11+
use smarty_rust_sdk::us_enrichment_api::secondary::SecondaryCountResponse;
12+
use smarty_rust_sdk::us_enrichment_api::secondary::SecondaryResponse;
13+
814
use std::error::Error;
915

1016
#[tokio::main]
@@ -13,12 +19,21 @@ async fn main() -> Result<(), Box<dyn Error>> {
1319

1420
lookup::<FinancialResponse>(key).await?;
1521
lookup::<PrincipalResponse>(key).await?;
22+
lookup::<GeoReferenceResponse>(key).await?;
23+
lookup::<GeoReference2010Response>(key).await?;
24+
lookup::<GeoReference2020Response>(key).await?;
25+
lookup::<SecondaryResponse>(key).await?;
26+
lookup::<SecondaryCountResponse>(key).await?;
1627

1728
Ok(())
1829
}
1930

2031
async fn lookup<R: EnrichmentResponse>(key: u32) -> Result<(), Box<dyn Error>> {
21-
let mut lookup = EnrichmentLookup::<R>::new(key);
32+
let mut lookup = EnrichmentLookup::<R> {
33+
smarty_key: key,
34+
etag: "".to_string(),
35+
..Default::default()
36+
};
2237

2338
let authentication = SecretKeyCredential::new(
2439
std::env::var("SMARTY_AUTH_ID").expect("Missing SMARTY_AUTH_ID env variable"),

smarty-rust-sdk/src/sdk/client.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,10 @@ impl Client {
5454
if let Some(auth) = &self.options.authentication {
5555
builder = auth.authenticate(builder);
5656
}
57-
58-
builder = builder.query(&[("license".to_string(), self.options.license.clone())]);
57+
58+
if !self.options.license.is_empty() {
59+
builder = builder.query(&[("license".to_string(), self.options.license.clone())]);
60+
}
5961

6062
for (header_key, header_value) in self.options.headers.clone() {
6163
builder = builder.header(header_key, header_value);

smarty-rust-sdk/src/sdk/mod.rs

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::sdk::error::SmartyError;
2+
use reqwest::Response;
23
use reqwest_middleware::RequestBuilder;
34
use serde::de::DeserializeOwned;
45
use serde_repr::{Deserialize_repr, Serialize_repr};
@@ -36,15 +37,16 @@ impl Display for CoordinateLicense {
3637
}
3738
}
3839

39-
pub(crate) async fn send_request<C>(request: RequestBuilder) -> Result<C, SmartyError>
40-
where
41-
C: DeserializeOwned,
42-
{
43-
let response = request.send().await.map_err(|e| match e {
40+
pub(crate) async fn send_request_full(request: RequestBuilder) -> Result<Response, SmartyError> {
41+
request.send().await.map_err(|e| match e {
4442
reqwest_middleware::Error::Middleware(e) => SmartyError::from(e),
4543
reqwest_middleware::Error::Reqwest(e) => SmartyError::from(e),
46-
})?;
44+
})
45+
}
4746

47+
pub(crate) async fn parse_response_json<C: DeserializeOwned>(
48+
response: Response,
49+
) -> Result<C, SmartyError> {
4850
if !response.status().is_success() {
4951
let status_code = response.status();
5052
let body = response.text().await?;
@@ -58,6 +60,13 @@ where
5860
Ok(response.json::<C>().await?)
5961
}
6062

63+
pub(crate) async fn send_request<C: DeserializeOwned>(
64+
request: RequestBuilder,
65+
) -> Result<C, SmartyError> {
66+
let response = send_request_full(request).await?;
67+
parse_response_json(response).await
68+
}
69+
6170
/// This is only used for Serializing for post
6271
#[allow(clippy::trivially_copy_pass_by_ref)]
6372
pub(crate) fn is_zero(num: &i64) -> bool {

smarty-rust-sdk/src/us_enrichment_api/client.rs

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
use crate::sdk::client::Client;
22
use crate::sdk::error::SmartyError;
33
use crate::sdk::options::Options;
4-
use crate::sdk::send_request;
4+
use crate::sdk::{parse_response_json, send_request_full};
55
use crate::us_enrichment_api::lookup::EnrichmentLookup;
6-
use crate::us_enrichment_api::results::EnrichmentResponse;
76
use reqwest::Method;
8-
use serde::de::DeserializeOwned;
97
use smarty_rust_proc_macro::smarty_api;
108

9+
use super::response::EnrichmentResponse;
10+
1111
#[smarty_api(
1212
api_path = "lookup",
1313
default_url = "https://us-enrichment.api.smarty.com/",
@@ -22,21 +22,37 @@ impl USEnrichmentClient {
2222
/// Uses the lookup and the client in
2323
/// order to build a request and send the message
2424
/// to the server.
25-
pub async fn send<R: EnrichmentResponse + DeserializeOwned>(
25+
pub async fn send<R: EnrichmentResponse>(
2626
&self,
2727
lookup: &mut EnrichmentLookup<R>,
2828
) -> Result<(), SmartyError> {
2929
let mut url = self.client.url.clone();
3030
url = url.join(&format!(
31-
"/lookup/{}/property/{}",
31+
"/lookup/{}/{}",
3232
lookup.smarty_key,
3333
R::lookup_type()
3434
))?;
3535

3636
let mut req = self.client.reqwest_client.request(Method::GET, url);
37+
38+
if !lookup.etag.is_empty() {
39+
req = req.header("ETag", &lookup.etag);
40+
}
41+
3742
req = self.client.build_request(req);
3843

39-
let candidates = send_request::<Vec<R>>(req).await?;
44+
println!("{req:?}");
45+
46+
let response = send_request_full(req).await?;
47+
48+
let etag = response
49+
.headers()
50+
.get("ETag")
51+
.map(|x| x.to_str().expect("ETag should always be a string"))
52+
.unwrap_or_default();
53+
lookup.etag = etag.to_string();
54+
55+
let candidates = parse_response_json(response).await?;
4056

4157
lookup.set_results(candidates);
4258

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
use serde::Deserialize;
2+
use serde::Serialize;
3+
use std::fmt::Debug;
4+
5+
use super::response::EnrichmentResponse;
6+
7+
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
8+
pub struct FinancialResponse {
9+
pub smarty_key: String,
10+
pub data_set_name: String,
11+
pub data_subset_name: String,
12+
pub attributes: FinancialAttributes,
13+
}
14+
15+
impl EnrichmentResponse for FinancialResponse {
16+
fn lookup_type() -> &'static str {
17+
"property/financial"
18+
}
19+
}
20+
21+
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
22+
#[serde(default)]
23+
pub struct FinancialAttributes {
24+
pub assessed_improvement_percent: String,
25+
pub assessed_improvement_value: String,
26+
pub assessed_land_value: String,
27+
pub assessed_value: String,
28+
pub assessor_last_update: String,
29+
pub assessor_taxroll_update: String,
30+
pub contact_city: String,
31+
pub contact_crrt: String,
32+
pub contact_full_address: String,
33+
pub contact_house_number: String,
34+
pub contact_mail_info_format: String,
35+
pub contact_mail_info_privacy: String,
36+
pub contact_mailing_county: String,
37+
pub contact_mailing_fips: String,
38+
pub contact_post_direction: String,
39+
pub contact_pre_direction: String,
40+
pub contact_state: String,
41+
pub contact_street_name: String,
42+
pub contact_suffix: String,
43+
pub contact_unit_designator: String,
44+
pub contact_value: String,
45+
pub contact_zip: String,
46+
pub contact_zip4: String,
47+
pub deed_document_page: String,
48+
pub deed_document_book: String,
49+
pub deed_document_number: String,
50+
pub deed_owner_first_name: String,
51+
pub deed_owner_first_name2: String,
52+
pub deed_owner_first_name3: String,
53+
pub deed_owner_first_name4: String,
54+
pub deed_owner_full_name: String,
55+
pub deed_owner_full_name2: String,
56+
pub deed_owner_full_name3: String,
57+
pub deed_owner_full_name4: String,
58+
pub deed_owner_last_name: String,
59+
pub deed_owner_last_name2: String,
60+
pub deed_owner_last_name3: String,
61+
pub deed_owner_last_name4: String,
62+
pub deed_owner_middle_name: String,
63+
pub deed_owner_middle_name2: String,
64+
pub deed_owner_middle_name3: String,
65+
pub deed_owner_middle_name4: String,
66+
pub deed_owner_suffix: String,
67+
pub deed_owner_suffix2: String,
68+
pub deed_owner_suffix3: String,
69+
pub deed_owner_suffix4: String,
70+
pub deed_sale_date: String,
71+
pub deed_sale_price: String,
72+
pub deed_transaction_id: String,
73+
pub disabled_tax_exemption: String,
74+
pub financial_history: Vec<FinancialHistory>,
75+
pub first_name: String,
76+
pub first_name_2: String,
77+
pub first_name_3: String,
78+
pub first_name_4: String,
79+
pub homeowner_tax_exemption: String,
80+
pub last_name: String,
81+
pub last_name_2: String,
82+
pub last_name_3: String,
83+
pub last_name_4: String,
84+
pub market_improvement_percent: String,
85+
pub market_improvement_value: String,
86+
pub market_land_value: String,
87+
pub market_value_year: String,
88+
pub match_type: String,
89+
pub middle_name: String,
90+
pub middle_name_2: String,
91+
pub middle_name_3: String,
92+
pub middle_name_4: String,
93+
pub other_tax_exemption: String,
94+
pub owner_full_name: String,
95+
pub owner_full_name_2: String,
96+
pub owner_full_name_3: String,
97+
pub owner_full_name_4: String,
98+
pub ownership_transfer_date: String,
99+
pub ownership_transfer_doc_number: String,
100+
pub ownership_transfer_transaction_id: String,
101+
pub ownership_type: String,
102+
pub ownership_type_2: String,
103+
pub previous_assessed_value: String,
104+
pub prior_sale_amount: String,
105+
pub prior_sale_date: String,
106+
pub sale_amount: String,
107+
pub sale_date: String,
108+
pub senior_tax_exemption: String,
109+
pub suffix: String,
110+
pub suffix_2: String,
111+
pub suffix_3: String,
112+
pub suffix_4: String,
113+
pub tax_assess_year: String,
114+
pub tax_billed_amount: String,
115+
pub tax_delinquent_year: String,
116+
pub tax_fiscal_year: String,
117+
pub tax_rate_area: String,
118+
pub total_market_value: String,
119+
pub trust_description: String,
120+
pub veteran_tax_exemption: String,
121+
pub widow_tax_exemption: String,
122+
}
123+
124+
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
125+
#[serde(default)]
126+
pub struct FinancialHistory {
127+
pub code_title_company: String,
128+
pub document_type_description: String,
129+
pub instrument_date: String,
130+
pub interest_rate_type_2: String,
131+
pub lender_address: String,
132+
pub lender_address_2: String,
133+
pub lender_city: String,
134+
pub lender_city_2: String,
135+
pub lender_code_2: String,
136+
pub lender_first_name: String,
137+
pub lender_first_name_2: String,
138+
pub lender_last_name: String,
139+
pub lender_last_name_2: String,
140+
pub lender_name: String,
141+
pub lender_name_2: String,
142+
pub lender_seller_carry_back: String,
143+
pub lender_seller_carry_back_2: String,
144+
pub lender_state: String,
145+
pub lender_state_2: String,
146+
pub lender_zip: String,
147+
pub lender_zip_2: String,
148+
pub lender_zip_extended: String,
149+
pub lender_zip_extended_2: String,
150+
pub mortgage_amount: String,
151+
pub mortgage_amount_2: String,
152+
pub mortgage_due_date: String,
153+
pub mortgage_due_date_2: String,
154+
pub mortgage_interest_rate: String,
155+
pub mortgage_interest_rate_type: String,
156+
pub mortgage_lender_code: String,
157+
pub mortgage_rate_2: String,
158+
pub mortgage_recording_date: String,
159+
pub mortgage_recording_date_2: String,
160+
pub mortgage_term: String,
161+
pub mortgage_term_2: String,
162+
pub mortgage_term_type: String,
163+
pub mortgage_term_type_2: String,
164+
pub mortgage_type: String,
165+
pub mortgage_type_2: String,
166+
pub multi_parcel_flag: String,
167+
pub name_title_company: String,
168+
pub recording_date: String,
169+
pub transfer_amount: String,
170+
}

0 commit comments

Comments
 (0)