Skip to content

Commit

Permalink
add search
Browse files Browse the repository at this point in the history
  • Loading branch information
datawrestler committed Apr 29, 2024
1 parent b1773ca commit d5c9bee
Show file tree
Hide file tree
Showing 5 changed files with 230 additions and 3 deletions.
30 changes: 29 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

## Sign Up for an API Key

To use the ParclLabs API, you need an API key. To get an API key, sign up at [ParclLabs](https://dashboard.parcllabs.com/signup).
To use the Parcl Labs API, you need an API key. To get an API key, sign up at [ParclLabs](https://dashboard.parcllabs.com/signup).

## Installation

Expand All @@ -13,6 +13,34 @@ You can install the package via pip:
pip install parcllabs
```

### Search
Search is your entry point into finding one or many of over 70,000 markets in the United States. You can search for markets by name, state, region, fips, or zip code. You can also search for markets by their Parcl ID.

#### Search Markets
```python
import os

from parcllabs import ParclLabsClient


api_key = os.getenv('PARCLLABS_API_KEY')
client = ParclLabsClient(api_key)

# all cities in EAST_NORTH_CENTRAL census region
results = client.search.markets.retrieve_many(
location_type='CITY',
region='EAST_NORTH_CENTRAL',
as_dataframe=True
)
print(results.head())
# parcl_id country geoid state_fips_code name state_abbreviation region location_type
# 0 5333443 USA 5500100 55 Abbotsford City WI EAST_NORTH_CENTRAL CITY
# 1 5387920 USA 1700113 17 Abingdon City IL EAST_NORTH_CENTRAL CITY
# 2 5403368 USA 5500275 55 Adams City WI EAST_NORTH_CENTRAL CITY
# 3 5278505 USA 2600440 26 Adrian City MI EAST_NORTH_CENTRAL CITY
# 4 5332624 USA 3901000 39 Akron City OH EAST_NORTH_CENTRAL CITY
```

### Rental Market Metrics

#### Gross Yield
Expand Down
1 change: 1 addition & 0 deletions parcllabs/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,4 @@
)

from parcllabs.services.portfolio_metrics import PortfolioMetricsSFHousingStockOwnership
from parcllabs.services.search import SearchMarkets
2 changes: 1 addition & 1 deletion parcllabs/__version__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
VERSION = "0.1.7"
VERSION = "0.1.8"
3 changes: 2 additions & 1 deletion parcllabs/plabs_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
)

from parcllabs.services.portfolio_metrics import PortfolioMetricsSFHousingStockOwnership

from parcllabs.services.search import SearchMarkets

class ParclLabsClient:
def __init__(self, api_key: str):
Expand Down Expand Up @@ -70,6 +70,7 @@ def __init__(self, api_key: str):
self.portfolio_metrics_sf_housing_stock_ownership = (
PortfolioMetricsSFHousingStockOwnership(client=self)
)
self.search_markets = SearchMarkets(client=self)

def get(self, url: str, params: dict = None):
"""
Expand Down
197 changes: 197 additions & 0 deletions parcllabs/services/search.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
from enum import Enum
from typing import Any, Mapping, Optional, List

import pandas as pd

from parcllabs.services.base_service import ParclLabsService

valid_locations = [
"COUNTY",
"CITY",
"ZIP5",
"CDP",
"VILLAGE",
"TOWN",
"CBSA",
"ALL",
]

valid_regions = [
"EAST_NORTH_CENTRAL",
"EAST_SOUTH_CENTRAL",
"MIDDLE_ATLANTIC",
"MOUNTAIN",
"NEW_ENGLAND",
"PACIFIC",
"SOUTH_ATLANTIC",
"WEST_NORTH_CENTRAL",
"WEST_SOUTH_CENTRAL",
"ALL",
]

valid_state_abbreviations = [
"AK",
"AL",
"AR",
"AZ",
"CA",
"CO",
"CT",
"DC",
"DE",
"FL",
"GA",
"HI",
"IA",
"ID",
"IL",
"IN",
"KS",
"KY",
"LA",
"MA",
"MD",
"ME",
"MI",
"MN",
"MO",
"MS",
"MT",
"NC",
"ND",
"NE",
"NH",
"NJ",
"NM",
"NV",
"NY",
"OH",
"OK",
"OR",
"PA",
"PR",
"RI",
"SC",
"SD",
"TN",
"TX",
"UT",
"VA",
"VI",
"VT",
"WA",
"WI",
"WV",
"WY",
"ALL",
]

valid_state_fips_codes = [
"01",
"02",
"04",
"05",
"06",
"08",
"09",
"10",
"11",
"12",
"13",
"15",
"16",
"17",
"18",
"19",
"20",
"21",
"22",
"23",
"24",
"25",
"26",
"27",
"28",
"29",
"30",
"31",
"32",
"33",
"34",
"35",
"36",
"37",
"38",
"39",
"40",
"41",
"42",
"44",
"45",
"46",
"47",
"48",
"49",
"50",
"51",
"53",
"54",
"55",
"56",
"60",
"66",
"69",
"72",
"78",
"ALL",
]

class SearchMarkets(ParclLabsService):
"""
Gets weekly updated rolling counts of newly listed for sale properties, segmented into 7, 30, 60, and 90 day periods ending on a specified date, based on a given <parcl_id>.
"""

def _as_pd_dataframe(self, data: List[Mapping[str, Any]]) -> Any:
return pd.DataFrame(data)

def retrieve(
self,
query: Optional[str] = None,
location_type: str = None,
region: str = None,
state_abbreviation: str = None,
state_fips_code: str = None,
parcl_id: int = None,
geoid: str = None,
params: Optional[Mapping[str, Any]] = None,
as_dataframe: bool = False,
):
if location_type is not None and location_type not in valid_locations:
raise ValueError(f"location_type value error. Valid values are: {valid_locations}. Received: {location_type}")

if region is not None and region not in valid_regions:
raise ValueError(f"region value error. Valid values are: {valid_regions}. Received: {region}")

if state_abbreviation is not None and state_abbreviation not in valid_state_abbreviations:
raise ValueError(f"state_abbreviation value error. Valid values are: {valid_state_abbreviations}. Received: {state_abbreviation}")

if state_fips_code is not None and state_fips_code not in valid_state_fips_codes:
raise ValueError(f"state_fips_code value error. Valid values are: {valid_state_fips_codes}. Received: {state_fips_code}")

params = {
"query": query,
"location_type": location_type,
"region": region,
"state_abbreviation": state_abbreviation,
"state_fips_code": state_fips_code,
"parcl_id": parcl_id,
"geoid": geoid,
**(params or {}),
}
results = self._request(
url="/v1/search/markets", params=params
)

if as_dataframe:
return self._as_pd_dataframe(results.get('items'))
return results

0 comments on commit d5c9bee

Please sign in to comment.