zillow-rapidapi-client 0.1.3__py3-none-any.whl

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.
Files changed (37) hide show
  1. zillow_rapidapi_client/__init__.py +18 -0
  2. zillow_rapidapi_client/_hooks/__init__.py +5 -0
  3. zillow_rapidapi_client/_hooks/registration.py +13 -0
  4. zillow_rapidapi_client/_hooks/sdkhooks.py +76 -0
  5. zillow_rapidapi_client/_hooks/types.py +106 -0
  6. zillow_rapidapi_client/_version.py +15 -0
  7. zillow_rapidapi_client/basesdk.py +358 -0
  8. zillow_rapidapi_client/httpclient.py +134 -0
  9. zillow_rapidapi_client/models/__init__.py +40 -0
  10. zillow_rapidapi_client/models/apierror.py +22 -0
  11. zillow_rapidapi_client/models/property.py +163 -0
  12. zillow_rapidapi_client/models/propertyextendedsearchop.py +106 -0
  13. zillow_rapidapi_client/models/propertysearchresponse.py +32 -0
  14. zillow_rapidapi_client/properties.py +221 -0
  15. zillow_rapidapi_client/py.typed +1 -0
  16. zillow_rapidapi_client/sdk.py +114 -0
  17. zillow_rapidapi_client/sdkconfiguration.py +52 -0
  18. zillow_rapidapi_client/types/__init__.py +21 -0
  19. zillow_rapidapi_client/types/basemodel.py +39 -0
  20. zillow_rapidapi_client/utils/__init__.py +99 -0
  21. zillow_rapidapi_client/utils/annotations.py +55 -0
  22. zillow_rapidapi_client/utils/enums.py +34 -0
  23. zillow_rapidapi_client/utils/eventstreaming.py +238 -0
  24. zillow_rapidapi_client/utils/forms.py +202 -0
  25. zillow_rapidapi_client/utils/headers.py +136 -0
  26. zillow_rapidapi_client/utils/logger.py +27 -0
  27. zillow_rapidapi_client/utils/metadata.py +118 -0
  28. zillow_rapidapi_client/utils/queryparams.py +205 -0
  29. zillow_rapidapi_client/utils/requestbodies.py +66 -0
  30. zillow_rapidapi_client/utils/retries.py +217 -0
  31. zillow_rapidapi_client/utils/security.py +174 -0
  32. zillow_rapidapi_client/utils/serializers.py +215 -0
  33. zillow_rapidapi_client/utils/url.py +155 -0
  34. zillow_rapidapi_client/utils/values.py +137 -0
  35. zillow_rapidapi_client-0.1.3.dist-info/METADATA +419 -0
  36. zillow_rapidapi_client-0.1.3.dist-info/RECORD +37 -0
  37. zillow_rapidapi_client-0.1.3.dist-info/WHEEL +4 -0
@@ -0,0 +1,134 @@
1
+ """Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
2
+
3
+ # pyright: reportReturnType = false
4
+ import asyncio
5
+ from concurrent.futures import ThreadPoolExecutor
6
+ from typing_extensions import Protocol, runtime_checkable
7
+ import httpx
8
+ from typing import Any, Optional, Union
9
+
10
+
11
+ @runtime_checkable
12
+ class HttpClient(Protocol):
13
+ def send(
14
+ self,
15
+ request: httpx.Request,
16
+ *,
17
+ stream: bool = False,
18
+ auth: Union[
19
+ httpx._types.AuthTypes, httpx._client.UseClientDefault, None
20
+ ] = httpx.USE_CLIENT_DEFAULT,
21
+ follow_redirects: Union[
22
+ bool, httpx._client.UseClientDefault
23
+ ] = httpx.USE_CLIENT_DEFAULT,
24
+ ) -> httpx.Response:
25
+ pass
26
+
27
+ def build_request(
28
+ self,
29
+ method: str,
30
+ url: httpx._types.URLTypes,
31
+ *,
32
+ content: Optional[httpx._types.RequestContent] = None,
33
+ data: Optional[httpx._types.RequestData] = None,
34
+ files: Optional[httpx._types.RequestFiles] = None,
35
+ json: Optional[Any] = None,
36
+ params: Optional[httpx._types.QueryParamTypes] = None,
37
+ headers: Optional[httpx._types.HeaderTypes] = None,
38
+ cookies: Optional[httpx._types.CookieTypes] = None,
39
+ timeout: Union[
40
+ httpx._types.TimeoutTypes, httpx._client.UseClientDefault
41
+ ] = httpx.USE_CLIENT_DEFAULT,
42
+ extensions: Optional[httpx._types.RequestExtensions] = None,
43
+ ) -> httpx.Request:
44
+ pass
45
+
46
+ def close(self) -> None:
47
+ pass
48
+
49
+
50
+ @runtime_checkable
51
+ class AsyncHttpClient(Protocol):
52
+ async def send(
53
+ self,
54
+ request: httpx.Request,
55
+ *,
56
+ stream: bool = False,
57
+ auth: Union[
58
+ httpx._types.AuthTypes, httpx._client.UseClientDefault, None
59
+ ] = httpx.USE_CLIENT_DEFAULT,
60
+ follow_redirects: Union[
61
+ bool, httpx._client.UseClientDefault
62
+ ] = httpx.USE_CLIENT_DEFAULT,
63
+ ) -> httpx.Response:
64
+ pass
65
+
66
+ def build_request(
67
+ self,
68
+ method: str,
69
+ url: httpx._types.URLTypes,
70
+ *,
71
+ content: Optional[httpx._types.RequestContent] = None,
72
+ data: Optional[httpx._types.RequestData] = None,
73
+ files: Optional[httpx._types.RequestFiles] = None,
74
+ json: Optional[Any] = None,
75
+ params: Optional[httpx._types.QueryParamTypes] = None,
76
+ headers: Optional[httpx._types.HeaderTypes] = None,
77
+ cookies: Optional[httpx._types.CookieTypes] = None,
78
+ timeout: Union[
79
+ httpx._types.TimeoutTypes, httpx._client.UseClientDefault
80
+ ] = httpx.USE_CLIENT_DEFAULT,
81
+ extensions: Optional[httpx._types.RequestExtensions] = None,
82
+ ) -> httpx.Request:
83
+ pass
84
+
85
+ async def aclose(self) -> None:
86
+ pass
87
+
88
+
89
+ class ClientOwner(Protocol):
90
+ client: Union[HttpClient, None]
91
+ async_client: Union[AsyncHttpClient, None]
92
+
93
+
94
+ def close_clients(
95
+ owner: ClientOwner,
96
+ sync_client: Union[HttpClient, None],
97
+ async_client: Union[AsyncHttpClient, None],
98
+ ) -> None:
99
+ """
100
+ A finalizer function that is meant to be used with weakref.finalize to close
101
+ httpx clients used by an SDK so that underlying resources can be garbage
102
+ collected.
103
+ """
104
+
105
+ # Unset the client/async_client properties so there are no more references
106
+ # to them from the owning SDK instance and they can be reaped.
107
+ owner.client = None
108
+ owner.async_client = None
109
+
110
+ if sync_client is not None:
111
+ try:
112
+ sync_client.close()
113
+ except Exception:
114
+ pass
115
+
116
+ if async_client is not None:
117
+ is_async = False
118
+ try:
119
+ asyncio.get_running_loop()
120
+ is_async = True
121
+ except RuntimeError:
122
+ pass
123
+
124
+ try:
125
+ # If this function is called in an async loop then start another
126
+ # loop in a separate thread to close the async http client.
127
+ if is_async:
128
+ with ThreadPoolExecutor(max_workers=1) as executor:
129
+ future = executor.submit(asyncio.run, async_client.aclose())
130
+ future.result()
131
+ else:
132
+ asyncio.run(async_client.aclose())
133
+ except Exception:
134
+ pass
@@ -0,0 +1,40 @@
1
+ """Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
2
+
3
+ from .apierror import APIError
4
+ from .property import (
5
+ ListingStatus,
6
+ ListingSubType,
7
+ ListingSubTypeTypedDict,
8
+ Property,
9
+ PropertyType,
10
+ PropertyTypedDict,
11
+ )
12
+ from .propertyextendedsearchop import (
13
+ HomeType,
14
+ PropertyExtendedSearchRequest,
15
+ PropertyExtendedSearchRequestTypedDict,
16
+ Sort,
17
+ StatusType,
18
+ )
19
+ from .propertysearchresponse import (
20
+ PropertySearchResponse,
21
+ PropertySearchResponseTypedDict,
22
+ )
23
+
24
+
25
+ __all__ = [
26
+ "APIError",
27
+ "HomeType",
28
+ "ListingStatus",
29
+ "ListingSubType",
30
+ "ListingSubTypeTypedDict",
31
+ "Property",
32
+ "PropertyExtendedSearchRequest",
33
+ "PropertyExtendedSearchRequestTypedDict",
34
+ "PropertySearchResponse",
35
+ "PropertySearchResponseTypedDict",
36
+ "PropertyType",
37
+ "PropertyTypedDict",
38
+ "Sort",
39
+ "StatusType",
40
+ ]
@@ -0,0 +1,22 @@
1
+ """Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
2
+
3
+ from dataclasses import dataclass
4
+ from typing import Optional
5
+ import httpx
6
+
7
+
8
+ @dataclass
9
+ class APIError(Exception):
10
+ """Represents an error returned by the API."""
11
+
12
+ message: str
13
+ status_code: int = -1
14
+ body: str = ""
15
+ raw_response: Optional[httpx.Response] = None
16
+
17
+ def __str__(self):
18
+ body = ""
19
+ if len(self.body) > 0:
20
+ body = f"\n{self.body}"
21
+
22
+ return f"{self.message}: Status {self.status_code}{body}"
@@ -0,0 +1,163 @@
1
+ """Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
2
+
3
+ from __future__ import annotations
4
+ from datetime import datetime
5
+ from enum import Enum
6
+ import pydantic
7
+ from pydantic import model_serializer
8
+ from typing import Optional
9
+ from typing_extensions import Annotated, NotRequired, TypedDict
10
+ from zillow_rapidapi_client.types import (
11
+ BaseModel,
12
+ Nullable,
13
+ OptionalNullable,
14
+ UNSET,
15
+ UNSET_SENTINEL,
16
+ )
17
+
18
+
19
+ class PropertyType(str, Enum):
20
+ SINGLE_FAMILY = "SINGLE_FAMILY"
21
+ MULTI_FAMILY = "MULTI_FAMILY"
22
+ CONDO = "CONDO"
23
+ TOWNHOUSE = "TOWNHOUSE"
24
+ APARTMENT = "APARTMENT"
25
+ LAND = "LAND"
26
+
27
+
28
+ class ListingStatus(str, Enum):
29
+ FOR_SALE = "FOR_SALE"
30
+ PENDING = "PENDING"
31
+ SOLD = "SOLD"
32
+
33
+
34
+ class ListingSubTypeTypedDict(TypedDict):
35
+ is_fsba: NotRequired[bool]
36
+
37
+
38
+ class ListingSubType(BaseModel):
39
+ is_fsba: Annotated[Optional[bool], pydantic.Field(alias="is_FSBA")] = None
40
+
41
+
42
+ class PropertyTypedDict(TypedDict):
43
+ date_sold: NotRequired[Nullable[datetime]]
44
+ property_type: NotRequired[PropertyType]
45
+ lot_area_value: NotRequired[float]
46
+ address: NotRequired[str]
47
+ img_src: NotRequired[str]
48
+ price: NotRequired[float]
49
+ bedrooms: NotRequired[int]
50
+ longitude: NotRequired[float]
51
+ latitude: NotRequired[float]
52
+ listing_status: NotRequired[ListingStatus]
53
+ zpid: NotRequired[str]
54
+ listing_sub_type: NotRequired[ListingSubTypeTypedDict]
55
+ days_on_zillow: NotRequired[int]
56
+ bathrooms: NotRequired[float]
57
+ living_area: NotRequired[int]
58
+ country: NotRequired[str]
59
+ currency: NotRequired[str]
60
+ lot_area_unit: NotRequired[str]
61
+ has_image: NotRequired[bool]
62
+
63
+
64
+ class Property(BaseModel):
65
+ date_sold: Annotated[
66
+ OptionalNullable[datetime], pydantic.Field(alias="dateSold")
67
+ ] = UNSET
68
+
69
+ property_type: Annotated[
70
+ Optional[PropertyType], pydantic.Field(alias="propertyType")
71
+ ] = None
72
+
73
+ lot_area_value: Annotated[Optional[float], pydantic.Field(alias="lotAreaValue")] = (
74
+ None
75
+ )
76
+
77
+ address: Optional[str] = None
78
+
79
+ img_src: Annotated[Optional[str], pydantic.Field(alias="imgSrc")] = None
80
+
81
+ price: Optional[float] = None
82
+
83
+ bedrooms: Optional[int] = None
84
+
85
+ longitude: Optional[float] = None
86
+
87
+ latitude: Optional[float] = None
88
+
89
+ listing_status: Annotated[
90
+ Optional[ListingStatus], pydantic.Field(alias="listingStatus")
91
+ ] = None
92
+
93
+ zpid: Optional[str] = None
94
+
95
+ listing_sub_type: Annotated[
96
+ Optional[ListingSubType], pydantic.Field(alias="listingSubType")
97
+ ] = None
98
+
99
+ days_on_zillow: Annotated[Optional[int], pydantic.Field(alias="daysOnZillow")] = (
100
+ None
101
+ )
102
+
103
+ bathrooms: Optional[float] = None
104
+
105
+ living_area: Annotated[Optional[int], pydantic.Field(alias="livingArea")] = None
106
+
107
+ country: Optional[str] = None
108
+
109
+ currency: Optional[str] = None
110
+
111
+ lot_area_unit: Annotated[Optional[str], pydantic.Field(alias="lotAreaUnit")] = None
112
+
113
+ has_image: Annotated[Optional[bool], pydantic.Field(alias="hasImage")] = None
114
+
115
+ @model_serializer(mode="wrap")
116
+ def serialize_model(self, handler):
117
+ optional_fields = [
118
+ "dateSold",
119
+ "propertyType",
120
+ "lotAreaValue",
121
+ "address",
122
+ "imgSrc",
123
+ "price",
124
+ "bedrooms",
125
+ "longitude",
126
+ "latitude",
127
+ "listingStatus",
128
+ "zpid",
129
+ "listingSubType",
130
+ "daysOnZillow",
131
+ "bathrooms",
132
+ "livingArea",
133
+ "country",
134
+ "currency",
135
+ "lotAreaUnit",
136
+ "hasImage",
137
+ ]
138
+ nullable_fields = ["dateSold"]
139
+ null_default_fields = []
140
+
141
+ serialized = handler(self)
142
+
143
+ m = {}
144
+
145
+ for n, f in self.model_fields.items():
146
+ k = f.alias or n
147
+ val = serialized.get(k)
148
+ serialized.pop(k, None)
149
+
150
+ optional_nullable = k in optional_fields and k in nullable_fields
151
+ is_set = (
152
+ self.__pydantic_fields_set__.intersection({n})
153
+ or k in null_default_fields
154
+ ) # pylint: disable=no-member
155
+
156
+ if val is not None and val != UNSET_SENTINEL:
157
+ m[k] = val
158
+ elif val != UNSET_SENTINEL and (
159
+ not k in optional_fields or (optional_nullable and is_set)
160
+ ):
161
+ m[k] = val
162
+
163
+ return m
@@ -0,0 +1,106 @@
1
+ """Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
2
+
3
+ from __future__ import annotations
4
+ from enum import Enum
5
+ import pydantic
6
+ from typing import Optional
7
+ from typing_extensions import Annotated, NotRequired, TypedDict
8
+ from zillow_rapidapi_client.types import BaseModel
9
+ from zillow_rapidapi_client.utils import FieldMetadata, QueryParamMetadata
10
+
11
+
12
+ class StatusType(str, Enum):
13
+ r"""Property status type."""
14
+
15
+ FOR_SALE = "ForSale"
16
+ RECENTLY_SOLD = "RecentlySold"
17
+ FOR_RENT = "ForRent"
18
+
19
+
20
+ class HomeType(str, Enum):
21
+ r"""Property type. Comma-separated list."""
22
+
23
+ HOUSES = "Houses"
24
+ APARTMENTS_CONDOS_CO_OPS = "Apartments_Condos_Co-ops"
25
+ MULTI_FAMILY = "Multi-family"
26
+ APARTMENTS = "Apartments"
27
+ MANUFACTURED = "Manufactured"
28
+ CONDOS = "Condos"
29
+ LOTS_LAND = "LotsLand"
30
+ TOWNHOMES = "Townhomes"
31
+
32
+
33
+ class Sort(str, Enum):
34
+ r"""Sorting order."""
35
+
36
+ HOMES_FOR_YOU = "Homes_for_You"
37
+ PRICE_HIGH_LOW = "Price_High_Low"
38
+ PRICE_LOW_HIGH = "Price_Low_High"
39
+ NEWEST = "Newest"
40
+ BEDROOMS = "Bedrooms"
41
+ BATHROOMS = "Bathrooms"
42
+ SQUARE_FEET = "Square_Feet"
43
+ LOT_SIZE = "Lot_Size"
44
+
45
+
46
+ class PropertyExtendedSearchRequestTypedDict(TypedDict):
47
+ location: NotRequired[str]
48
+ r"""Location details (address, county, neighborhood, or Zip code). Required if polygon or coordinates are empty."""
49
+ page: NotRequired[int]
50
+ r"""Page number for paginated results. Max value is 20."""
51
+ status_type: NotRequired[StatusType]
52
+ r"""Property status type."""
53
+ home_type: NotRequired[HomeType]
54
+ r"""Property type. Comma-separated list."""
55
+ sort: NotRequired[Sort]
56
+ r"""Sorting order."""
57
+ min_price: NotRequired[float]
58
+ r"""Minimum price filter."""
59
+ max_price: NotRequired[float]
60
+ r"""Maximum price filter."""
61
+
62
+
63
+ class PropertyExtendedSearchRequest(BaseModel):
64
+ location: Annotated[
65
+ Optional[str],
66
+ FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
67
+ ] = None
68
+ r"""Location details (address, county, neighborhood, or Zip code). Required if polygon or coordinates are empty."""
69
+
70
+ page: Annotated[
71
+ Optional[int],
72
+ FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
73
+ ] = None
74
+ r"""Page number for paginated results. Max value is 20."""
75
+
76
+ status_type: Annotated[
77
+ Optional[StatusType],
78
+ FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
79
+ ] = None
80
+ r"""Property status type."""
81
+
82
+ home_type: Annotated[
83
+ Optional[HomeType],
84
+ FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
85
+ ] = None
86
+ r"""Property type. Comma-separated list."""
87
+
88
+ sort: Annotated[
89
+ Optional[Sort],
90
+ FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
91
+ ] = None
92
+ r"""Sorting order."""
93
+
94
+ min_price: Annotated[
95
+ Optional[float],
96
+ pydantic.Field(alias="minPrice"),
97
+ FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
98
+ ] = None
99
+ r"""Minimum price filter."""
100
+
101
+ max_price: Annotated[
102
+ Optional[float],
103
+ pydantic.Field(alias="maxPrice"),
104
+ FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
105
+ ] = None
106
+ r"""Maximum price filter."""
@@ -0,0 +1,32 @@
1
+ """Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
2
+
3
+ from __future__ import annotations
4
+ from .property import Property, PropertyTypedDict
5
+ import pydantic
6
+ from typing import List, Optional
7
+ from typing_extensions import Annotated, NotRequired, TypedDict
8
+ from zillow_rapidapi_client.types import BaseModel
9
+
10
+
11
+ class PropertySearchResponseTypedDict(TypedDict):
12
+ props: NotRequired[List[PropertyTypedDict]]
13
+ results_per_page: NotRequired[int]
14
+ total_pages: NotRequired[int]
15
+ total_result_count: NotRequired[int]
16
+ current_page: NotRequired[int]
17
+
18
+
19
+ class PropertySearchResponse(BaseModel):
20
+ props: Optional[List[Property]] = None
21
+
22
+ results_per_page: Annotated[
23
+ Optional[int], pydantic.Field(alias="resultsPerPage")
24
+ ] = None
25
+
26
+ total_pages: Annotated[Optional[int], pydantic.Field(alias="totalPages")] = None
27
+
28
+ total_result_count: Annotated[
29
+ Optional[int], pydantic.Field(alias="totalResultCount")
30
+ ] = None
31
+
32
+ current_page: Annotated[Optional[int], pydantic.Field(alias="currentPage")] = None