apple-maps-api 0.1.0__tar.gz
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.
- apple_maps_api-0.1.0/PKG-INFO +268 -0
- apple_maps_api-0.1.0/README.md +252 -0
- apple_maps_api-0.1.0/apple_maps_api/__init__.py +48 -0
- apple_maps_api-0.1.0/apple_maps_api/client.py +559 -0
- apple_maps_api-0.1.0/apple_maps_api/exceptions.py +34 -0
- apple_maps_api-0.1.0/apple_maps_api/helpers.py +145 -0
- apple_maps_api-0.1.0/apple_maps_api/models.py +288 -0
- apple_maps_api-0.1.0/apple_maps_api/version.py +34 -0
- apple_maps_api-0.1.0/pyproject.toml +51 -0
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: apple-maps-api
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A modern Python client for the Apple Maps Server API with automatic JWT management and type safety
|
|
5
|
+
Keywords: apple-maps,geocoding,search,geolocation
|
|
6
|
+
Author: Michael Bianco
|
|
7
|
+
Author-email: Michael Bianco <mike@mikebian.co>
|
|
8
|
+
Requires-Dist: pydantic>=2.12.3
|
|
9
|
+
Requires-Dist: tenacity>=9.1.2
|
|
10
|
+
Requires-Dist: pyjwt[crypto]>=2.9.0
|
|
11
|
+
Requires-Dist: httpx2>=2.7.0
|
|
12
|
+
Requires-Dist: funcy>=2.0
|
|
13
|
+
Requires-Python: >=3.11
|
|
14
|
+
Project-URL: Repository, https://github.com/iloveitaly/apple-maps-api
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
|
|
17
|
+
[](https://github.com/iloveitaly/apple-maps-api/releases)
|
|
18
|
+
[](https://pepy.tech/project/apple-maps-api)
|
|
19
|
+

|
|
20
|
+
[](https://opensource.org/licenses/MIT)
|
|
21
|
+
|
|
22
|
+
# Python Client for Apple Maps Server API
|
|
23
|
+
|
|
24
|
+
A modern, type-safe Python client for the [Apple Maps Server API](https://developer.apple.com/documentation/applemapsserverapi).
|
|
25
|
+
|
|
26
|
+
There's no python library for the Apple Maps API. Maps is super cheap compared to all of the alternatives, so with AI I figured it wouldn't be too hard to build a client library.
|
|
27
|
+
|
|
28
|
+
The goal of this library is to provide similar functionality to the radar python client. Here's the main goals:
|
|
29
|
+
|
|
30
|
+
- **Automatic JWT Management**: Handles signing and periodic refresh of Apple's ES256 tokens.
|
|
31
|
+
- **Type-Safe**: Built with Pydantic models for all API responses, giving you excellent IDE support.
|
|
32
|
+
- **Resilient**: Automatic retries with exponential backoff for transient network and server errors.
|
|
33
|
+
- **Modern**: Uses `httpx` for synchronous requests, with a structure that's ready for future async support.
|
|
34
|
+
|
|
35
|
+
## Installation
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
uv add apple-maps-api
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Usage
|
|
42
|
+
|
|
43
|
+
### Basic Setup
|
|
44
|
+
|
|
45
|
+
You'll need your Team ID, Key ID, and the private key from your Apple Developer account.
|
|
46
|
+
|
|
47
|
+
```python
|
|
48
|
+
from apple_maps_api import AppleMapsClient
|
|
49
|
+
|
|
50
|
+
client = AppleMapsClient(
|
|
51
|
+
team_id="YOUR_TEAM_ID",
|
|
52
|
+
key_id="YOUR_KEY_ID",
|
|
53
|
+
private_key="""-----BEGIN PRIVATE KEY-----
|
|
54
|
+
...
|
|
55
|
+
-----END PRIVATE KEY-----"""
|
|
56
|
+
)
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Or load credentials from environment variables:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
export APPLE_MAPS_TEAM_ID=...
|
|
63
|
+
export APPLE_MAPS_KEY_ID=...
|
|
64
|
+
export APPLE_MAPS_P8_KEY=... # PEM or raw base64 DER
|
|
65
|
+
# optional: export APPLE_MAPS_ORIGIN=https://example.com
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
And then you can source the vars from the env:
|
|
69
|
+
|
|
70
|
+
```python
|
|
71
|
+
from apple_maps_api import AppleMapsClient
|
|
72
|
+
|
|
73
|
+
client = AppleMapsClient.from_env()
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Geocoding
|
|
77
|
+
|
|
78
|
+
Convert an address string to coordinates:
|
|
79
|
+
|
|
80
|
+
```python
|
|
81
|
+
results = client.geocode("1 Apple Park Way, Cupertino, CA")
|
|
82
|
+
|
|
83
|
+
for place in results.results:
|
|
84
|
+
print(f"{place.name}: {place.coordinate.latitude}, {place.coordinate.longitude}")
|
|
85
|
+
|
|
86
|
+
# place.name => "1 Apple Park Way"
|
|
87
|
+
# place.coordinate.latitude => 37.334859
|
|
88
|
+
# place.coordinate.longitude => -122.0090403
|
|
89
|
+
# place.formattedAddressLines => ["1 Apple Park Way", "Cupertino, CA 95014", "United States"]
|
|
90
|
+
# place.structuredAddress.locality => "Cupertino"
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Reverse Geocoding
|
|
94
|
+
|
|
95
|
+
Convert coordinates back to a structured address:
|
|
96
|
+
|
|
97
|
+
```python
|
|
98
|
+
results = client.reverse_geocode((37.3346, -122.0090))
|
|
99
|
+
|
|
100
|
+
if results.results:
|
|
101
|
+
print(results.results[0].formattedAddressLines)
|
|
102
|
+
|
|
103
|
+
# place.formattedAddressLines => ["Apple Park", "1 Apple Park Way", "Cupertino, CA 95014", "United States"]
|
|
104
|
+
# place.structuredAddress.locality => "Cupertino"
|
|
105
|
+
# place.structuredAddress.postCode => "95014"
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Place Search
|
|
109
|
+
|
|
110
|
+
Search for points of interest near a location:
|
|
111
|
+
|
|
112
|
+
```python
|
|
113
|
+
results = client.search("pizza", near="37.3346,-122.0090")
|
|
114
|
+
# or: client.search("pizza", lat=37.3346, lng=-122.0090)
|
|
115
|
+
|
|
116
|
+
for place in results.results:
|
|
117
|
+
print(f"{place.name} - {place.formattedAddressLines}")
|
|
118
|
+
|
|
119
|
+
# results.results[0].name => "Pizza My Heart"
|
|
120
|
+
# results.results[0].formattedAddressLines => ["19409 Stevens Creek Blvd", "Cupertino, CA 95014", "United States"]
|
|
121
|
+
# results.results[1].name => "Mountain Mike's Pizza"
|
|
122
|
+
# results.results[2].name => "Pizz'a Chicago"
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Address Autocomplete
|
|
126
|
+
|
|
127
|
+
Provide search completions for a partial query and filter by country:
|
|
128
|
+
|
|
129
|
+
```python
|
|
130
|
+
results = client.autocomplete("1 Apple Park", limit_to_countries="US", lat=37.3346, lng=-122.0090)
|
|
131
|
+
|
|
132
|
+
for completion in results.results:
|
|
133
|
+
print(completion.displayLines)
|
|
134
|
+
|
|
135
|
+
# results.results[0].displayLines => ["1 Apple Park Way", "Cupertino, CA, United States"]
|
|
136
|
+
# results.results[1].displayLines => ["1 Apple Hill Dr", "Natick, MA, United States"]
|
|
137
|
+
# results.results[0].completionUrl => "/v1/search?q=1%20Apple%20Park%20Way..."
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Helper Functions
|
|
141
|
+
|
|
142
|
+
The library includes high-level helpers for common geocoding operations:
|
|
143
|
+
|
|
144
|
+
```python
|
|
145
|
+
from apple_maps_api import geocode_postal_code, geocode_coordinates
|
|
146
|
+
|
|
147
|
+
# Geocode a postal code
|
|
148
|
+
result = geocode_postal_code(client, postal_code="95014", country="US")
|
|
149
|
+
# result.lat => 37.2895111
|
|
150
|
+
# result.lon => -122.0811912
|
|
151
|
+
# result.city => "Cupertino"
|
|
152
|
+
# result.state_code => "CA"
|
|
153
|
+
# result.postal_code => "95014"
|
|
154
|
+
# result.formatted_address => "Cupertino, CA 95014, United States"
|
|
155
|
+
|
|
156
|
+
# Reverse geocode coordinates
|
|
157
|
+
result = geocode_coordinates(client, lat=37.3346, lon=-122.0090)
|
|
158
|
+
# result.address1 => "1 Apple Park Way"
|
|
159
|
+
# result.postal_code => "95014"
|
|
160
|
+
# result.city => "Cupertino"
|
|
161
|
+
# result.state_code => "CA"
|
|
162
|
+
# result.formatted_address => "Apple Park, 1 Apple Park Way, Cupertino, CA 95014, United States"
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Example Payloads
|
|
166
|
+
|
|
167
|
+
These examples show the real data shapes returned by the Apple Maps API for common operations.
|
|
168
|
+
|
|
169
|
+
> **Note on city names:** Apple Maps uses its own administrative boundaries. The `city` field on `GeocodeResult` maps to `structuredAddress.locality`, which may differ from the colloquial city name. For example, postal code `90210` returns `city="Los Angeles"` even though the formatted address reads `"Beverly Hills"` — Beverly Hills is an independent city but Apple Maps assigns it to the LA locality.
|
|
170
|
+
|
|
171
|
+
### Geocoding a postal code
|
|
172
|
+
|
|
173
|
+
```python
|
|
174
|
+
result = geocode_postal_code(client, postal_code="10001")
|
|
175
|
+
# result.lat => 40.7504876
|
|
176
|
+
# result.lon => -74.0025705
|
|
177
|
+
# result.city => "New York"
|
|
178
|
+
# result.state_code => "NY"
|
|
179
|
+
# result.postal_code => "10001"
|
|
180
|
+
# result.formatted_address => "New York, NY 10001, United States"
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
```python
|
|
184
|
+
result = geocode_postal_code(client, postal_code="90210")
|
|
185
|
+
# result.lat => 34.1025226
|
|
186
|
+
# result.lon => -118.4167959
|
|
187
|
+
# result.city => "Los Angeles" # NOT "Beverly Hills"
|
|
188
|
+
# result.state_code => "CA"
|
|
189
|
+
# result.postal_code => "90210"
|
|
190
|
+
# result.formatted_address => "Beverly Hills, CA 90210, United States"
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Reverse geocoding coordinates
|
|
194
|
+
|
|
195
|
+
```python
|
|
196
|
+
# Times Square, NYC
|
|
197
|
+
result = geocode_coordinates(client, lat=40.7589, lon=-73.9851)
|
|
198
|
+
# result.address1 => "1552–1568 Broadway"
|
|
199
|
+
# result.postal_code => "10036"
|
|
200
|
+
# result.city => "New York"
|
|
201
|
+
# result.state_code => "NY"
|
|
202
|
+
# result.formatted_address => "Times Square, 1552–1568 Broadway, New York, NY 10036, United States"
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Raw `reverse_geocode` response — full `structuredAddress`
|
|
206
|
+
|
|
207
|
+
Apple Park, Cupertino CA (`37.3346, -122.0090`):
|
|
208
|
+
|
|
209
|
+
```python
|
|
210
|
+
place = client.reverse_geocode((37.3346, -122.0090)).results[0]
|
|
211
|
+
# place.name => "Apple Park"
|
|
212
|
+
# place.formattedAddressLines => ["Apple Park", "1 Apple Park Way", "Cupertino, CA 95014", "United States"]
|
|
213
|
+
# place.structuredAddress.administrativeArea => "California"
|
|
214
|
+
# place.structuredAddress.administrativeAreaCode => "CA"
|
|
215
|
+
# place.structuredAddress.subAdministrativeArea => None
|
|
216
|
+
# place.structuredAddress.locality => "Cupertino"
|
|
217
|
+
# place.structuredAddress.subLocality => None
|
|
218
|
+
# place.structuredAddress.fullThoroughfare => "1 Apple Park Way"
|
|
219
|
+
# place.structuredAddress.thoroughfare => "Apple Park Way"
|
|
220
|
+
# place.structuredAddress.subThoroughfare => "1"
|
|
221
|
+
# place.structuredAddress.postCode => "95014"
|
|
222
|
+
# place.structuredAddress.areasOfInterest => ["Apple Park"]
|
|
223
|
+
# place.structuredAddress.dependentLocalities => None
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
Times Square, NYC (`40.7589, -73.9851`):
|
|
227
|
+
|
|
228
|
+
```python
|
|
229
|
+
place = client.reverse_geocode((40.7589, -73.9851)).results[0]
|
|
230
|
+
# place.name => "Times Square"
|
|
231
|
+
# place.formattedAddressLines => ["Times Square", "1552–1568 Broadway", "New York, NY 10036", "United States"]
|
|
232
|
+
# place.structuredAddress.administrativeArea => "New York"
|
|
233
|
+
# place.structuredAddress.administrativeAreaCode => "NY"
|
|
234
|
+
# place.structuredAddress.subAdministrativeArea => None
|
|
235
|
+
# place.structuredAddress.locality => "New York"
|
|
236
|
+
# place.structuredAddress.subLocality => "Manhattan"
|
|
237
|
+
# place.structuredAddress.fullThoroughfare => "1552–1568 Broadway"
|
|
238
|
+
# place.structuredAddress.thoroughfare => "Broadway"
|
|
239
|
+
# place.structuredAddress.subThoroughfare => "1552–1568"
|
|
240
|
+
# place.structuredAddress.postCode => "10036"
|
|
241
|
+
# place.structuredAddress.areasOfInterest => ["Times Square", "Manhattan"]
|
|
242
|
+
# place.structuredAddress.dependentLocalities => ["Broadway", "Times Square", "Theater District", "Midtown Manhattan", "Midtown", "North Hudson"]
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
Beverly Hills, CA (`34.1025226, -118.4167959`) — note `locality` vs formatted address mismatch:
|
|
246
|
+
|
|
247
|
+
```python
|
|
248
|
+
place = client.reverse_geocode((34.1025226, -118.4167959)).results[0]
|
|
249
|
+
# place.name => "1731 N Franklin Canyon Dr"
|
|
250
|
+
# place.formattedAddressLines => ["1731 N Franklin Canyon Dr", "Beverly Hills, CA 90210", "United States"]
|
|
251
|
+
# place.structuredAddress.administrativeArea => "California"
|
|
252
|
+
# place.structuredAddress.administrativeAreaCode => "CA"
|
|
253
|
+
# place.structuredAddress.subAdministrativeArea => None
|
|
254
|
+
# place.structuredAddress.locality => "Los Angeles" # NOT "Beverly Hills"
|
|
255
|
+
# place.structuredAddress.subLocality => "Beverly Crest"
|
|
256
|
+
# place.structuredAddress.fullThoroughfare => "1731 N Franklin Canyon Dr"
|
|
257
|
+
# place.structuredAddress.thoroughfare => "N Franklin Canyon Dr"
|
|
258
|
+
# place.structuredAddress.subThoroughfare => "1731"
|
|
259
|
+
# place.structuredAddress.postCode => "90210"
|
|
260
|
+
# place.structuredAddress.areasOfInterest => None
|
|
261
|
+
# place.structuredAddress.dependentLocalities => ["Beverly Crest"]
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
## [MIT License](LICENSE.md)
|
|
265
|
+
|
|
266
|
+
---
|
|
267
|
+
|
|
268
|
+
*This project was created from [iloveitaly/python-package-template](https://github.com/iloveitaly/python-package-template)*
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
[](https://github.com/iloveitaly/apple-maps-api/releases)
|
|
2
|
+
[](https://pepy.tech/project/apple-maps-api)
|
|
3
|
+

|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
|
|
6
|
+
# Python Client for Apple Maps Server API
|
|
7
|
+
|
|
8
|
+
A modern, type-safe Python client for the [Apple Maps Server API](https://developer.apple.com/documentation/applemapsserverapi).
|
|
9
|
+
|
|
10
|
+
There's no python library for the Apple Maps API. Maps is super cheap compared to all of the alternatives, so with AI I figured it wouldn't be too hard to build a client library.
|
|
11
|
+
|
|
12
|
+
The goal of this library is to provide similar functionality to the radar python client. Here's the main goals:
|
|
13
|
+
|
|
14
|
+
- **Automatic JWT Management**: Handles signing and periodic refresh of Apple's ES256 tokens.
|
|
15
|
+
- **Type-Safe**: Built with Pydantic models for all API responses, giving you excellent IDE support.
|
|
16
|
+
- **Resilient**: Automatic retries with exponential backoff for transient network and server errors.
|
|
17
|
+
- **Modern**: Uses `httpx` for synchronous requests, with a structure that's ready for future async support.
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
uv add apple-maps-api
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Usage
|
|
26
|
+
|
|
27
|
+
### Basic Setup
|
|
28
|
+
|
|
29
|
+
You'll need your Team ID, Key ID, and the private key from your Apple Developer account.
|
|
30
|
+
|
|
31
|
+
```python
|
|
32
|
+
from apple_maps_api import AppleMapsClient
|
|
33
|
+
|
|
34
|
+
client = AppleMapsClient(
|
|
35
|
+
team_id="YOUR_TEAM_ID",
|
|
36
|
+
key_id="YOUR_KEY_ID",
|
|
37
|
+
private_key="""-----BEGIN PRIVATE KEY-----
|
|
38
|
+
...
|
|
39
|
+
-----END PRIVATE KEY-----"""
|
|
40
|
+
)
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Or load credentials from environment variables:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
export APPLE_MAPS_TEAM_ID=...
|
|
47
|
+
export APPLE_MAPS_KEY_ID=...
|
|
48
|
+
export APPLE_MAPS_P8_KEY=... # PEM or raw base64 DER
|
|
49
|
+
# optional: export APPLE_MAPS_ORIGIN=https://example.com
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
And then you can source the vars from the env:
|
|
53
|
+
|
|
54
|
+
```python
|
|
55
|
+
from apple_maps_api import AppleMapsClient
|
|
56
|
+
|
|
57
|
+
client = AppleMapsClient.from_env()
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Geocoding
|
|
61
|
+
|
|
62
|
+
Convert an address string to coordinates:
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
results = client.geocode("1 Apple Park Way, Cupertino, CA")
|
|
66
|
+
|
|
67
|
+
for place in results.results:
|
|
68
|
+
print(f"{place.name}: {place.coordinate.latitude}, {place.coordinate.longitude}")
|
|
69
|
+
|
|
70
|
+
# place.name => "1 Apple Park Way"
|
|
71
|
+
# place.coordinate.latitude => 37.334859
|
|
72
|
+
# place.coordinate.longitude => -122.0090403
|
|
73
|
+
# place.formattedAddressLines => ["1 Apple Park Way", "Cupertino, CA 95014", "United States"]
|
|
74
|
+
# place.structuredAddress.locality => "Cupertino"
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Reverse Geocoding
|
|
78
|
+
|
|
79
|
+
Convert coordinates back to a structured address:
|
|
80
|
+
|
|
81
|
+
```python
|
|
82
|
+
results = client.reverse_geocode((37.3346, -122.0090))
|
|
83
|
+
|
|
84
|
+
if results.results:
|
|
85
|
+
print(results.results[0].formattedAddressLines)
|
|
86
|
+
|
|
87
|
+
# place.formattedAddressLines => ["Apple Park", "1 Apple Park Way", "Cupertino, CA 95014", "United States"]
|
|
88
|
+
# place.structuredAddress.locality => "Cupertino"
|
|
89
|
+
# place.structuredAddress.postCode => "95014"
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Place Search
|
|
93
|
+
|
|
94
|
+
Search for points of interest near a location:
|
|
95
|
+
|
|
96
|
+
```python
|
|
97
|
+
results = client.search("pizza", near="37.3346,-122.0090")
|
|
98
|
+
# or: client.search("pizza", lat=37.3346, lng=-122.0090)
|
|
99
|
+
|
|
100
|
+
for place in results.results:
|
|
101
|
+
print(f"{place.name} - {place.formattedAddressLines}")
|
|
102
|
+
|
|
103
|
+
# results.results[0].name => "Pizza My Heart"
|
|
104
|
+
# results.results[0].formattedAddressLines => ["19409 Stevens Creek Blvd", "Cupertino, CA 95014", "United States"]
|
|
105
|
+
# results.results[1].name => "Mountain Mike's Pizza"
|
|
106
|
+
# results.results[2].name => "Pizz'a Chicago"
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Address Autocomplete
|
|
110
|
+
|
|
111
|
+
Provide search completions for a partial query and filter by country:
|
|
112
|
+
|
|
113
|
+
```python
|
|
114
|
+
results = client.autocomplete("1 Apple Park", limit_to_countries="US", lat=37.3346, lng=-122.0090)
|
|
115
|
+
|
|
116
|
+
for completion in results.results:
|
|
117
|
+
print(completion.displayLines)
|
|
118
|
+
|
|
119
|
+
# results.results[0].displayLines => ["1 Apple Park Way", "Cupertino, CA, United States"]
|
|
120
|
+
# results.results[1].displayLines => ["1 Apple Hill Dr", "Natick, MA, United States"]
|
|
121
|
+
# results.results[0].completionUrl => "/v1/search?q=1%20Apple%20Park%20Way..."
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Helper Functions
|
|
125
|
+
|
|
126
|
+
The library includes high-level helpers for common geocoding operations:
|
|
127
|
+
|
|
128
|
+
```python
|
|
129
|
+
from apple_maps_api import geocode_postal_code, geocode_coordinates
|
|
130
|
+
|
|
131
|
+
# Geocode a postal code
|
|
132
|
+
result = geocode_postal_code(client, postal_code="95014", country="US")
|
|
133
|
+
# result.lat => 37.2895111
|
|
134
|
+
# result.lon => -122.0811912
|
|
135
|
+
# result.city => "Cupertino"
|
|
136
|
+
# result.state_code => "CA"
|
|
137
|
+
# result.postal_code => "95014"
|
|
138
|
+
# result.formatted_address => "Cupertino, CA 95014, United States"
|
|
139
|
+
|
|
140
|
+
# Reverse geocode coordinates
|
|
141
|
+
result = geocode_coordinates(client, lat=37.3346, lon=-122.0090)
|
|
142
|
+
# result.address1 => "1 Apple Park Way"
|
|
143
|
+
# result.postal_code => "95014"
|
|
144
|
+
# result.city => "Cupertino"
|
|
145
|
+
# result.state_code => "CA"
|
|
146
|
+
# result.formatted_address => "Apple Park, 1 Apple Park Way, Cupertino, CA 95014, United States"
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Example Payloads
|
|
150
|
+
|
|
151
|
+
These examples show the real data shapes returned by the Apple Maps API for common operations.
|
|
152
|
+
|
|
153
|
+
> **Note on city names:** Apple Maps uses its own administrative boundaries. The `city` field on `GeocodeResult` maps to `structuredAddress.locality`, which may differ from the colloquial city name. For example, postal code `90210` returns `city="Los Angeles"` even though the formatted address reads `"Beverly Hills"` — Beverly Hills is an independent city but Apple Maps assigns it to the LA locality.
|
|
154
|
+
|
|
155
|
+
### Geocoding a postal code
|
|
156
|
+
|
|
157
|
+
```python
|
|
158
|
+
result = geocode_postal_code(client, postal_code="10001")
|
|
159
|
+
# result.lat => 40.7504876
|
|
160
|
+
# result.lon => -74.0025705
|
|
161
|
+
# result.city => "New York"
|
|
162
|
+
# result.state_code => "NY"
|
|
163
|
+
# result.postal_code => "10001"
|
|
164
|
+
# result.formatted_address => "New York, NY 10001, United States"
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
```python
|
|
168
|
+
result = geocode_postal_code(client, postal_code="90210")
|
|
169
|
+
# result.lat => 34.1025226
|
|
170
|
+
# result.lon => -118.4167959
|
|
171
|
+
# result.city => "Los Angeles" # NOT "Beverly Hills"
|
|
172
|
+
# result.state_code => "CA"
|
|
173
|
+
# result.postal_code => "90210"
|
|
174
|
+
# result.formatted_address => "Beverly Hills, CA 90210, United States"
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Reverse geocoding coordinates
|
|
178
|
+
|
|
179
|
+
```python
|
|
180
|
+
# Times Square, NYC
|
|
181
|
+
result = geocode_coordinates(client, lat=40.7589, lon=-73.9851)
|
|
182
|
+
# result.address1 => "1552–1568 Broadway"
|
|
183
|
+
# result.postal_code => "10036"
|
|
184
|
+
# result.city => "New York"
|
|
185
|
+
# result.state_code => "NY"
|
|
186
|
+
# result.formatted_address => "Times Square, 1552–1568 Broadway, New York, NY 10036, United States"
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Raw `reverse_geocode` response — full `structuredAddress`
|
|
190
|
+
|
|
191
|
+
Apple Park, Cupertino CA (`37.3346, -122.0090`):
|
|
192
|
+
|
|
193
|
+
```python
|
|
194
|
+
place = client.reverse_geocode((37.3346, -122.0090)).results[0]
|
|
195
|
+
# place.name => "Apple Park"
|
|
196
|
+
# place.formattedAddressLines => ["Apple Park", "1 Apple Park Way", "Cupertino, CA 95014", "United States"]
|
|
197
|
+
# place.structuredAddress.administrativeArea => "California"
|
|
198
|
+
# place.structuredAddress.administrativeAreaCode => "CA"
|
|
199
|
+
# place.structuredAddress.subAdministrativeArea => None
|
|
200
|
+
# place.structuredAddress.locality => "Cupertino"
|
|
201
|
+
# place.structuredAddress.subLocality => None
|
|
202
|
+
# place.structuredAddress.fullThoroughfare => "1 Apple Park Way"
|
|
203
|
+
# place.structuredAddress.thoroughfare => "Apple Park Way"
|
|
204
|
+
# place.structuredAddress.subThoroughfare => "1"
|
|
205
|
+
# place.structuredAddress.postCode => "95014"
|
|
206
|
+
# place.structuredAddress.areasOfInterest => ["Apple Park"]
|
|
207
|
+
# place.structuredAddress.dependentLocalities => None
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
Times Square, NYC (`40.7589, -73.9851`):
|
|
211
|
+
|
|
212
|
+
```python
|
|
213
|
+
place = client.reverse_geocode((40.7589, -73.9851)).results[0]
|
|
214
|
+
# place.name => "Times Square"
|
|
215
|
+
# place.formattedAddressLines => ["Times Square", "1552–1568 Broadway", "New York, NY 10036", "United States"]
|
|
216
|
+
# place.structuredAddress.administrativeArea => "New York"
|
|
217
|
+
# place.structuredAddress.administrativeAreaCode => "NY"
|
|
218
|
+
# place.structuredAddress.subAdministrativeArea => None
|
|
219
|
+
# place.structuredAddress.locality => "New York"
|
|
220
|
+
# place.structuredAddress.subLocality => "Manhattan"
|
|
221
|
+
# place.structuredAddress.fullThoroughfare => "1552–1568 Broadway"
|
|
222
|
+
# place.structuredAddress.thoroughfare => "Broadway"
|
|
223
|
+
# place.structuredAddress.subThoroughfare => "1552–1568"
|
|
224
|
+
# place.structuredAddress.postCode => "10036"
|
|
225
|
+
# place.structuredAddress.areasOfInterest => ["Times Square", "Manhattan"]
|
|
226
|
+
# place.structuredAddress.dependentLocalities => ["Broadway", "Times Square", "Theater District", "Midtown Manhattan", "Midtown", "North Hudson"]
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
Beverly Hills, CA (`34.1025226, -118.4167959`) — note `locality` vs formatted address mismatch:
|
|
230
|
+
|
|
231
|
+
```python
|
|
232
|
+
place = client.reverse_geocode((34.1025226, -118.4167959)).results[0]
|
|
233
|
+
# place.name => "1731 N Franklin Canyon Dr"
|
|
234
|
+
# place.formattedAddressLines => ["1731 N Franklin Canyon Dr", "Beverly Hills, CA 90210", "United States"]
|
|
235
|
+
# place.structuredAddress.administrativeArea => "California"
|
|
236
|
+
# place.structuredAddress.administrativeAreaCode => "CA"
|
|
237
|
+
# place.structuredAddress.subAdministrativeArea => None
|
|
238
|
+
# place.structuredAddress.locality => "Los Angeles" # NOT "Beverly Hills"
|
|
239
|
+
# place.structuredAddress.subLocality => "Beverly Crest"
|
|
240
|
+
# place.structuredAddress.fullThoroughfare => "1731 N Franklin Canyon Dr"
|
|
241
|
+
# place.structuredAddress.thoroughfare => "N Franklin Canyon Dr"
|
|
242
|
+
# place.structuredAddress.subThoroughfare => "1731"
|
|
243
|
+
# place.structuredAddress.postCode => "90210"
|
|
244
|
+
# place.structuredAddress.areasOfInterest => None
|
|
245
|
+
# place.structuredAddress.dependentLocalities => ["Beverly Crest"]
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
## [MIT License](LICENSE.md)
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
*This project was created from [iloveitaly/python-package-template](https://github.com/iloveitaly/python-package-template)*
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"""apple-maps-api: A Python client for the Apple Maps Server API.
|
|
2
|
+
|
|
3
|
+
This package provides a type-safe, production-ready client for interacting with
|
|
4
|
+
Apple Maps geocoding, reverse geocoding, search, and autocomplete APIs.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from .client import AppleMapsClient
|
|
8
|
+
from .helpers import geocode_coordinates, geocode_postal_code
|
|
9
|
+
from .models import (
|
|
10
|
+
AddressCategory,
|
|
11
|
+
AutocompleteResult,
|
|
12
|
+
GeocodeResult,
|
|
13
|
+
Location,
|
|
14
|
+
MapRegion,
|
|
15
|
+
Place,
|
|
16
|
+
PlaceResults,
|
|
17
|
+
PoiCategory,
|
|
18
|
+
SearchACResultType,
|
|
19
|
+
SearchAutocompleteResponse,
|
|
20
|
+
SearchPlace,
|
|
21
|
+
SearchResponse,
|
|
22
|
+
SearchResultType,
|
|
23
|
+
StructuredAddress,
|
|
24
|
+
TokenResponse,
|
|
25
|
+
)
|
|
26
|
+
from .version import __version__
|
|
27
|
+
|
|
28
|
+
__all__ = [
|
|
29
|
+
"__version__",
|
|
30
|
+
"AppleMapsClient",
|
|
31
|
+
"geocode_coordinates",
|
|
32
|
+
"geocode_postal_code",
|
|
33
|
+
"AddressCategory",
|
|
34
|
+
"AutocompleteResult",
|
|
35
|
+
"GeocodeResult",
|
|
36
|
+
"Location",
|
|
37
|
+
"MapRegion",
|
|
38
|
+
"Place",
|
|
39
|
+
"PlaceResults",
|
|
40
|
+
"PoiCategory",
|
|
41
|
+
"SearchACResultType",
|
|
42
|
+
"SearchAutocompleteResponse",
|
|
43
|
+
"SearchPlace",
|
|
44
|
+
"SearchResponse",
|
|
45
|
+
"SearchResultType",
|
|
46
|
+
"StructuredAddress",
|
|
47
|
+
"TokenResponse",
|
|
48
|
+
]
|