permitstack 1.0.0__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.
- permitstack/__init__.py +17 -0
- permitstack/_hooks/__init__.py +4 -0
- permitstack/_hooks/sdkhooks.py +74 -0
- permitstack/_hooks/types.py +112 -0
- permitstack/_version.py +15 -0
- permitstack/basesdk.py +396 -0
- permitstack/bulk_export.py +241 -0
- permitstack/contractors.py +625 -0
- permitstack/errors/__init__.py +39 -0
- permitstack/errors/httpvalidationerror.py +28 -0
- permitstack/errors/no_response_error.py +17 -0
- permitstack/errors/permitstackdefaulterror.py +40 -0
- permitstack/errors/permitstackerror.py +30 -0
- permitstack/errors/responsevalidationerror.py +27 -0
- permitstack/health.py +171 -0
- permitstack/httpclient.py +125 -0
- permitstack/models/__init__.py +158 -0
- permitstack/models/contractorprofile.py +108 -0
- permitstack/models/contractorsearchresponse.py +24 -0
- permitstack/models/contractorsummary.py +57 -0
- permitstack/models/delete_webhookop.py +16 -0
- permitstack/models/export_permits_csvop.py +98 -0
- permitstack/models/get_contractor_permitsop.py +46 -0
- permitstack/models/get_contractorop.py +16 -0
- permitstack/models/get_permitop.py +16 -0
- permitstack/models/get_permits_by_addressop.py +46 -0
- permitstack/models/get_property_historyop.py +18 -0
- permitstack/models/permitcategory.py +27 -0
- permitstack/models/permitdetail.py +164 -0
- permitstack/models/permitsearchresponse.py +24 -0
- permitstack/models/permitstatus.py +16 -0
- permitstack/models/permitsummary.py +121 -0
- permitstack/models/propertytype.py +14 -0
- permitstack/models/search_contractorsop.py +98 -0
- permitstack/models/search_permitsop.py +247 -0
- permitstack/models/security.py +42 -0
- permitstack/models/validationerror.py +57 -0
- permitstack/models/webhookcreate.py +60 -0
- permitstack/permits.py +866 -0
- permitstack/property_history.py +207 -0
- permitstack/py.typed +1 -0
- permitstack/sdk.py +218 -0
- permitstack/sdkconfiguration.py +49 -0
- permitstack/types/__init__.py +21 -0
- permitstack/types/basemodel.py +77 -0
- permitstack/utils/__init__.py +178 -0
- permitstack/utils/annotations.py +79 -0
- permitstack/utils/datetimes.py +23 -0
- permitstack/utils/dynamic_imports.py +54 -0
- permitstack/utils/enums.py +134 -0
- permitstack/utils/eventstreaming.py +309 -0
- permitstack/utils/forms.py +234 -0
- permitstack/utils/headers.py +136 -0
- permitstack/utils/logger.py +27 -0
- permitstack/utils/metadata.py +119 -0
- permitstack/utils/queryparams.py +217 -0
- permitstack/utils/requestbodies.py +66 -0
- permitstack/utils/retries.py +271 -0
- permitstack/utils/security.py +215 -0
- permitstack/utils/serializers.py +225 -0
- permitstack/utils/unmarshal_json_response.py +38 -0
- permitstack/utils/url.py +155 -0
- permitstack/utils/values.py +137 -0
- permitstack/webhooks.py +593 -0
- permitstack-1.0.0.dist-info/METADATA +541 -0
- permitstack-1.0.0.dist-info/RECORD +68 -0
- permitstack-1.0.0.dist-info/WHEEL +5 -0
- permitstack-1.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
from typing import Literal
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
PropertyType = Literal[
|
|
8
|
+
"residential",
|
|
9
|
+
"commercial",
|
|
10
|
+
"industrial",
|
|
11
|
+
"mixed_use",
|
|
12
|
+
"institutional",
|
|
13
|
+
"unknown",
|
|
14
|
+
]
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
from permitstack.types import (
|
|
5
|
+
BaseModel,
|
|
6
|
+
Nullable,
|
|
7
|
+
OptionalNullable,
|
|
8
|
+
UNSET,
|
|
9
|
+
UNSET_SENTINEL,
|
|
10
|
+
)
|
|
11
|
+
from permitstack.utils import FieldMetadata, QueryParamMetadata
|
|
12
|
+
from pydantic import model_serializer
|
|
13
|
+
from typing import Optional
|
|
14
|
+
from typing_extensions import Annotated, NotRequired, TypedDict
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class SearchContractorsRequestTypedDict(TypedDict):
|
|
18
|
+
name: NotRequired[Nullable[str]]
|
|
19
|
+
r"""Contractor name (partial match)"""
|
|
20
|
+
state: NotRequired[Nullable[str]]
|
|
21
|
+
r"""2-letter state code"""
|
|
22
|
+
city: NotRequired[Nullable[str]]
|
|
23
|
+
r"""City name"""
|
|
24
|
+
specialty: NotRequired[Nullable[str]]
|
|
25
|
+
r"""Specialty tag (e.g. solar, roofing, hvac)"""
|
|
26
|
+
min_permits: NotRequired[Nullable[int]]
|
|
27
|
+
r"""Minimum total permits"""
|
|
28
|
+
page: NotRequired[int]
|
|
29
|
+
per_page: NotRequired[int]
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class SearchContractorsRequest(BaseModel):
|
|
33
|
+
name: Annotated[
|
|
34
|
+
OptionalNullable[str],
|
|
35
|
+
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
|
36
|
+
] = UNSET
|
|
37
|
+
r"""Contractor name (partial match)"""
|
|
38
|
+
|
|
39
|
+
state: Annotated[
|
|
40
|
+
OptionalNullable[str],
|
|
41
|
+
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
|
42
|
+
] = UNSET
|
|
43
|
+
r"""2-letter state code"""
|
|
44
|
+
|
|
45
|
+
city: Annotated[
|
|
46
|
+
OptionalNullable[str],
|
|
47
|
+
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
|
48
|
+
] = UNSET
|
|
49
|
+
r"""City name"""
|
|
50
|
+
|
|
51
|
+
specialty: Annotated[
|
|
52
|
+
OptionalNullable[str],
|
|
53
|
+
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
|
54
|
+
] = UNSET
|
|
55
|
+
r"""Specialty tag (e.g. solar, roofing, hvac)"""
|
|
56
|
+
|
|
57
|
+
min_permits: Annotated[
|
|
58
|
+
OptionalNullable[int],
|
|
59
|
+
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
|
60
|
+
] = UNSET
|
|
61
|
+
r"""Minimum total permits"""
|
|
62
|
+
|
|
63
|
+
page: Annotated[
|
|
64
|
+
Optional[int],
|
|
65
|
+
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
|
66
|
+
] = 1
|
|
67
|
+
|
|
68
|
+
per_page: Annotated[
|
|
69
|
+
Optional[int],
|
|
70
|
+
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
|
71
|
+
] = 25
|
|
72
|
+
|
|
73
|
+
@model_serializer(mode="wrap")
|
|
74
|
+
def serialize_model(self, handler):
|
|
75
|
+
optional_fields = set(
|
|
76
|
+
["name", "state", "city", "specialty", "min_permits", "page", "per_page"]
|
|
77
|
+
)
|
|
78
|
+
nullable_fields = set(["name", "state", "city", "specialty", "min_permits"])
|
|
79
|
+
serialized = handler(self)
|
|
80
|
+
m = {}
|
|
81
|
+
|
|
82
|
+
for n, f in type(self).model_fields.items():
|
|
83
|
+
k = f.alias or n
|
|
84
|
+
val = serialized.get(k, serialized.get(n))
|
|
85
|
+
is_nullable_and_explicitly_set = (
|
|
86
|
+
k in nullable_fields
|
|
87
|
+
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
if val != UNSET_SENTINEL:
|
|
91
|
+
if (
|
|
92
|
+
val is not None
|
|
93
|
+
or k not in optional_fields
|
|
94
|
+
or is_nullable_and_explicitly_set
|
|
95
|
+
):
|
|
96
|
+
m[k] = val
|
|
97
|
+
|
|
98
|
+
return m
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
from .permitcategory import PermitCategory
|
|
5
|
+
from .permitstatus import PermitStatus
|
|
6
|
+
from .propertytype import PropertyType
|
|
7
|
+
from datetime import date
|
|
8
|
+
from permitstack.types import (
|
|
9
|
+
BaseModel,
|
|
10
|
+
Nullable,
|
|
11
|
+
OptionalNullable,
|
|
12
|
+
UNSET,
|
|
13
|
+
UNSET_SENTINEL,
|
|
14
|
+
)
|
|
15
|
+
from permitstack.utils import FieldMetadata, QueryParamMetadata
|
|
16
|
+
from pydantic import model_serializer
|
|
17
|
+
from typing import Optional
|
|
18
|
+
from typing_extensions import Annotated, NotRequired, TypedDict
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class SearchPermitsRequestTypedDict(TypedDict):
|
|
22
|
+
zip_code: NotRequired[Nullable[str]]
|
|
23
|
+
r"""5-digit ZIP code"""
|
|
24
|
+
city: NotRequired[Nullable[str]]
|
|
25
|
+
r"""City name"""
|
|
26
|
+
state: NotRequired[Nullable[str]]
|
|
27
|
+
r"""2-letter state code"""
|
|
28
|
+
lat: NotRequired[Nullable[float]]
|
|
29
|
+
r"""Latitude for radius search"""
|
|
30
|
+
lng: NotRequired[Nullable[float]]
|
|
31
|
+
r"""Longitude for radius search"""
|
|
32
|
+
radius_miles: NotRequired[float]
|
|
33
|
+
r"""Radius in miles (used with lat/lng)"""
|
|
34
|
+
category: NotRequired[Nullable[PermitCategory]]
|
|
35
|
+
r"""Permit category (e.g. solar, roofing, hvac)"""
|
|
36
|
+
status: NotRequired[Nullable[PermitStatus]]
|
|
37
|
+
r"""Permit status (e.g. issued, filed, final)"""
|
|
38
|
+
property_type: NotRequired[Nullable[PropertyType]]
|
|
39
|
+
r"""Property type (e.g. residential, commercial)"""
|
|
40
|
+
tag: NotRequired[Nullable[str]]
|
|
41
|
+
r"""Filter by tag"""
|
|
42
|
+
filed_after: NotRequired[Nullable[date]]
|
|
43
|
+
r"""Filed on or after this date"""
|
|
44
|
+
filed_before: NotRequired[Nullable[date]]
|
|
45
|
+
r"""Filed on or before this date"""
|
|
46
|
+
issued_after: NotRequired[Nullable[date]]
|
|
47
|
+
r"""Issued on or after this date"""
|
|
48
|
+
issued_before: NotRequired[Nullable[date]]
|
|
49
|
+
r"""Issued on or before this date"""
|
|
50
|
+
min_value: NotRequired[Nullable[float]]
|
|
51
|
+
r"""Minimum estimated value"""
|
|
52
|
+
max_value: NotRequired[Nullable[float]]
|
|
53
|
+
r"""Maximum estimated value"""
|
|
54
|
+
q: NotRequired[Nullable[str]]
|
|
55
|
+
r"""Full-text search query"""
|
|
56
|
+
contractor_name: NotRequired[Nullable[str]]
|
|
57
|
+
r"""Contractor name (partial match)"""
|
|
58
|
+
page: NotRequired[int]
|
|
59
|
+
per_page: NotRequired[int]
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class SearchPermitsRequest(BaseModel):
|
|
63
|
+
zip_code: Annotated[
|
|
64
|
+
OptionalNullable[str],
|
|
65
|
+
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
|
66
|
+
] = UNSET
|
|
67
|
+
r"""5-digit ZIP code"""
|
|
68
|
+
|
|
69
|
+
city: Annotated[
|
|
70
|
+
OptionalNullable[str],
|
|
71
|
+
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
|
72
|
+
] = UNSET
|
|
73
|
+
r"""City name"""
|
|
74
|
+
|
|
75
|
+
state: Annotated[
|
|
76
|
+
OptionalNullable[str],
|
|
77
|
+
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
|
78
|
+
] = UNSET
|
|
79
|
+
r"""2-letter state code"""
|
|
80
|
+
|
|
81
|
+
lat: Annotated[
|
|
82
|
+
OptionalNullable[float],
|
|
83
|
+
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
|
84
|
+
] = UNSET
|
|
85
|
+
r"""Latitude for radius search"""
|
|
86
|
+
|
|
87
|
+
lng: Annotated[
|
|
88
|
+
OptionalNullable[float],
|
|
89
|
+
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
|
90
|
+
] = UNSET
|
|
91
|
+
r"""Longitude for radius search"""
|
|
92
|
+
|
|
93
|
+
radius_miles: Annotated[
|
|
94
|
+
Optional[float],
|
|
95
|
+
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
|
96
|
+
] = 5
|
|
97
|
+
r"""Radius in miles (used with lat/lng)"""
|
|
98
|
+
|
|
99
|
+
category: Annotated[
|
|
100
|
+
OptionalNullable[PermitCategory],
|
|
101
|
+
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
|
102
|
+
] = UNSET
|
|
103
|
+
r"""Permit category (e.g. solar, roofing, hvac)"""
|
|
104
|
+
|
|
105
|
+
status: Annotated[
|
|
106
|
+
OptionalNullable[PermitStatus],
|
|
107
|
+
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
|
108
|
+
] = UNSET
|
|
109
|
+
r"""Permit status (e.g. issued, filed, final)"""
|
|
110
|
+
|
|
111
|
+
property_type: Annotated[
|
|
112
|
+
OptionalNullable[PropertyType],
|
|
113
|
+
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
|
114
|
+
] = UNSET
|
|
115
|
+
r"""Property type (e.g. residential, commercial)"""
|
|
116
|
+
|
|
117
|
+
tag: Annotated[
|
|
118
|
+
OptionalNullable[str],
|
|
119
|
+
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
|
120
|
+
] = UNSET
|
|
121
|
+
r"""Filter by tag"""
|
|
122
|
+
|
|
123
|
+
filed_after: Annotated[
|
|
124
|
+
OptionalNullable[date],
|
|
125
|
+
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
|
126
|
+
] = UNSET
|
|
127
|
+
r"""Filed on or after this date"""
|
|
128
|
+
|
|
129
|
+
filed_before: Annotated[
|
|
130
|
+
OptionalNullable[date],
|
|
131
|
+
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
|
132
|
+
] = UNSET
|
|
133
|
+
r"""Filed on or before this date"""
|
|
134
|
+
|
|
135
|
+
issued_after: Annotated[
|
|
136
|
+
OptionalNullable[date],
|
|
137
|
+
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
|
138
|
+
] = UNSET
|
|
139
|
+
r"""Issued on or after this date"""
|
|
140
|
+
|
|
141
|
+
issued_before: Annotated[
|
|
142
|
+
OptionalNullable[date],
|
|
143
|
+
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
|
144
|
+
] = UNSET
|
|
145
|
+
r"""Issued on or before this date"""
|
|
146
|
+
|
|
147
|
+
min_value: Annotated[
|
|
148
|
+
OptionalNullable[float],
|
|
149
|
+
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
|
150
|
+
] = UNSET
|
|
151
|
+
r"""Minimum estimated value"""
|
|
152
|
+
|
|
153
|
+
max_value: Annotated[
|
|
154
|
+
OptionalNullable[float],
|
|
155
|
+
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
|
156
|
+
] = UNSET
|
|
157
|
+
r"""Maximum estimated value"""
|
|
158
|
+
|
|
159
|
+
q: Annotated[
|
|
160
|
+
OptionalNullable[str],
|
|
161
|
+
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
|
162
|
+
] = UNSET
|
|
163
|
+
r"""Full-text search query"""
|
|
164
|
+
|
|
165
|
+
contractor_name: Annotated[
|
|
166
|
+
OptionalNullable[str],
|
|
167
|
+
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
|
168
|
+
] = UNSET
|
|
169
|
+
r"""Contractor name (partial match)"""
|
|
170
|
+
|
|
171
|
+
page: Annotated[
|
|
172
|
+
Optional[int],
|
|
173
|
+
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
|
174
|
+
] = 1
|
|
175
|
+
|
|
176
|
+
per_page: Annotated[
|
|
177
|
+
Optional[int],
|
|
178
|
+
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
|
179
|
+
] = 25
|
|
180
|
+
|
|
181
|
+
@model_serializer(mode="wrap")
|
|
182
|
+
def serialize_model(self, handler):
|
|
183
|
+
optional_fields = set(
|
|
184
|
+
[
|
|
185
|
+
"zip_code",
|
|
186
|
+
"city",
|
|
187
|
+
"state",
|
|
188
|
+
"lat",
|
|
189
|
+
"lng",
|
|
190
|
+
"radius_miles",
|
|
191
|
+
"category",
|
|
192
|
+
"status",
|
|
193
|
+
"property_type",
|
|
194
|
+
"tag",
|
|
195
|
+
"filed_after",
|
|
196
|
+
"filed_before",
|
|
197
|
+
"issued_after",
|
|
198
|
+
"issued_before",
|
|
199
|
+
"min_value",
|
|
200
|
+
"max_value",
|
|
201
|
+
"q",
|
|
202
|
+
"contractor_name",
|
|
203
|
+
"page",
|
|
204
|
+
"per_page",
|
|
205
|
+
]
|
|
206
|
+
)
|
|
207
|
+
nullable_fields = set(
|
|
208
|
+
[
|
|
209
|
+
"zip_code",
|
|
210
|
+
"city",
|
|
211
|
+
"state",
|
|
212
|
+
"lat",
|
|
213
|
+
"lng",
|
|
214
|
+
"category",
|
|
215
|
+
"status",
|
|
216
|
+
"property_type",
|
|
217
|
+
"tag",
|
|
218
|
+
"filed_after",
|
|
219
|
+
"filed_before",
|
|
220
|
+
"issued_after",
|
|
221
|
+
"issued_before",
|
|
222
|
+
"min_value",
|
|
223
|
+
"max_value",
|
|
224
|
+
"q",
|
|
225
|
+
"contractor_name",
|
|
226
|
+
]
|
|
227
|
+
)
|
|
228
|
+
serialized = handler(self)
|
|
229
|
+
m = {}
|
|
230
|
+
|
|
231
|
+
for n, f in type(self).model_fields.items():
|
|
232
|
+
k = f.alias or n
|
|
233
|
+
val = serialized.get(k, serialized.get(n))
|
|
234
|
+
is_nullable_and_explicitly_set = (
|
|
235
|
+
k in nullable_fields
|
|
236
|
+
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
|
|
237
|
+
)
|
|
238
|
+
|
|
239
|
+
if val != UNSET_SENTINEL:
|
|
240
|
+
if (
|
|
241
|
+
val is not None
|
|
242
|
+
or k not in optional_fields
|
|
243
|
+
or is_nullable_and_explicitly_set
|
|
244
|
+
):
|
|
245
|
+
m[k] = val
|
|
246
|
+
|
|
247
|
+
return m
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
from permitstack.types import BaseModel, UNSET_SENTINEL
|
|
5
|
+
from permitstack.utils import FieldMetadata, SecurityMetadata
|
|
6
|
+
from pydantic import model_serializer
|
|
7
|
+
from typing import Optional
|
|
8
|
+
from typing_extensions import Annotated, NotRequired, TypedDict
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class SecurityTypedDict(TypedDict):
|
|
12
|
+
api_key: NotRequired[str]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class Security(BaseModel):
|
|
16
|
+
api_key: Annotated[
|
|
17
|
+
Optional[str],
|
|
18
|
+
FieldMetadata(
|
|
19
|
+
security=SecurityMetadata(
|
|
20
|
+
scheme=True,
|
|
21
|
+
scheme_type="apiKey",
|
|
22
|
+
sub_type="header",
|
|
23
|
+
field_name="X-API-Key",
|
|
24
|
+
)
|
|
25
|
+
),
|
|
26
|
+
] = None
|
|
27
|
+
|
|
28
|
+
@model_serializer(mode="wrap")
|
|
29
|
+
def serialize_model(self, handler):
|
|
30
|
+
optional_fields = set(["ApiKey"])
|
|
31
|
+
serialized = handler(self)
|
|
32
|
+
m = {}
|
|
33
|
+
|
|
34
|
+
for n, f in type(self).model_fields.items():
|
|
35
|
+
k = f.alias or n
|
|
36
|
+
val = serialized.get(k, serialized.get(n))
|
|
37
|
+
|
|
38
|
+
if val != UNSET_SENTINEL:
|
|
39
|
+
if val is not None or k not in optional_fields:
|
|
40
|
+
m[k] = val
|
|
41
|
+
|
|
42
|
+
return m
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
from permitstack.types import BaseModel, UNSET_SENTINEL
|
|
5
|
+
from pydantic import model_serializer
|
|
6
|
+
from typing import Any, List, Optional, Union
|
|
7
|
+
from typing_extensions import NotRequired, TypeAliasType, TypedDict
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
LocTypedDict = TypeAliasType("LocTypedDict", Union[str, int])
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
Loc = TypeAliasType("Loc", Union[str, int])
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class ContextTypedDict(TypedDict):
|
|
17
|
+
pass
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class Context(BaseModel):
|
|
21
|
+
pass
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class ValidationErrorTypedDict(TypedDict):
|
|
25
|
+
loc: List[LocTypedDict]
|
|
26
|
+
msg: str
|
|
27
|
+
type: str
|
|
28
|
+
input: NotRequired[Any]
|
|
29
|
+
ctx: NotRequired[ContextTypedDict]
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class ValidationError(BaseModel):
|
|
33
|
+
loc: List[Loc]
|
|
34
|
+
|
|
35
|
+
msg: str
|
|
36
|
+
|
|
37
|
+
type: str
|
|
38
|
+
|
|
39
|
+
input: Optional[Any] = None
|
|
40
|
+
|
|
41
|
+
ctx: Optional[Context] = None
|
|
42
|
+
|
|
43
|
+
@model_serializer(mode="wrap")
|
|
44
|
+
def serialize_model(self, handler):
|
|
45
|
+
optional_fields = set(["input", "ctx"])
|
|
46
|
+
serialized = handler(self)
|
|
47
|
+
m = {}
|
|
48
|
+
|
|
49
|
+
for n, f in type(self).model_fields.items():
|
|
50
|
+
k = f.alias or n
|
|
51
|
+
val = serialized.get(k, serialized.get(n))
|
|
52
|
+
|
|
53
|
+
if val != UNSET_SENTINEL:
|
|
54
|
+
if val is not None or k not in optional_fields:
|
|
55
|
+
m[k] = val
|
|
56
|
+
|
|
57
|
+
return m
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
from permitstack.types import (
|
|
5
|
+
BaseModel,
|
|
6
|
+
Nullable,
|
|
7
|
+
OptionalNullable,
|
|
8
|
+
UNSET,
|
|
9
|
+
UNSET_SENTINEL,
|
|
10
|
+
)
|
|
11
|
+
from pydantic import model_serializer
|
|
12
|
+
from typing_extensions import NotRequired, TypedDict
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class WebhookCreateTypedDict(TypedDict):
|
|
16
|
+
url: str
|
|
17
|
+
city: NotRequired[Nullable[str]]
|
|
18
|
+
state: NotRequired[Nullable[str]]
|
|
19
|
+
category: NotRequired[Nullable[str]]
|
|
20
|
+
zip_code: NotRequired[Nullable[str]]
|
|
21
|
+
description: NotRequired[Nullable[str]]
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class WebhookCreate(BaseModel):
|
|
25
|
+
url: str
|
|
26
|
+
|
|
27
|
+
city: OptionalNullable[str] = UNSET
|
|
28
|
+
|
|
29
|
+
state: OptionalNullable[str] = UNSET
|
|
30
|
+
|
|
31
|
+
category: OptionalNullable[str] = UNSET
|
|
32
|
+
|
|
33
|
+
zip_code: OptionalNullable[str] = UNSET
|
|
34
|
+
|
|
35
|
+
description: OptionalNullable[str] = UNSET
|
|
36
|
+
|
|
37
|
+
@model_serializer(mode="wrap")
|
|
38
|
+
def serialize_model(self, handler):
|
|
39
|
+
optional_fields = set(["city", "state", "category", "zip_code", "description"])
|
|
40
|
+
nullable_fields = set(["city", "state", "category", "zip_code", "description"])
|
|
41
|
+
serialized = handler(self)
|
|
42
|
+
m = {}
|
|
43
|
+
|
|
44
|
+
for n, f in type(self).model_fields.items():
|
|
45
|
+
k = f.alias or n
|
|
46
|
+
val = serialized.get(k, serialized.get(n))
|
|
47
|
+
is_nullable_and_explicitly_set = (
|
|
48
|
+
k in nullable_fields
|
|
49
|
+
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
if val != UNSET_SENTINEL:
|
|
53
|
+
if (
|
|
54
|
+
val is not None
|
|
55
|
+
or k not in optional_fields
|
|
56
|
+
or is_nullable_and_explicitly_set
|
|
57
|
+
):
|
|
58
|
+
m[k] = val
|
|
59
|
+
|
|
60
|
+
return m
|