0
# osmapi
1
2
Python wrapper for the OpenStreetMap (OSM) API that enables developers to programmatically interact with OpenStreetMap data and services. It provides full CRUD operations for OSM elements (nodes, ways, relations), changeset management, OAuth 2.0 authentication support, and robust error handling for API interactions. The library is designed for maximum usability in GIS applications, data analysis tools, mapping software, and automated OSM editing workflows.
3
4
## Package Information
5
6
- **Package Name**: osmapi
7
- **Language**: Python
8
- **Installation**: `pip install osmapi`
9
- **Requirements**: Python >= 3.8, requests library
10
11
## Core Imports
12
13
```python
14
import osmapi
15
```
16
17
Common pattern with main API class:
18
19
```python
20
import osmapi
21
api = osmapi.OsmApi()
22
```
23
24
Import specific error classes:
25
26
```python
27
from osmapi import ElementNotFoundApiError, ApiError
28
```
29
30
## Basic Usage
31
32
```python
33
import osmapi
34
35
# Read data (no authentication required)
36
api = osmapi.OsmApi()
37
node = api.NodeGet(123)
38
print(f"Node {node['id']} at ({node['lat']}, {node['lon']})")
39
40
# Download map data in a bounding box
41
map_data = api.Map(min_lon=-122.35, min_lat=47.60, max_lon=-122.30, max_lat=47.63)
42
print(f"Downloaded {len(map_data)} elements")
43
for element in map_data[:3]: # Show first 3 elements
44
print(f" {element['type']} {element['data']['id']}")
45
46
# Write data (authentication required)
47
api = osmapi.OsmApi(username="your_username", password="your_password")
48
with api.Changeset({"comment": "Adding new nodes"}) as changeset_id:
49
# Create a new node
50
new_node = api.NodeCreate({
51
"lat": 47.6062,
52
"lon": -122.3321,
53
"tag": {"name": "Seattle Center", "amenity": "attraction"}
54
})
55
print(f"Created node {new_node['id']}")
56
```
57
58
## Architecture
59
60
The osmapi library follows a comprehensive design pattern:
61
62
- **OsmApi Class**: Main interface providing all OpenStreetMap API operations
63
- **Session Management**: HTTP session handling with automatic retry logic and connection pooling
64
- **Authentication**: Support for basic auth, OAuth 2.0, and custom session objects
65
- **Changeset Management**: Automatic or manual changeset handling for data modifications
66
- **Error Hierarchy**: Comprehensive exception classes for different API error scenarios
67
- **XML Processing**: Built-in parsing and generation of OSM XML formats
68
- **Data Validation**: Type checking and validation for OSM data structures
69
70
## Capabilities
71
72
### Node Operations
73
74
Complete CRUD operations for OSM nodes including creation, retrieval, updating, deletion, and history tracking. Supports bulk operations and relationship queries.
75
76
```python { .api }
77
def NodeGet(NodeId, NodeVersion=-1): ...
78
def NodeCreate(NodeData): ...
79
def NodeUpdate(NodeData): ...
80
def NodeDelete(NodeData): ...
81
def NodeHistory(NodeId): ...
82
def NodeWays(NodeId): ...
83
def NodeRelations(NodeId): ...
84
def NodesGet(NodeIdList): ...
85
```
86
87
[Node Operations](./nodes.md)
88
89
### Way Operations
90
91
Full lifecycle management for OSM ways including creation with node references, modification, deletion, and relationship tracking. Supports bulk operations and full data retrieval.
92
93
```python { .api }
94
def WayGet(WayId, WayVersion=-1): ...
95
def WayCreate(WayData): ...
96
def WayUpdate(WayData): ...
97
def WayDelete(WayData): ...
98
def WayHistory(WayId): ...
99
def WayRelations(WayId): ...
100
def WayFull(WayId): ...
101
def WaysGet(WayIdList): ...
102
```
103
104
[Way Operations](./ways.md)
105
106
### Relation Operations
107
108
Comprehensive relation management including creation, modification, deletion, and nested relation handling. Supports both two-level and recursive full data retrieval.
109
110
```python { .api }
111
def RelationGet(RelationId, RelationVersion=-1): ...
112
def RelationCreate(RelationData): ...
113
def RelationUpdate(RelationData): ...
114
def RelationDelete(RelationData): ...
115
def RelationHistory(RelationId): ...
116
def RelationRelations(RelationId): ...
117
def RelationFull(RelationId): ...
118
def RelationFullRecur(RelationId): ...
119
def RelationsGet(RelationIdList): ...
120
```
121
122
[Relation Operations](./relations.md)
123
124
### Changeset Management
125
126
Complete changeset lifecycle including creation, modification, closure, and discussion management. Supports both automatic and manual changeset handling with batch uploads.
127
128
```python { .api }
129
@contextmanager
130
def Changeset(ChangesetTags={}): ...
131
def ChangesetGet(ChangesetId, include_discussion=False): ...
132
def ChangesetCreate(ChangesetTags={}): ...
133
def ChangesetUpdate(ChangesetTags={}): ...
134
def ChangesetClose(): ...
135
def ChangesetUpload(ChangesData): ...
136
def ChangesetDownload(ChangesetId): ...
137
def ChangesetsGet(**filters): ...
138
def ChangesetComment(ChangesetId, comment): ...
139
def ChangesetSubscribe(ChangesetId): ...
140
def ChangesetUnsubscribe(ChangesetId): ...
141
```
142
143
[Changeset Management](./changesets.md)
144
145
### Notes Operations
146
147
Full Notes API support including creation, commenting, status management, and search functionality. Enables community interaction and issue reporting.
148
149
```python { .api }
150
def NotesGet(min_lon, min_lat, max_lon, max_lat, limit=100, closed=7): ...
151
def NoteGet(id): ...
152
def NoteCreate(NoteData): ...
153
def NoteComment(NoteId, comment): ...
154
def NoteClose(NoteId, comment): ...
155
def NoteReopen(NoteId, comment): ...
156
def NotesSearch(query, limit=100, closed=7): ...
157
```
158
159
[Notes Operations](./notes.md)
160
161
### Map Data Download
162
163
Download OSM data within a specified bounding box, returning all elements (nodes, ways, relations) in that area for offline processing or analysis.
164
165
```python { .api }
166
def Map(min_lon, min_lat, max_lon, max_lat): ...
167
```
168
169
### Authentication & Configuration
170
171
Multiple authentication methods including basic auth, OAuth 2.0, and custom session handling. Supports both production and development OSM servers.
172
173
```python { .api }
174
class OsmApi:
175
def __init__(
176
self,
177
username=None,
178
password=None,
179
passwordfile=None,
180
appid="",
181
created_by="osmapi/4.3.0",
182
api="https://www.openstreetmap.org",
183
changesetauto=False,
184
changesetautotags={},
185
changesetautosize=500,
186
changesetautomulti=1,
187
session=None,
188
timeout=30,
189
): ...
190
```
191
192
[Authentication & Configuration](./authentication.md)
193
194
### Error Handling
195
196
Comprehensive error hierarchy covering all API scenarios including network errors, authentication failures, data conflicts, and OSM-specific exceptions.
197
198
```python { .api }
199
class OsmApiError(Exception): ...
200
class ApiError(OsmApiError): ...
201
class UsernamePasswordMissingError(OsmApiError): ...
202
class ElementNotFoundApiError(ApiError): ...
203
class ElementDeletedApiError(ApiError): ...
204
class VersionMismatchApiError(ApiError): ...
205
# ... 15+ additional error classes
206
```
207
208
[Error Handling](./errors.md)
209
210
## Types
211
212
### Core Data Structures
213
214
```python { .api }
215
# Node data structure
216
NodeData = {
217
'id': int, # Node ID (for existing nodes)
218
'lat': float, # Latitude (required)
219
'lon': float, # Longitude (required)
220
'tag': dict, # Key-value tags
221
'version': int, # Version number
222
'changeset': int, # Changeset ID
223
'user': str, # Username
224
'uid': int, # User ID
225
'timestamp': str, # ISO timestamp
226
'visible': bool # Visibility flag
227
}
228
229
# Way data structure
230
WayData = {
231
'id': int, # Way ID (for existing ways)
232
'nd': list[int], # List of node IDs (required)
233
'tag': dict, # Key-value tags
234
'version': int, # Version number
235
'changeset': int, # Changeset ID
236
'user': str, # Username
237
'uid': int, # User ID
238
'timestamp': str, # ISO timestamp
239
'visible': bool # Visibility flag
240
}
241
242
# Relation data structure
243
RelationData = {
244
'id': int, # Relation ID (for existing relations)
245
'member': list[dict], # List of member objects (required)
246
'tag': dict, # Key-value tags
247
'version': int, # Version number
248
'changeset': int, # Changeset ID
249
'user': str, # Username
250
'uid': int, # User ID
251
'timestamp': str, # ISO timestamp
252
'visible': bool # Visibility flag
253
}
254
255
# Relation member structure
256
RelationMember = {
257
'type': str, # 'node', 'way', or 'relation'
258
'ref': int, # Referenced element ID
259
'role': str # Role description
260
}
261
262
# Note data structure
263
NoteData = {
264
'id': int, # Note ID
265
'lat': float, # Latitude
266
'lon': float, # Longitude
267
'text': str, # Note text
268
'status': str, # 'open' or 'closed'
269
'date_created': str, # Creation timestamp
270
'date_closed': str, # Closure timestamp (or None)
271
'uid': int, # User ID (or None)
272
'user': str, # Username (or None)
273
'comments': list[dict] # List of comment objects
274
}
275
```