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,24 @@
|
|
|
1
|
+
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
from .contractorsummary import ContractorSummary, ContractorSummaryTypedDict
|
|
5
|
+
from permitstack.types import BaseModel
|
|
6
|
+
from typing import List
|
|
7
|
+
from typing_extensions import TypedDict
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class ContractorSearchResponseTypedDict(TypedDict):
|
|
11
|
+
total: int
|
|
12
|
+
page: int
|
|
13
|
+
per_page: int
|
|
14
|
+
results: List[ContractorSummaryTypedDict]
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class ContractorSearchResponse(BaseModel):
|
|
18
|
+
total: int
|
|
19
|
+
|
|
20
|
+
page: int
|
|
21
|
+
|
|
22
|
+
per_page: int
|
|
23
|
+
|
|
24
|
+
results: List[ContractorSummary]
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
from datetime import date
|
|
5
|
+
from permitstack.types import BaseModel, Nullable, UNSET_SENTINEL
|
|
6
|
+
from pydantic import model_serializer
|
|
7
|
+
from typing import List
|
|
8
|
+
from typing_extensions import TypedDict
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class ContractorSummaryTypedDict(TypedDict):
|
|
12
|
+
id: str
|
|
13
|
+
name: str
|
|
14
|
+
license_number: Nullable[str]
|
|
15
|
+
license_state: Nullable[str]
|
|
16
|
+
city: Nullable[str]
|
|
17
|
+
state: Nullable[str]
|
|
18
|
+
total_permits: int
|
|
19
|
+
first_permit_date: Nullable[date]
|
|
20
|
+
last_permit_date: Nullable[date]
|
|
21
|
+
specialties: Nullable[List[str]]
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class ContractorSummary(BaseModel):
|
|
25
|
+
id: str
|
|
26
|
+
|
|
27
|
+
name: str
|
|
28
|
+
|
|
29
|
+
license_number: Nullable[str]
|
|
30
|
+
|
|
31
|
+
license_state: Nullable[str]
|
|
32
|
+
|
|
33
|
+
city: Nullable[str]
|
|
34
|
+
|
|
35
|
+
state: Nullable[str]
|
|
36
|
+
|
|
37
|
+
total_permits: int
|
|
38
|
+
|
|
39
|
+
first_permit_date: Nullable[date]
|
|
40
|
+
|
|
41
|
+
last_permit_date: Nullable[date]
|
|
42
|
+
|
|
43
|
+
specialties: Nullable[List[str]]
|
|
44
|
+
|
|
45
|
+
@model_serializer(mode="wrap")
|
|
46
|
+
def serialize_model(self, handler):
|
|
47
|
+
serialized = handler(self)
|
|
48
|
+
m = {}
|
|
49
|
+
|
|
50
|
+
for n, f in type(self).model_fields.items():
|
|
51
|
+
k = f.alias or n
|
|
52
|
+
val = serialized.get(k, serialized.get(n))
|
|
53
|
+
|
|
54
|
+
if val != UNSET_SENTINEL:
|
|
55
|
+
m[k] = val
|
|
56
|
+
|
|
57
|
+
return m
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
from permitstack.types import BaseModel
|
|
5
|
+
from permitstack.utils import FieldMetadata, PathParamMetadata
|
|
6
|
+
from typing_extensions import Annotated, TypedDict
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class DeleteWebhookRequestTypedDict(TypedDict):
|
|
10
|
+
webhook_id: str
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class DeleteWebhookRequest(BaseModel):
|
|
14
|
+
webhook_id: Annotated[
|
|
15
|
+
str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))
|
|
16
|
+
]
|
|
@@ -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 ExportPermitsCsvRequestTypedDict(TypedDict):
|
|
18
|
+
city: NotRequired[Nullable[str]]
|
|
19
|
+
state: NotRequired[Nullable[str]]
|
|
20
|
+
category: NotRequired[Nullable[str]]
|
|
21
|
+
zip_code: NotRequired[Nullable[str]]
|
|
22
|
+
filed_after: NotRequired[Nullable[str]]
|
|
23
|
+
filed_before: NotRequired[Nullable[str]]
|
|
24
|
+
limit: NotRequired[int]
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class ExportPermitsCsvRequest(BaseModel):
|
|
28
|
+
city: Annotated[
|
|
29
|
+
OptionalNullable[str],
|
|
30
|
+
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
|
31
|
+
] = UNSET
|
|
32
|
+
|
|
33
|
+
state: Annotated[
|
|
34
|
+
OptionalNullable[str],
|
|
35
|
+
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
|
36
|
+
] = UNSET
|
|
37
|
+
|
|
38
|
+
category: Annotated[
|
|
39
|
+
OptionalNullable[str],
|
|
40
|
+
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
|
41
|
+
] = UNSET
|
|
42
|
+
|
|
43
|
+
zip_code: Annotated[
|
|
44
|
+
OptionalNullable[str],
|
|
45
|
+
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
|
46
|
+
] = UNSET
|
|
47
|
+
|
|
48
|
+
filed_after: Annotated[
|
|
49
|
+
OptionalNullable[str],
|
|
50
|
+
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
|
51
|
+
] = UNSET
|
|
52
|
+
|
|
53
|
+
filed_before: Annotated[
|
|
54
|
+
OptionalNullable[str],
|
|
55
|
+
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
|
56
|
+
] = UNSET
|
|
57
|
+
|
|
58
|
+
limit: Annotated[
|
|
59
|
+
Optional[int],
|
|
60
|
+
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
|
61
|
+
] = 10000
|
|
62
|
+
|
|
63
|
+
@model_serializer(mode="wrap")
|
|
64
|
+
def serialize_model(self, handler):
|
|
65
|
+
optional_fields = set(
|
|
66
|
+
[
|
|
67
|
+
"city",
|
|
68
|
+
"state",
|
|
69
|
+
"category",
|
|
70
|
+
"zip_code",
|
|
71
|
+
"filed_after",
|
|
72
|
+
"filed_before",
|
|
73
|
+
"limit",
|
|
74
|
+
]
|
|
75
|
+
)
|
|
76
|
+
nullable_fields = set(
|
|
77
|
+
["city", "state", "category", "zip_code", "filed_after", "filed_before"]
|
|
78
|
+
)
|
|
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,46 @@
|
|
|
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, PathParamMetadata, QueryParamMetadata
|
|
6
|
+
from pydantic import model_serializer
|
|
7
|
+
from typing import Optional
|
|
8
|
+
from typing_extensions import Annotated, NotRequired, TypedDict
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class GetContractorPermitsRequestTypedDict(TypedDict):
|
|
12
|
+
contractor_id: str
|
|
13
|
+
page: NotRequired[int]
|
|
14
|
+
per_page: NotRequired[int]
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class GetContractorPermitsRequest(BaseModel):
|
|
18
|
+
contractor_id: Annotated[
|
|
19
|
+
str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
page: Annotated[
|
|
23
|
+
Optional[int],
|
|
24
|
+
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
|
25
|
+
] = 1
|
|
26
|
+
|
|
27
|
+
per_page: Annotated[
|
|
28
|
+
Optional[int],
|
|
29
|
+
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
|
30
|
+
] = 25
|
|
31
|
+
|
|
32
|
+
@model_serializer(mode="wrap")
|
|
33
|
+
def serialize_model(self, handler):
|
|
34
|
+
optional_fields = set(["page", "per_page"])
|
|
35
|
+
serialized = handler(self)
|
|
36
|
+
m = {}
|
|
37
|
+
|
|
38
|
+
for n, f in type(self).model_fields.items():
|
|
39
|
+
k = f.alias or n
|
|
40
|
+
val = serialized.get(k, serialized.get(n))
|
|
41
|
+
|
|
42
|
+
if val != UNSET_SENTINEL:
|
|
43
|
+
if val is not None or k not in optional_fields:
|
|
44
|
+
m[k] = val
|
|
45
|
+
|
|
46
|
+
return m
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
from permitstack.types import BaseModel
|
|
5
|
+
from permitstack.utils import FieldMetadata, PathParamMetadata
|
|
6
|
+
from typing_extensions import Annotated, TypedDict
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class GetContractorRequestTypedDict(TypedDict):
|
|
10
|
+
contractor_id: str
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class GetContractorRequest(BaseModel):
|
|
14
|
+
contractor_id: Annotated[
|
|
15
|
+
str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))
|
|
16
|
+
]
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
from permitstack.types import BaseModel
|
|
5
|
+
from permitstack.utils import FieldMetadata, PathParamMetadata
|
|
6
|
+
from typing_extensions import Annotated, TypedDict
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class GetPermitRequestTypedDict(TypedDict):
|
|
10
|
+
permit_id: str
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class GetPermitRequest(BaseModel):
|
|
14
|
+
permit_id: Annotated[
|
|
15
|
+
str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))
|
|
16
|
+
]
|
|
@@ -0,0 +1,46 @@
|
|
|
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, PathParamMetadata, QueryParamMetadata
|
|
6
|
+
from pydantic import model_serializer
|
|
7
|
+
from typing import Optional
|
|
8
|
+
from typing_extensions import Annotated, NotRequired, TypedDict
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class GetPermitsByAddressRequestTypedDict(TypedDict):
|
|
12
|
+
address: str
|
|
13
|
+
page: NotRequired[int]
|
|
14
|
+
per_page: NotRequired[int]
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class GetPermitsByAddressRequest(BaseModel):
|
|
18
|
+
address: Annotated[
|
|
19
|
+
str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False))
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
page: Annotated[
|
|
23
|
+
Optional[int],
|
|
24
|
+
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
|
25
|
+
] = 1
|
|
26
|
+
|
|
27
|
+
per_page: Annotated[
|
|
28
|
+
Optional[int],
|
|
29
|
+
FieldMetadata(query=QueryParamMetadata(style="form", explode=True)),
|
|
30
|
+
] = 25
|
|
31
|
+
|
|
32
|
+
@model_serializer(mode="wrap")
|
|
33
|
+
def serialize_model(self, handler):
|
|
34
|
+
optional_fields = set(["page", "per_page"])
|
|
35
|
+
serialized = handler(self)
|
|
36
|
+
m = {}
|
|
37
|
+
|
|
38
|
+
for n, f in type(self).model_fields.items():
|
|
39
|
+
k = f.alias or n
|
|
40
|
+
val = serialized.get(k, serialized.get(n))
|
|
41
|
+
|
|
42
|
+
if val != UNSET_SENTINEL:
|
|
43
|
+
if val is not None or k not in optional_fields:
|
|
44
|
+
m[k] = val
|
|
45
|
+
|
|
46
|
+
return m
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
from permitstack.types import BaseModel
|
|
5
|
+
from permitstack.utils import FieldMetadata, QueryParamMetadata
|
|
6
|
+
from typing_extensions import Annotated, TypedDict
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class GetPropertyHistoryRequestTypedDict(TypedDict):
|
|
10
|
+
address: str
|
|
11
|
+
r"""Street address to look up"""
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class GetPropertyHistoryRequest(BaseModel):
|
|
15
|
+
address: Annotated[
|
|
16
|
+
str, FieldMetadata(query=QueryParamMetadata(style="form", explode=True))
|
|
17
|
+
]
|
|
18
|
+
r"""Street address to look up"""
|
|
@@ -0,0 +1,27 @@
|
|
|
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
|
+
PermitCategory = Literal[
|
|
8
|
+
"new_construction",
|
|
9
|
+
"renovation",
|
|
10
|
+
"demolition",
|
|
11
|
+
"electrical",
|
|
12
|
+
"plumbing",
|
|
13
|
+
"mechanical",
|
|
14
|
+
"roofing",
|
|
15
|
+
"solar",
|
|
16
|
+
"ev_charger",
|
|
17
|
+
"hvac",
|
|
18
|
+
"fire_alarm",
|
|
19
|
+
"sign",
|
|
20
|
+
"fence",
|
|
21
|
+
"pool",
|
|
22
|
+
"foundation",
|
|
23
|
+
"addition",
|
|
24
|
+
"interior_remodel",
|
|
25
|
+
"grading",
|
|
26
|
+
"other",
|
|
27
|
+
]
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
from datetime import date
|
|
5
|
+
from permitstack.types import (
|
|
6
|
+
BaseModel,
|
|
7
|
+
Nullable,
|
|
8
|
+
OptionalNullable,
|
|
9
|
+
UNSET,
|
|
10
|
+
UNSET_SENTINEL,
|
|
11
|
+
)
|
|
12
|
+
from pydantic import model_serializer
|
|
13
|
+
from typing import List
|
|
14
|
+
from typing_extensions import NotRequired, TypedDict
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class PermitDetailTypedDict(TypedDict):
|
|
18
|
+
id: str
|
|
19
|
+
permit_number: Nullable[str]
|
|
20
|
+
status: str
|
|
21
|
+
category: str
|
|
22
|
+
tags: Nullable[List[str]]
|
|
23
|
+
property_type: str
|
|
24
|
+
address_street: Nullable[str]
|
|
25
|
+
address_city: Nullable[str]
|
|
26
|
+
address_state: Nullable[str]
|
|
27
|
+
address_zip: Nullable[str]
|
|
28
|
+
description_raw: Nullable[str]
|
|
29
|
+
estimated_value: Nullable[float]
|
|
30
|
+
date_filed: Nullable[date]
|
|
31
|
+
date_issued: Nullable[date]
|
|
32
|
+
date_completed: Nullable[date]
|
|
33
|
+
date_expired: Nullable[date]
|
|
34
|
+
fee_amount: Nullable[float]
|
|
35
|
+
stories: Nullable[int]
|
|
36
|
+
units: Nullable[int]
|
|
37
|
+
square_footage: Nullable[float]
|
|
38
|
+
applicant_name: Nullable[str]
|
|
39
|
+
owner_name: Nullable[str]
|
|
40
|
+
contractor_name: NotRequired[Nullable[str]]
|
|
41
|
+
jurisdiction_name: NotRequired[Nullable[str]]
|
|
42
|
+
latitude: NotRequired[Nullable[float]]
|
|
43
|
+
longitude: NotRequired[Nullable[float]]
|
|
44
|
+
contractor_license: NotRequired[Nullable[str]]
|
|
45
|
+
created_at: NotRequired[Nullable[str]]
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class PermitDetail(BaseModel):
|
|
49
|
+
id: str
|
|
50
|
+
|
|
51
|
+
permit_number: Nullable[str]
|
|
52
|
+
|
|
53
|
+
status: str
|
|
54
|
+
|
|
55
|
+
category: str
|
|
56
|
+
|
|
57
|
+
tags: Nullable[List[str]]
|
|
58
|
+
|
|
59
|
+
property_type: str
|
|
60
|
+
|
|
61
|
+
address_street: Nullable[str]
|
|
62
|
+
|
|
63
|
+
address_city: Nullable[str]
|
|
64
|
+
|
|
65
|
+
address_state: Nullable[str]
|
|
66
|
+
|
|
67
|
+
address_zip: Nullable[str]
|
|
68
|
+
|
|
69
|
+
description_raw: Nullable[str]
|
|
70
|
+
|
|
71
|
+
estimated_value: Nullable[float]
|
|
72
|
+
|
|
73
|
+
date_filed: Nullable[date]
|
|
74
|
+
|
|
75
|
+
date_issued: Nullable[date]
|
|
76
|
+
|
|
77
|
+
date_completed: Nullable[date]
|
|
78
|
+
|
|
79
|
+
date_expired: Nullable[date]
|
|
80
|
+
|
|
81
|
+
fee_amount: Nullable[float]
|
|
82
|
+
|
|
83
|
+
stories: Nullable[int]
|
|
84
|
+
|
|
85
|
+
units: Nullable[int]
|
|
86
|
+
|
|
87
|
+
square_footage: Nullable[float]
|
|
88
|
+
|
|
89
|
+
applicant_name: Nullable[str]
|
|
90
|
+
|
|
91
|
+
owner_name: Nullable[str]
|
|
92
|
+
|
|
93
|
+
contractor_name: OptionalNullable[str] = UNSET
|
|
94
|
+
|
|
95
|
+
jurisdiction_name: OptionalNullable[str] = UNSET
|
|
96
|
+
|
|
97
|
+
latitude: OptionalNullable[float] = UNSET
|
|
98
|
+
|
|
99
|
+
longitude: OptionalNullable[float] = UNSET
|
|
100
|
+
|
|
101
|
+
contractor_license: OptionalNullable[str] = UNSET
|
|
102
|
+
|
|
103
|
+
created_at: OptionalNullable[str] = UNSET
|
|
104
|
+
|
|
105
|
+
@model_serializer(mode="wrap")
|
|
106
|
+
def serialize_model(self, handler):
|
|
107
|
+
optional_fields = set(
|
|
108
|
+
[
|
|
109
|
+
"contractor_name",
|
|
110
|
+
"jurisdiction_name",
|
|
111
|
+
"latitude",
|
|
112
|
+
"longitude",
|
|
113
|
+
"contractor_license",
|
|
114
|
+
"created_at",
|
|
115
|
+
]
|
|
116
|
+
)
|
|
117
|
+
nullable_fields = set(
|
|
118
|
+
[
|
|
119
|
+
"permit_number",
|
|
120
|
+
"tags",
|
|
121
|
+
"address_street",
|
|
122
|
+
"address_city",
|
|
123
|
+
"address_state",
|
|
124
|
+
"address_zip",
|
|
125
|
+
"description_raw",
|
|
126
|
+
"estimated_value",
|
|
127
|
+
"date_filed",
|
|
128
|
+
"date_issued",
|
|
129
|
+
"date_completed",
|
|
130
|
+
"contractor_name",
|
|
131
|
+
"jurisdiction_name",
|
|
132
|
+
"latitude",
|
|
133
|
+
"longitude",
|
|
134
|
+
"date_expired",
|
|
135
|
+
"fee_amount",
|
|
136
|
+
"stories",
|
|
137
|
+
"units",
|
|
138
|
+
"square_footage",
|
|
139
|
+
"applicant_name",
|
|
140
|
+
"owner_name",
|
|
141
|
+
"contractor_license",
|
|
142
|
+
"created_at",
|
|
143
|
+
]
|
|
144
|
+
)
|
|
145
|
+
serialized = handler(self)
|
|
146
|
+
m = {}
|
|
147
|
+
|
|
148
|
+
for n, f in type(self).model_fields.items():
|
|
149
|
+
k = f.alias or n
|
|
150
|
+
val = serialized.get(k, serialized.get(n))
|
|
151
|
+
is_nullable_and_explicitly_set = (
|
|
152
|
+
k in nullable_fields
|
|
153
|
+
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
if val != UNSET_SENTINEL:
|
|
157
|
+
if (
|
|
158
|
+
val is not None
|
|
159
|
+
or k not in optional_fields
|
|
160
|
+
or is_nullable_and_explicitly_set
|
|
161
|
+
):
|
|
162
|
+
m[k] = val
|
|
163
|
+
|
|
164
|
+
return m
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
from .permitsummary import PermitSummary, PermitSummaryTypedDict
|
|
5
|
+
from permitstack.types import BaseModel
|
|
6
|
+
from typing import List
|
|
7
|
+
from typing_extensions import TypedDict
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class PermitSearchResponseTypedDict(TypedDict):
|
|
11
|
+
total: int
|
|
12
|
+
page: int
|
|
13
|
+
per_page: int
|
|
14
|
+
results: List[PermitSummaryTypedDict]
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class PermitSearchResponse(BaseModel):
|
|
18
|
+
total: int
|
|
19
|
+
|
|
20
|
+
page: int
|
|
21
|
+
|
|
22
|
+
per_page: int
|
|
23
|
+
|
|
24
|
+
results: List[PermitSummary]
|
|
@@ -0,0 +1,16 @@
|
|
|
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
|
+
PermitStatus = Literal[
|
|
8
|
+
"filed",
|
|
9
|
+
"issued",
|
|
10
|
+
"in_progress",
|
|
11
|
+
"final",
|
|
12
|
+
"expired",
|
|
13
|
+
"cancelled",
|
|
14
|
+
"revoked",
|
|
15
|
+
"unknown",
|
|
16
|
+
]
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
from datetime import date
|
|
5
|
+
from permitstack.types import (
|
|
6
|
+
BaseModel,
|
|
7
|
+
Nullable,
|
|
8
|
+
OptionalNullable,
|
|
9
|
+
UNSET,
|
|
10
|
+
UNSET_SENTINEL,
|
|
11
|
+
)
|
|
12
|
+
from pydantic import model_serializer
|
|
13
|
+
from typing import List
|
|
14
|
+
from typing_extensions import NotRequired, TypedDict
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class PermitSummaryTypedDict(TypedDict):
|
|
18
|
+
id: str
|
|
19
|
+
permit_number: Nullable[str]
|
|
20
|
+
status: str
|
|
21
|
+
category: str
|
|
22
|
+
tags: Nullable[List[str]]
|
|
23
|
+
property_type: str
|
|
24
|
+
address_street: Nullable[str]
|
|
25
|
+
address_city: Nullable[str]
|
|
26
|
+
address_state: Nullable[str]
|
|
27
|
+
address_zip: Nullable[str]
|
|
28
|
+
description_raw: Nullable[str]
|
|
29
|
+
estimated_value: Nullable[float]
|
|
30
|
+
date_filed: Nullable[date]
|
|
31
|
+
date_issued: Nullable[date]
|
|
32
|
+
date_completed: Nullable[date]
|
|
33
|
+
contractor_name: NotRequired[Nullable[str]]
|
|
34
|
+
jurisdiction_name: NotRequired[Nullable[str]]
|
|
35
|
+
latitude: NotRequired[Nullable[float]]
|
|
36
|
+
longitude: NotRequired[Nullable[float]]
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class PermitSummary(BaseModel):
|
|
40
|
+
id: str
|
|
41
|
+
|
|
42
|
+
permit_number: Nullable[str]
|
|
43
|
+
|
|
44
|
+
status: str
|
|
45
|
+
|
|
46
|
+
category: str
|
|
47
|
+
|
|
48
|
+
tags: Nullable[List[str]]
|
|
49
|
+
|
|
50
|
+
property_type: str
|
|
51
|
+
|
|
52
|
+
address_street: Nullable[str]
|
|
53
|
+
|
|
54
|
+
address_city: Nullable[str]
|
|
55
|
+
|
|
56
|
+
address_state: Nullable[str]
|
|
57
|
+
|
|
58
|
+
address_zip: Nullable[str]
|
|
59
|
+
|
|
60
|
+
description_raw: Nullable[str]
|
|
61
|
+
|
|
62
|
+
estimated_value: Nullable[float]
|
|
63
|
+
|
|
64
|
+
date_filed: Nullable[date]
|
|
65
|
+
|
|
66
|
+
date_issued: Nullable[date]
|
|
67
|
+
|
|
68
|
+
date_completed: Nullable[date]
|
|
69
|
+
|
|
70
|
+
contractor_name: OptionalNullable[str] = UNSET
|
|
71
|
+
|
|
72
|
+
jurisdiction_name: OptionalNullable[str] = UNSET
|
|
73
|
+
|
|
74
|
+
latitude: OptionalNullable[float] = UNSET
|
|
75
|
+
|
|
76
|
+
longitude: OptionalNullable[float] = UNSET
|
|
77
|
+
|
|
78
|
+
@model_serializer(mode="wrap")
|
|
79
|
+
def serialize_model(self, handler):
|
|
80
|
+
optional_fields = set(
|
|
81
|
+
["contractor_name", "jurisdiction_name", "latitude", "longitude"]
|
|
82
|
+
)
|
|
83
|
+
nullable_fields = set(
|
|
84
|
+
[
|
|
85
|
+
"permit_number",
|
|
86
|
+
"tags",
|
|
87
|
+
"address_street",
|
|
88
|
+
"address_city",
|
|
89
|
+
"address_state",
|
|
90
|
+
"address_zip",
|
|
91
|
+
"description_raw",
|
|
92
|
+
"estimated_value",
|
|
93
|
+
"date_filed",
|
|
94
|
+
"date_issued",
|
|
95
|
+
"date_completed",
|
|
96
|
+
"contractor_name",
|
|
97
|
+
"jurisdiction_name",
|
|
98
|
+
"latitude",
|
|
99
|
+
"longitude",
|
|
100
|
+
]
|
|
101
|
+
)
|
|
102
|
+
serialized = handler(self)
|
|
103
|
+
m = {}
|
|
104
|
+
|
|
105
|
+
for n, f in type(self).model_fields.items():
|
|
106
|
+
k = f.alias or n
|
|
107
|
+
val = serialized.get(k, serialized.get(n))
|
|
108
|
+
is_nullable_and_explicitly_set = (
|
|
109
|
+
k in nullable_fields
|
|
110
|
+
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
if val != UNSET_SENTINEL:
|
|
114
|
+
if (
|
|
115
|
+
val is not None
|
|
116
|
+
or k not in optional_fields
|
|
117
|
+
or is_nullable_and_explicitly_set
|
|
118
|
+
):
|
|
119
|
+
m[k] = val
|
|
120
|
+
|
|
121
|
+
return m
|