osmapi.OsmApi
The OsmApi module is a wrapper for the OpenStreetMap API. As such it provides an easy access to the functionality of the API.
You can find this module on PyPI or on GitHub.
Find all information about changes of the different versions of this module in the CHANGELOG.
Notes:
- dictionary keys are _unicode_
- changeset is _integer_
- version is _integer_
- tag is a _dictionary_
- timestamp is _unicode_
- user is _unicode_
- uid is _integer_
- node lat and lon are _floats_
- way nd is list of _integers_
- relation member is a _list of dictionaries_ like
{"role": "", "ref":123, "type": "node"} - Since version 5.0 of this library, all method names are in snake_case, the CamelCase versions are deprecated and will be removed in version 6.0.
1""" 2The OsmApi module is a wrapper for the OpenStreetMap API. 3As such it provides an easy access to the functionality of the API. 4 5You can find this module [on PyPI](https://pypi.python.org/pypi/osmapi) 6or [on GitHub](https://github.com/metaodi/osmapi). 7 8Find all information about changes of the different versions of this module 9[in the CHANGELOG](https://github.com/metaodi/osmapi/blob/master/CHANGELOG.md). 10 11 12## Notes: 13 14* **dictionary keys** are _unicode_ 15* **changeset** is _integer_ 16* **version** is _integer_ 17* **tag** is a _dictionary_ 18* **timestamp** is _unicode_ 19* **user** is _unicode_ 20* **uid** is _integer_ 21* node **lat** and **lon** are _floats_ 22* way **nd** is list of _integers_ 23* relation **member** is a _list of dictionaries_ like 24`{"role": "", "ref":123, "type": "node"}` 25* Since version 5.0 of this library, all method names are in snake_case, 26the CamelCase versions are deprecated and will be removed in version 6.0. 27""" 28 29import re 30import logging 31import warnings 32from contextlib import contextmanager 33from typing import Any, Optional, Generator 34from xml.dom.minidom import Element 35import requests 36 37from osmapi import __version__ 38from . import errors 39from . import http 40from . import xmlbuilder 41from .node import NodeMixin 42from .way import WayMixin 43from .relation import RelationMixin 44from .changeset import ChangesetMixin 45from .note import NoteMixin 46from .capabilities import CapabilitiesMixin 47 48logger = logging.getLogger(__name__) 49 50 51class OsmApi( 52 NodeMixin, 53 WayMixin, 54 RelationMixin, 55 ChangesetMixin, 56 NoteMixin, 57 CapabilitiesMixin, 58): 59 """ 60 Main class of osmapi, instanciate this class to use osmapi 61 """ 62 63 def __init__( 64 self, 65 username: Optional[str] = None, 66 password: Optional[str] = None, 67 passwordfile: Optional[str] = None, 68 appid: str = "", 69 created_by: str = f"osmapi/{__version__}", 70 api: str = "https://www.openstreetmap.org", 71 session: Optional[requests.Session] = None, 72 timeout: int = 30, 73 ) -> None: 74 """ 75 Initialized the OsmApi object. 76 77 There are two different ways to authenticate a user. 78 Either `username` and `password` are supplied directly or the path 79 to a `passwordfile` is given, where on the first line username 80 and password must be colon-separated (<user>:<pass>). 81 82 To credit the application that supplies changes to OSM, an `appid` 83 can be provided. This is a string identifying the application. 84 If this is omitted "osmapi" is used. 85 86 It is possible to configure the URL to connect to using the `api` 87 parameter. By default this is the SSL version of the production API 88 of OpenStreetMap, for testing purposes, one might prefer the official 89 test instance at "api06.dev.openstreetmap.org" or any other valid 90 OSM-API. To use an encrypted connection (HTTPS) simply add 'https://' 91 in front of the hostname of the `api` parameter (e.g. 92 https://api.openstreetmap.com). 93 94 The `session` parameter can be used to provide a custom requests 95 http session object (requests.Session). This might be useful for 96 OAuth authentication, custom adapters, hooks etc. 97 98 Finally the `timeout` parameter is used by the http session to 99 throw an expcetion if the the timeout (in seconds) has passed without 100 an answer from the server. 101 """ 102 # Get username 103 self._username: Optional[str] = None 104 if username: 105 self._username = username 106 elif passwordfile: 107 with open(passwordfile) as f: 108 pass_line = f.readline() 109 self._username = pass_line.partition(":")[0].strip() 110 111 # Get password 112 self._password: Optional[str] = None 113 if password: 114 self._password = password 115 elif passwordfile: 116 with open(passwordfile) as f: 117 for line in f: 118 key, _, value = line.strip().partition(":") 119 if key == self._username: 120 self._password = value 121 122 # Get API 123 self._api: str = api.strip("/") 124 125 # Get created_by 126 if not appid: 127 self._created_by: str = created_by 128 else: 129 self._created_by = f"{appid} ({created_by})" 130 131 # Initialisation 132 self._current_changeset_id: int = 0 133 134 # Http connection 135 self.http_session: Optional[requests.Session] = session 136 self._timeout: int = timeout 137 auth: Optional[tuple[str, str]] = None 138 if self._username and self._password: 139 auth = (self._username, self._password) 140 self._session: http.OsmApiSession = http.OsmApiSession( 141 self._api, 142 self._created_by, 143 auth=auth, 144 session=self.http_session, 145 timeout=self._timeout, 146 ) 147 148 def __enter__(self) -> "OsmApi": 149 self._session = http.OsmApiSession( 150 self._api, 151 self._created_by, 152 session=self.http_session, 153 timeout=self._timeout, 154 ) 155 return self 156 157 def __exit__(self, *args: Any) -> None: 158 self.close() 159 160 def close(self) -> None: 161 if self._session: 162 self._session.close() 163 164 ################################################## 165 # Capabilities # 166 ################################################## 167 168 def Capabilities(self) -> dict[str, dict[str, Any]]: 169 """ 170 Returns the API capabilities as a dict. 171 172 .. deprecated:: 173 Use :meth:`capabilities` instead. 174 175 The capabilities can be used by a client to 176 gain insights of the server in use. 177 """ 178 warnings.warn( 179 "Capabilities() is deprecated, use capabilities() instead", 180 DeprecationWarning, 181 stacklevel=2, 182 ) 183 return self.capabilities() 184 185 ################################################## 186 # Node - Deprecated CamelCase methods # 187 ################################################## 188 189 def NodeGet(self, NodeId: int, NodeVersion: int = -1) -> dict[str, Any]: 190 """.. deprecated:: Use :meth:`node_get` instead.""" 191 warnings.warn( 192 "NodeGet() is deprecated, use node_get() instead", 193 DeprecationWarning, 194 stacklevel=2, 195 ) 196 return self.node_get(NodeId, NodeVersion) 197 198 def NodeCreate(self, NodeData: dict[str, Any]) -> Optional[dict[str, Any]]: 199 """.. deprecated:: Use :meth:`node_create` instead.""" 200 warnings.warn( 201 "NodeCreate() is deprecated, use node_create() instead", 202 DeprecationWarning, 203 stacklevel=2, 204 ) 205 return self.node_create(NodeData) 206 207 def NodeUpdate(self, NodeData: dict[str, Any]) -> Optional[dict[str, Any]]: 208 """.. deprecated:: Use :meth:`node_update` instead.""" 209 warnings.warn( 210 "NodeUpdate() is deprecated, use node_update() instead", 211 DeprecationWarning, 212 stacklevel=2, 213 ) 214 return self.node_update(NodeData) 215 216 def NodeDelete(self, NodeData: dict[str, Any]) -> Optional[dict[str, Any]]: 217 """.. deprecated:: Use :meth:`node_delete` instead.""" 218 warnings.warn( 219 "NodeDelete() is deprecated, use node_delete() instead", 220 DeprecationWarning, 221 stacklevel=2, 222 ) 223 return self.node_delete(NodeData) 224 225 def NodeHistory(self, NodeId: int) -> dict[int, dict[str, Any]]: 226 """.. deprecated:: Use :meth:`node_history` instead.""" 227 warnings.warn( 228 "NodeHistory() is deprecated, use node_history() instead", 229 DeprecationWarning, 230 stacklevel=2, 231 ) 232 return self.node_history(NodeId) 233 234 def NodeWays(self, NodeId: int) -> list[dict[str, Any]]: 235 """.. deprecated:: Use :meth:`node_ways` instead.""" 236 warnings.warn( 237 "NodeWays() is deprecated, use node_ways() instead", 238 DeprecationWarning, 239 stacklevel=2, 240 ) 241 return self.node_ways(NodeId) 242 243 def NodeRelations(self, NodeId: int) -> list[dict[str, Any]]: 244 """.. deprecated:: Use :meth:`node_relations` instead.""" 245 warnings.warn( 246 "NodeRelations() is deprecated, use node_relations() instead", 247 DeprecationWarning, 248 stacklevel=2, 249 ) 250 return self.node_relations(NodeId) 251 252 def NodesGet(self, NodeIdList: list[int]) -> dict[int, dict[str, Any]]: 253 """.. deprecated:: Use :meth:`nodes_get` instead.""" 254 warnings.warn( 255 "NodesGet() is deprecated, use nodes_get() instead", 256 DeprecationWarning, 257 stacklevel=2, 258 ) 259 return self.nodes_get(NodeIdList) 260 261 ################################################## 262 # Way - Deprecated CamelCase methods # 263 ################################################## 264 265 def WayGet(self, WayId: int, WayVersion: int = -1) -> dict[str, Any]: 266 """.. deprecated:: Use :meth:`way_get` instead.""" 267 warnings.warn( 268 "WayGet() is deprecated, use way_get() instead", 269 DeprecationWarning, 270 stacklevel=2, 271 ) 272 return self.way_get(WayId, WayVersion) 273 274 def WayCreate(self, WayData: dict[str, Any]) -> Optional[dict[str, Any]]: 275 """.. deprecated:: Use :meth:`way_create` instead.""" 276 warnings.warn( 277 "WayCreate() is deprecated, use way_create() instead", 278 DeprecationWarning, 279 stacklevel=2, 280 ) 281 return self.way_create(WayData) 282 283 def WayUpdate(self, WayData: dict[str, Any]) -> Optional[dict[str, Any]]: 284 """.. deprecated:: Use :meth:`way_update` instead.""" 285 warnings.warn( 286 "WayUpdate() is deprecated, use way_update() instead", 287 DeprecationWarning, 288 stacklevel=2, 289 ) 290 return self.way_update(WayData) 291 292 def WayDelete(self, WayData: dict[str, Any]) -> Optional[dict[str, Any]]: 293 """.. deprecated:: Use :meth:`way_delete` instead.""" 294 warnings.warn( 295 "WayDelete() is deprecated, use way_delete() instead", 296 DeprecationWarning, 297 stacklevel=2, 298 ) 299 return self.way_delete(WayData) 300 301 def WayHistory(self, WayId: int) -> dict[int, dict[str, Any]]: 302 """.. deprecated:: Use :meth:`way_history` instead.""" 303 warnings.warn( 304 "WayHistory() is deprecated, use way_history() instead", 305 DeprecationWarning, 306 stacklevel=2, 307 ) 308 return self.way_history(WayId) 309 310 def WayRelations(self, WayId: int) -> list[dict[str, Any]]: 311 """.. deprecated:: Use :meth:`way_relations` instead.""" 312 warnings.warn( 313 "WayRelations() is deprecated, use way_relations() instead", 314 DeprecationWarning, 315 stacklevel=2, 316 ) 317 return self.way_relations(WayId) 318 319 def WayFull(self, WayId: int) -> list[dict[str, Any]]: 320 """.. deprecated:: Use :meth:`way_full` instead.""" 321 warnings.warn( 322 "WayFull() is deprecated, use way_full() instead", 323 DeprecationWarning, 324 stacklevel=2, 325 ) 326 return self.way_full(WayId) 327 328 def WaysGet(self, WayIdList: list[int]) -> dict[int, dict[str, Any]]: 329 """.. deprecated:: Use :meth:`ways_get` instead.""" 330 warnings.warn( 331 "WaysGet() is deprecated, use ways_get() instead", 332 DeprecationWarning, 333 stacklevel=2, 334 ) 335 return self.ways_get(WayIdList) 336 337 ################################################## 338 # Relation - Deprecated CamelCase methods # 339 ################################################## 340 341 def RelationGet(self, RelationId: int, RelationVersion: int = -1) -> dict[str, Any]: 342 """.. deprecated:: Use :meth:`relation_get` instead.""" 343 warnings.warn( 344 "RelationGet() is deprecated, use relation_get() instead", 345 DeprecationWarning, 346 stacklevel=2, 347 ) 348 return self.relation_get(RelationId, RelationVersion) 349 350 def RelationCreate(self, RelationData: dict[str, Any]) -> Optional[dict[str, Any]]: 351 """.. deprecated:: Use :meth:`relation_create` instead.""" 352 warnings.warn( 353 "RelationCreate() is deprecated, use relation_create() instead", 354 DeprecationWarning, 355 stacklevel=2, 356 ) 357 return self.relation_create(RelationData) 358 359 def RelationUpdate(self, RelationData: dict[str, Any]) -> Optional[dict[str, Any]]: 360 """.. deprecated:: Use :meth:`relation_update` instead.""" 361 warnings.warn( 362 "RelationUpdate() is deprecated, use relation_update() instead", 363 DeprecationWarning, 364 stacklevel=2, 365 ) 366 return self.relation_update(RelationData) 367 368 def RelationDelete(self, RelationData: dict[str, Any]) -> Optional[dict[str, Any]]: 369 """.. deprecated:: Use :meth:`relation_delete` instead.""" 370 warnings.warn( 371 "RelationDelete() is deprecated, use relation_delete() instead", 372 DeprecationWarning, 373 stacklevel=2, 374 ) 375 return self.relation_delete(RelationData) 376 377 def RelationHistory(self, RelationId: int) -> dict[int, dict[str, Any]]: 378 """.. deprecated:: Use :meth:`relation_history` instead.""" 379 warnings.warn( 380 "RelationHistory() is deprecated, use relation_history() instead", 381 DeprecationWarning, 382 stacklevel=2, 383 ) 384 return self.relation_history(RelationId) 385 386 def RelationRelations(self, RelationId: int) -> list[dict[str, Any]]: 387 """.. deprecated:: Use :meth:`relation_relations` instead.""" 388 warnings.warn( 389 "RelationRelations() is deprecated, use relation_relations() instead", 390 DeprecationWarning, 391 stacklevel=2, 392 ) 393 return self.relation_relations(RelationId) 394 395 def RelationFullRecur(self, RelationId: int) -> list[dict[str, Any]]: 396 """.. deprecated:: Use :meth:`relation_full_recur` instead.""" 397 warnings.warn( 398 "RelationFullRecur() is deprecated, use relation_full_recur() instead", 399 DeprecationWarning, 400 stacklevel=2, 401 ) 402 return self.relation_full_recur(RelationId) 403 404 def RelationFull(self, RelationId: int) -> list[dict[str, Any]]: 405 """.. deprecated:: Use :meth:`relation_full` instead.""" 406 warnings.warn( 407 "RelationFull() is deprecated, use relation_full() instead", 408 DeprecationWarning, 409 stacklevel=2, 410 ) 411 return self.relation_full(RelationId) 412 413 def RelationsGet(self, RelationIdList: list[int]) -> dict[int, dict[str, Any]]: 414 """.. deprecated:: Use :meth:`relations_get` instead.""" 415 warnings.warn( 416 "RelationsGet() is deprecated, use relations_get() instead", 417 DeprecationWarning, 418 stacklevel=2, 419 ) 420 return self.relations_get(RelationIdList) 421 422 ################################################## 423 # Changeset - Deprecated CamelCase methods # 424 ################################################## 425 426 @contextmanager 427 def Changeset( 428 self, ChangesetTags: Optional[dict[str, str]] = None 429 ) -> Generator[int, None, None]: 430 """.. deprecated:: Use :meth:`changeset` instead.""" 431 warnings.warn( 432 "Changeset() is deprecated, use changeset() instead", 433 DeprecationWarning, 434 stacklevel=2, 435 ) 436 with self.changeset(ChangesetTags) as changeset_id: 437 yield changeset_id 438 439 def ChangesetGet( 440 self, ChangesetId: int, include_discussion: bool = False 441 ) -> dict[str, Any]: 442 """.. deprecated:: Use :meth:`changeset_get` instead.""" 443 warnings.warn( 444 "ChangesetGet() is deprecated, use changeset_get() instead", 445 DeprecationWarning, 446 stacklevel=2, 447 ) 448 return self.changeset_get(ChangesetId, include_discussion) 449 450 def ChangesetUpdate(self, ChangesetTags: Optional[dict[str, str]] = None) -> int: 451 """.. deprecated:: Use :meth:`changeset_update` instead.""" 452 warnings.warn( 453 "ChangesetUpdate() is deprecated, use changeset_update() instead", 454 DeprecationWarning, 455 stacklevel=2, 456 ) 457 return self.changeset_update(ChangesetTags) 458 459 def ChangesetCreate(self, ChangesetTags: Optional[dict[str, str]] = None) -> int: 460 """.. deprecated:: Use :meth:`changeset_create` instead.""" 461 warnings.warn( 462 "ChangesetCreate() is deprecated, use changeset_create() instead", 463 DeprecationWarning, 464 stacklevel=2, 465 ) 466 return self.changeset_create(ChangesetTags) 467 468 def ChangesetClose(self) -> int: 469 """.. deprecated:: Use :meth:`changeset_close` instead.""" 470 warnings.warn( 471 "ChangesetClose() is deprecated, use changeset_close() instead", 472 DeprecationWarning, 473 stacklevel=2, 474 ) 475 return self.changeset_close() 476 477 def ChangesetUpload( 478 self, ChangesData: list[dict[str, Any]] 479 ) -> list[dict[str, Any]]: 480 """.. deprecated:: Use :meth:`changeset_upload` instead.""" 481 warnings.warn( 482 "ChangesetUpload() is deprecated, use changeset_upload() instead", 483 DeprecationWarning, 484 stacklevel=2, 485 ) 486 return self.changeset_upload(ChangesData) 487 488 def ChangesetDownload(self, ChangesetId: int) -> list[dict[str, Any]]: 489 """.. deprecated:: Use :meth:`changeset_download` instead.""" 490 warnings.warn( 491 "ChangesetDownload() is deprecated, use changeset_download() instead", 492 DeprecationWarning, 493 stacklevel=2, 494 ) 495 return self.changeset_download(ChangesetId) 496 497 def ChangesetsGet( # noqa 498 self, 499 min_lon: Optional[float] = None, 500 min_lat: Optional[float] = None, 501 max_lon: Optional[float] = None, 502 max_lat: Optional[float] = None, 503 userid: Optional[int] = None, 504 username: Optional[str] = None, 505 closed_after: Optional[str] = None, 506 created_before: Optional[str] = None, 507 only_open: bool = False, 508 only_closed: bool = False, 509 ) -> dict[int, dict[str, Any]]: 510 """.. deprecated:: Use :meth:`changesets_get` instead.""" 511 warnings.warn( 512 "ChangesetsGet() is deprecated, use changesets_get() instead", 513 DeprecationWarning, 514 stacklevel=2, 515 ) 516 return self.changesets_get( 517 min_lon, 518 min_lat, 519 max_lon, 520 max_lat, 521 userid, 522 username, 523 closed_after, 524 created_before, 525 only_open, 526 only_closed, 527 ) 528 529 def ChangesetComment(self, ChangesetId: int, comment: str) -> dict[str, Any]: 530 """.. deprecated:: Use :meth:`changeset_comment` instead.""" 531 warnings.warn( 532 "ChangesetComment() is deprecated, use changeset_comment() instead", 533 DeprecationWarning, 534 stacklevel=2, 535 ) 536 return self.changeset_comment(ChangesetId, comment) 537 538 def ChangesetSubscribe(self, ChangesetId: int) -> dict[str, Any]: 539 """.. deprecated:: Use :meth:`changeset_subscribe` instead.""" 540 warnings.warn( 541 "ChangesetSubscribe() is deprecated, use changeset_subscribe() instead", 542 DeprecationWarning, 543 stacklevel=2, 544 ) 545 return self.changeset_subscribe(ChangesetId) 546 547 def ChangesetUnsubscribe(self, ChangesetId: int) -> dict[str, Any]: 548 """.. deprecated:: Use :meth:`changeset_unsubscribe` instead.""" 549 warnings.warn( 550 "ChangesetUnsubscribe() is deprecated, use changeset_unsubscribe() instead", 551 DeprecationWarning, 552 stacklevel=2, 553 ) 554 return self.changeset_unsubscribe(ChangesetId) 555 556 ################################################## 557 # Note - Deprecated CamelCase methods # 558 ################################################## 559 560 def NotesGet( 561 self, 562 min_lon: float, 563 min_lat: float, 564 max_lon: float, 565 max_lat: float, 566 limit: int = 100, 567 closed: int = 7, 568 ) -> list[dict[str, Any]]: 569 """.. deprecated:: Use :meth:`notes_get` instead.""" 570 warnings.warn( 571 "NotesGet() is deprecated, use notes_get() instead", 572 DeprecationWarning, 573 stacklevel=2, 574 ) 575 return self.notes_get(min_lon, min_lat, max_lon, max_lat, limit, closed) 576 577 def NoteGet(self, id: int) -> dict[str, Any]: 578 """.. deprecated:: Use :meth:`note_get` instead.""" 579 warnings.warn( 580 "NoteGet() is deprecated, use note_get() instead", 581 DeprecationWarning, 582 stacklevel=2, 583 ) 584 return self.note_get(id) 585 586 def NoteCreate(self, NoteData: dict[str, Any]) -> dict[str, Any]: 587 """.. deprecated:: Use :meth:`note_create` instead.""" 588 warnings.warn( 589 "NoteCreate() is deprecated, use note_create() instead", 590 DeprecationWarning, 591 stacklevel=2, 592 ) 593 return self.note_create(NoteData) 594 595 def NoteComment(self, note_id: int, comment: str) -> dict[str, Any]: 596 """.. deprecated:: Use :meth:`note_comment` instead.""" 597 warnings.warn( 598 "NoteComment() is deprecated, use note_comment() instead", 599 DeprecationWarning, 600 stacklevel=2, 601 ) 602 return self.note_comment(note_id, comment) 603 604 def NoteClose(self, note_id: int, comment: Optional[str] = None) -> dict[str, Any]: 605 """.. deprecated:: Use :meth:`note_close` instead.""" 606 warnings.warn( 607 "NoteClose() is deprecated, use note_close() instead", 608 DeprecationWarning, 609 stacklevel=2, 610 ) 611 return self.note_close(note_id, comment) 612 613 def NoteReopen(self, note_id: int, comment: Optional[str] = None) -> dict[str, Any]: 614 """.. deprecated:: Use :meth:`note_reopen` instead.""" 615 warnings.warn( 616 "NoteReopen() is deprecated, use note_reopen() instead", 617 DeprecationWarning, 618 stacklevel=2, 619 ) 620 return self.note_reopen(note_id, comment) 621 622 def NotesSearch( 623 self, query: str, limit: int = 100, closed: int = 7 624 ) -> list[dict[str, Any]]: 625 """.. deprecated:: Use :meth:`notes_search` instead.""" 626 warnings.warn( 627 "NotesSearch() is deprecated, use notes_search() instead", 628 DeprecationWarning, 629 stacklevel=2, 630 ) 631 return self.notes_search(query, limit, closed) 632 633 def _NoteAction( 634 self, path: str, comment: Optional[str] = None, optionalAuth: bool = True 635 ) -> dict[str, Any]: 636 """Internal method - calls _note_action.""" 637 return self._note_action(path, comment, optionalAuth) 638 639 ################################################## 640 # Map - Deprecated CamelCase methods # 641 ################################################## 642 643 def Map( 644 self, min_lon: float, min_lat: float, max_lon: float, max_lat: float 645 ) -> list[dict[str, Any]]: 646 """.. deprecated:: Use :meth:`map` instead.""" 647 warnings.warn( 648 "Map() is deprecated, use map() instead", 649 DeprecationWarning, 650 stacklevel=2, 651 ) 652 return self.map(min_lon, min_lat, max_lon, max_lat) 653 654 ################################################## 655 # Internal method # 656 ################################################## 657 658 def _do( # type: ignore[return-value] # noqa: C901 659 self, action: str, osm_type: str, osm_data: dict[str, Any] 660 ) -> dict[str, Any]: 661 if not self._current_changeset_id: 662 raise errors.NoChangesetOpenError( 663 "You need to open a changeset before uploading data" 664 ) 665 if "timestamp" in osm_data: 666 osm_data.pop("timestamp") 667 osm_data["changeset"] = self._current_changeset_id 668 if action == "create": 669 if osm_data.get("id", -1) > 0: 670 raise errors.OsmTypeAlreadyExistsError( 671 f"This {osm_type} already exists" 672 ) 673 try: 674 result = self._session._put( 675 f"/api/0.6/{osm_type}/create", 676 xmlbuilder._xml_build(osm_type, osm_data, data=self), 677 ) 678 except errors.ApiError as e: 679 if e.status == 409 and re.search( 680 r"The changeset .* was closed at .*", e.payload 681 ): 682 raise errors.ChangesetClosedApiError( 683 e.status, e.reason, e.payload 684 ) from e 685 elif e.status == 409: 686 raise errors.VersionMismatchApiError( 687 e.status, e.reason, e.payload 688 ) from e 689 elif e.status == 412: 690 raise errors.PreconditionFailedApiError( 691 e.status, e.reason, e.payload 692 ) from e 693 else: 694 raise 695 osm_data["id"] = int(result.strip()) 696 osm_data["version"] = 1 697 return osm_data 698 elif action == "modify": 699 try: 700 result = self._session._put( 701 f"/api/0.6/{osm_type}/{osm_data['id']}", 702 xmlbuilder._xml_build(osm_type, osm_data, data=self), 703 ) 704 except errors.ApiError as e: 705 logger.error(e.reason) 706 if e.status == 409 and re.search( 707 r"The changeset .* was closed at .*", e.payload 708 ): 709 raise errors.ChangesetClosedApiError( 710 e.status, e.reason, e.payload 711 ) from e 712 elif e.status == 409: 713 raise errors.VersionMismatchApiError( 714 e.status, e.reason, e.payload 715 ) from e 716 elif e.status == 412: 717 raise errors.PreconditionFailedApiError( 718 e.status, e.reason, e.payload 719 ) from e 720 else: 721 raise 722 osm_data["version"] = int(result.strip()) 723 return osm_data 724 elif action == "delete": 725 try: 726 result = self._session._delete( 727 f"/api/0.6/{osm_type}/{osm_data['id']}", 728 xmlbuilder._xml_build(osm_type, osm_data, data=self), 729 ) 730 except errors.ApiError as e: 731 if e.status == 409 and re.search( 732 r"The changeset .* was closed at .*", e.payload 733 ): 734 raise errors.ChangesetClosedApiError( 735 e.status, e.reason, e.payload 736 ) from e 737 elif e.status == 409: 738 raise errors.VersionMismatchApiError( 739 e.status, e.reason, e.payload 740 ) from e 741 elif e.status == 412: 742 raise errors.PreconditionFailedApiError( 743 e.status, e.reason, e.payload 744 ) from e 745 else: 746 raise 747 osm_data["version"] = int(result.strip()) 748 osm_data["visible"] = False 749 return osm_data 750 751 def _add_changeset_data(self, change_data: list[dict[str, Any]], type: str) -> str: 752 data = "" 753 for changed_element in change_data: 754 changed_element["changeset"] = self._current_changeset_id 755 xml_data = xmlbuilder._xml_build(type, changed_element, False, data=self) 756 data += xml_data.decode("utf-8") 757 return data 758 759 def _assign_id_and_version( 760 self, response_data: list[Element], request_data: list[dict[str, Any]] 761 ) -> None: 762 for response, element in zip(response_data, request_data): 763 element["id"] = int(response.getAttribute("new_id")) 764 element["version"] = int(response.getAttribute("new_version"))
52class OsmApi( 53 NodeMixin, 54 WayMixin, 55 RelationMixin, 56 ChangesetMixin, 57 NoteMixin, 58 CapabilitiesMixin, 59): 60 """ 61 Main class of osmapi, instanciate this class to use osmapi 62 """ 63 64 def __init__( 65 self, 66 username: Optional[str] = None, 67 password: Optional[str] = None, 68 passwordfile: Optional[str] = None, 69 appid: str = "", 70 created_by: str = f"osmapi/{__version__}", 71 api: str = "https://www.openstreetmap.org", 72 session: Optional[requests.Session] = None, 73 timeout: int = 30, 74 ) -> None: 75 """ 76 Initialized the OsmApi object. 77 78 There are two different ways to authenticate a user. 79 Either `username` and `password` are supplied directly or the path 80 to a `passwordfile` is given, where on the first line username 81 and password must be colon-separated (<user>:<pass>). 82 83 To credit the application that supplies changes to OSM, an `appid` 84 can be provided. This is a string identifying the application. 85 If this is omitted "osmapi" is used. 86 87 It is possible to configure the URL to connect to using the `api` 88 parameter. By default this is the SSL version of the production API 89 of OpenStreetMap, for testing purposes, one might prefer the official 90 test instance at "api06.dev.openstreetmap.org" or any other valid 91 OSM-API. To use an encrypted connection (HTTPS) simply add 'https://' 92 in front of the hostname of the `api` parameter (e.g. 93 https://api.openstreetmap.com). 94 95 The `session` parameter can be used to provide a custom requests 96 http session object (requests.Session). This might be useful for 97 OAuth authentication, custom adapters, hooks etc. 98 99 Finally the `timeout` parameter is used by the http session to 100 throw an expcetion if the the timeout (in seconds) has passed without 101 an answer from the server. 102 """ 103 # Get username 104 self._username: Optional[str] = None 105 if username: 106 self._username = username 107 elif passwordfile: 108 with open(passwordfile) as f: 109 pass_line = f.readline() 110 self._username = pass_line.partition(":")[0].strip() 111 112 # Get password 113 self._password: Optional[str] = None 114 if password: 115 self._password = password 116 elif passwordfile: 117 with open(passwordfile) as f: 118 for line in f: 119 key, _, value = line.strip().partition(":") 120 if key == self._username: 121 self._password = value 122 123 # Get API 124 self._api: str = api.strip("/") 125 126 # Get created_by 127 if not appid: 128 self._created_by: str = created_by 129 else: 130 self._created_by = f"{appid} ({created_by})" 131 132 # Initialisation 133 self._current_changeset_id: int = 0 134 135 # Http connection 136 self.http_session: Optional[requests.Session] = session 137 self._timeout: int = timeout 138 auth: Optional[tuple[str, str]] = None 139 if self._username and self._password: 140 auth = (self._username, self._password) 141 self._session: http.OsmApiSession = http.OsmApiSession( 142 self._api, 143 self._created_by, 144 auth=auth, 145 session=self.http_session, 146 timeout=self._timeout, 147 ) 148 149 def __enter__(self) -> "OsmApi": 150 self._session = http.OsmApiSession( 151 self._api, 152 self._created_by, 153 session=self.http_session, 154 timeout=self._timeout, 155 ) 156 return self 157 158 def __exit__(self, *args: Any) -> None: 159 self.close() 160 161 def close(self) -> None: 162 if self._session: 163 self._session.close() 164 165 ################################################## 166 # Capabilities # 167 ################################################## 168 169 def Capabilities(self) -> dict[str, dict[str, Any]]: 170 """ 171 Returns the API capabilities as a dict. 172 173 .. deprecated:: 174 Use :meth:`capabilities` instead. 175 176 The capabilities can be used by a client to 177 gain insights of the server in use. 178 """ 179 warnings.warn( 180 "Capabilities() is deprecated, use capabilities() instead", 181 DeprecationWarning, 182 stacklevel=2, 183 ) 184 return self.capabilities() 185 186 ################################################## 187 # Node - Deprecated CamelCase methods # 188 ################################################## 189 190 def NodeGet(self, NodeId: int, NodeVersion: int = -1) -> dict[str, Any]: 191 """.. deprecated:: Use :meth:`node_get` instead.""" 192 warnings.warn( 193 "NodeGet() is deprecated, use node_get() instead", 194 DeprecationWarning, 195 stacklevel=2, 196 ) 197 return self.node_get(NodeId, NodeVersion) 198 199 def NodeCreate(self, NodeData: dict[str, Any]) -> Optional[dict[str, Any]]: 200 """.. deprecated:: Use :meth:`node_create` instead.""" 201 warnings.warn( 202 "NodeCreate() is deprecated, use node_create() instead", 203 DeprecationWarning, 204 stacklevel=2, 205 ) 206 return self.node_create(NodeData) 207 208 def NodeUpdate(self, NodeData: dict[str, Any]) -> Optional[dict[str, Any]]: 209 """.. deprecated:: Use :meth:`node_update` instead.""" 210 warnings.warn( 211 "NodeUpdate() is deprecated, use node_update() instead", 212 DeprecationWarning, 213 stacklevel=2, 214 ) 215 return self.node_update(NodeData) 216 217 def NodeDelete(self, NodeData: dict[str, Any]) -> Optional[dict[str, Any]]: 218 """.. deprecated:: Use :meth:`node_delete` instead.""" 219 warnings.warn( 220 "NodeDelete() is deprecated, use node_delete() instead", 221 DeprecationWarning, 222 stacklevel=2, 223 ) 224 return self.node_delete(NodeData) 225 226 def NodeHistory(self, NodeId: int) -> dict[int, dict[str, Any]]: 227 """.. deprecated:: Use :meth:`node_history` instead.""" 228 warnings.warn( 229 "NodeHistory() is deprecated, use node_history() instead", 230 DeprecationWarning, 231 stacklevel=2, 232 ) 233 return self.node_history(NodeId) 234 235 def NodeWays(self, NodeId: int) -> list[dict[str, Any]]: 236 """.. deprecated:: Use :meth:`node_ways` instead.""" 237 warnings.warn( 238 "NodeWays() is deprecated, use node_ways() instead", 239 DeprecationWarning, 240 stacklevel=2, 241 ) 242 return self.node_ways(NodeId) 243 244 def NodeRelations(self, NodeId: int) -> list[dict[str, Any]]: 245 """.. deprecated:: Use :meth:`node_relations` instead.""" 246 warnings.warn( 247 "NodeRelations() is deprecated, use node_relations() instead", 248 DeprecationWarning, 249 stacklevel=2, 250 ) 251 return self.node_relations(NodeId) 252 253 def NodesGet(self, NodeIdList: list[int]) -> dict[int, dict[str, Any]]: 254 """.. deprecated:: Use :meth:`nodes_get` instead.""" 255 warnings.warn( 256 "NodesGet() is deprecated, use nodes_get() instead", 257 DeprecationWarning, 258 stacklevel=2, 259 ) 260 return self.nodes_get(NodeIdList) 261 262 ################################################## 263 # Way - Deprecated CamelCase methods # 264 ################################################## 265 266 def WayGet(self, WayId: int, WayVersion: int = -1) -> dict[str, Any]: 267 """.. deprecated:: Use :meth:`way_get` instead.""" 268 warnings.warn( 269 "WayGet() is deprecated, use way_get() instead", 270 DeprecationWarning, 271 stacklevel=2, 272 ) 273 return self.way_get(WayId, WayVersion) 274 275 def WayCreate(self, WayData: dict[str, Any]) -> Optional[dict[str, Any]]: 276 """.. deprecated:: Use :meth:`way_create` instead.""" 277 warnings.warn( 278 "WayCreate() is deprecated, use way_create() instead", 279 DeprecationWarning, 280 stacklevel=2, 281 ) 282 return self.way_create(WayData) 283 284 def WayUpdate(self, WayData: dict[str, Any]) -> Optional[dict[str, Any]]: 285 """.. deprecated:: Use :meth:`way_update` instead.""" 286 warnings.warn( 287 "WayUpdate() is deprecated, use way_update() instead", 288 DeprecationWarning, 289 stacklevel=2, 290 ) 291 return self.way_update(WayData) 292 293 def WayDelete(self, WayData: dict[str, Any]) -> Optional[dict[str, Any]]: 294 """.. deprecated:: Use :meth:`way_delete` instead.""" 295 warnings.warn( 296 "WayDelete() is deprecated, use way_delete() instead", 297 DeprecationWarning, 298 stacklevel=2, 299 ) 300 return self.way_delete(WayData) 301 302 def WayHistory(self, WayId: int) -> dict[int, dict[str, Any]]: 303 """.. deprecated:: Use :meth:`way_history` instead.""" 304 warnings.warn( 305 "WayHistory() is deprecated, use way_history() instead", 306 DeprecationWarning, 307 stacklevel=2, 308 ) 309 return self.way_history(WayId) 310 311 def WayRelations(self, WayId: int) -> list[dict[str, Any]]: 312 """.. deprecated:: Use :meth:`way_relations` instead.""" 313 warnings.warn( 314 "WayRelations() is deprecated, use way_relations() instead", 315 DeprecationWarning, 316 stacklevel=2, 317 ) 318 return self.way_relations(WayId) 319 320 def WayFull(self, WayId: int) -> list[dict[str, Any]]: 321 """.. deprecated:: Use :meth:`way_full` instead.""" 322 warnings.warn( 323 "WayFull() is deprecated, use way_full() instead", 324 DeprecationWarning, 325 stacklevel=2, 326 ) 327 return self.way_full(WayId) 328 329 def WaysGet(self, WayIdList: list[int]) -> dict[int, dict[str, Any]]: 330 """.. deprecated:: Use :meth:`ways_get` instead.""" 331 warnings.warn( 332 "WaysGet() is deprecated, use ways_get() instead", 333 DeprecationWarning, 334 stacklevel=2, 335 ) 336 return self.ways_get(WayIdList) 337 338 ################################################## 339 # Relation - Deprecated CamelCase methods # 340 ################################################## 341 342 def RelationGet(self, RelationId: int, RelationVersion: int = -1) -> dict[str, Any]: 343 """.. deprecated:: Use :meth:`relation_get` instead.""" 344 warnings.warn( 345 "RelationGet() is deprecated, use relation_get() instead", 346 DeprecationWarning, 347 stacklevel=2, 348 ) 349 return self.relation_get(RelationId, RelationVersion) 350 351 def RelationCreate(self, RelationData: dict[str, Any]) -> Optional[dict[str, Any]]: 352 """.. deprecated:: Use :meth:`relation_create` instead.""" 353 warnings.warn( 354 "RelationCreate() is deprecated, use relation_create() instead", 355 DeprecationWarning, 356 stacklevel=2, 357 ) 358 return self.relation_create(RelationData) 359 360 def RelationUpdate(self, RelationData: dict[str, Any]) -> Optional[dict[str, Any]]: 361 """.. deprecated:: Use :meth:`relation_update` instead.""" 362 warnings.warn( 363 "RelationUpdate() is deprecated, use relation_update() instead", 364 DeprecationWarning, 365 stacklevel=2, 366 ) 367 return self.relation_update(RelationData) 368 369 def RelationDelete(self, RelationData: dict[str, Any]) -> Optional[dict[str, Any]]: 370 """.. deprecated:: Use :meth:`relation_delete` instead.""" 371 warnings.warn( 372 "RelationDelete() is deprecated, use relation_delete() instead", 373 DeprecationWarning, 374 stacklevel=2, 375 ) 376 return self.relation_delete(RelationData) 377 378 def RelationHistory(self, RelationId: int) -> dict[int, dict[str, Any]]: 379 """.. deprecated:: Use :meth:`relation_history` instead.""" 380 warnings.warn( 381 "RelationHistory() is deprecated, use relation_history() instead", 382 DeprecationWarning, 383 stacklevel=2, 384 ) 385 return self.relation_history(RelationId) 386 387 def RelationRelations(self, RelationId: int) -> list[dict[str, Any]]: 388 """.. deprecated:: Use :meth:`relation_relations` instead.""" 389 warnings.warn( 390 "RelationRelations() is deprecated, use relation_relations() instead", 391 DeprecationWarning, 392 stacklevel=2, 393 ) 394 return self.relation_relations(RelationId) 395 396 def RelationFullRecur(self, RelationId: int) -> list[dict[str, Any]]: 397 """.. deprecated:: Use :meth:`relation_full_recur` instead.""" 398 warnings.warn( 399 "RelationFullRecur() is deprecated, use relation_full_recur() instead", 400 DeprecationWarning, 401 stacklevel=2, 402 ) 403 return self.relation_full_recur(RelationId) 404 405 def RelationFull(self, RelationId: int) -> list[dict[str, Any]]: 406 """.. deprecated:: Use :meth:`relation_full` instead.""" 407 warnings.warn( 408 "RelationFull() is deprecated, use relation_full() instead", 409 DeprecationWarning, 410 stacklevel=2, 411 ) 412 return self.relation_full(RelationId) 413 414 def RelationsGet(self, RelationIdList: list[int]) -> dict[int, dict[str, Any]]: 415 """.. deprecated:: Use :meth:`relations_get` instead.""" 416 warnings.warn( 417 "RelationsGet() is deprecated, use relations_get() instead", 418 DeprecationWarning, 419 stacklevel=2, 420 ) 421 return self.relations_get(RelationIdList) 422 423 ################################################## 424 # Changeset - Deprecated CamelCase methods # 425 ################################################## 426 427 @contextmanager 428 def Changeset( 429 self, ChangesetTags: Optional[dict[str, str]] = None 430 ) -> Generator[int, None, None]: 431 """.. deprecated:: Use :meth:`changeset` instead.""" 432 warnings.warn( 433 "Changeset() is deprecated, use changeset() instead", 434 DeprecationWarning, 435 stacklevel=2, 436 ) 437 with self.changeset(ChangesetTags) as changeset_id: 438 yield changeset_id 439 440 def ChangesetGet( 441 self, ChangesetId: int, include_discussion: bool = False 442 ) -> dict[str, Any]: 443 """.. deprecated:: Use :meth:`changeset_get` instead.""" 444 warnings.warn( 445 "ChangesetGet() is deprecated, use changeset_get() instead", 446 DeprecationWarning, 447 stacklevel=2, 448 ) 449 return self.changeset_get(ChangesetId, include_discussion) 450 451 def ChangesetUpdate(self, ChangesetTags: Optional[dict[str, str]] = None) -> int: 452 """.. deprecated:: Use :meth:`changeset_update` instead.""" 453 warnings.warn( 454 "ChangesetUpdate() is deprecated, use changeset_update() instead", 455 DeprecationWarning, 456 stacklevel=2, 457 ) 458 return self.changeset_update(ChangesetTags) 459 460 def ChangesetCreate(self, ChangesetTags: Optional[dict[str, str]] = None) -> int: 461 """.. deprecated:: Use :meth:`changeset_create` instead.""" 462 warnings.warn( 463 "ChangesetCreate() is deprecated, use changeset_create() instead", 464 DeprecationWarning, 465 stacklevel=2, 466 ) 467 return self.changeset_create(ChangesetTags) 468 469 def ChangesetClose(self) -> int: 470 """.. deprecated:: Use :meth:`changeset_close` instead.""" 471 warnings.warn( 472 "ChangesetClose() is deprecated, use changeset_close() instead", 473 DeprecationWarning, 474 stacklevel=2, 475 ) 476 return self.changeset_close() 477 478 def ChangesetUpload( 479 self, ChangesData: list[dict[str, Any]] 480 ) -> list[dict[str, Any]]: 481 """.. deprecated:: Use :meth:`changeset_upload` instead.""" 482 warnings.warn( 483 "ChangesetUpload() is deprecated, use changeset_upload() instead", 484 DeprecationWarning, 485 stacklevel=2, 486 ) 487 return self.changeset_upload(ChangesData) 488 489 def ChangesetDownload(self, ChangesetId: int) -> list[dict[str, Any]]: 490 """.. deprecated:: Use :meth:`changeset_download` instead.""" 491 warnings.warn( 492 "ChangesetDownload() is deprecated, use changeset_download() instead", 493 DeprecationWarning, 494 stacklevel=2, 495 ) 496 return self.changeset_download(ChangesetId) 497 498 def ChangesetsGet( # noqa 499 self, 500 min_lon: Optional[float] = None, 501 min_lat: Optional[float] = None, 502 max_lon: Optional[float] = None, 503 max_lat: Optional[float] = None, 504 userid: Optional[int] = None, 505 username: Optional[str] = None, 506 closed_after: Optional[str] = None, 507 created_before: Optional[str] = None, 508 only_open: bool = False, 509 only_closed: bool = False, 510 ) -> dict[int, dict[str, Any]]: 511 """.. deprecated:: Use :meth:`changesets_get` instead.""" 512 warnings.warn( 513 "ChangesetsGet() is deprecated, use changesets_get() instead", 514 DeprecationWarning, 515 stacklevel=2, 516 ) 517 return self.changesets_get( 518 min_lon, 519 min_lat, 520 max_lon, 521 max_lat, 522 userid, 523 username, 524 closed_after, 525 created_before, 526 only_open, 527 only_closed, 528 ) 529 530 def ChangesetComment(self, ChangesetId: int, comment: str) -> dict[str, Any]: 531 """.. deprecated:: Use :meth:`changeset_comment` instead.""" 532 warnings.warn( 533 "ChangesetComment() is deprecated, use changeset_comment() instead", 534 DeprecationWarning, 535 stacklevel=2, 536 ) 537 return self.changeset_comment(ChangesetId, comment) 538 539 def ChangesetSubscribe(self, ChangesetId: int) -> dict[str, Any]: 540 """.. deprecated:: Use :meth:`changeset_subscribe` instead.""" 541 warnings.warn( 542 "ChangesetSubscribe() is deprecated, use changeset_subscribe() instead", 543 DeprecationWarning, 544 stacklevel=2, 545 ) 546 return self.changeset_subscribe(ChangesetId) 547 548 def ChangesetUnsubscribe(self, ChangesetId: int) -> dict[str, Any]: 549 """.. deprecated:: Use :meth:`changeset_unsubscribe` instead.""" 550 warnings.warn( 551 "ChangesetUnsubscribe() is deprecated, use changeset_unsubscribe() instead", 552 DeprecationWarning, 553 stacklevel=2, 554 ) 555 return self.changeset_unsubscribe(ChangesetId) 556 557 ################################################## 558 # Note - Deprecated CamelCase methods # 559 ################################################## 560 561 def NotesGet( 562 self, 563 min_lon: float, 564 min_lat: float, 565 max_lon: float, 566 max_lat: float, 567 limit: int = 100, 568 closed: int = 7, 569 ) -> list[dict[str, Any]]: 570 """.. deprecated:: Use :meth:`notes_get` instead.""" 571 warnings.warn( 572 "NotesGet() is deprecated, use notes_get() instead", 573 DeprecationWarning, 574 stacklevel=2, 575 ) 576 return self.notes_get(min_lon, min_lat, max_lon, max_lat, limit, closed) 577 578 def NoteGet(self, id: int) -> dict[str, Any]: 579 """.. deprecated:: Use :meth:`note_get` instead.""" 580 warnings.warn( 581 "NoteGet() is deprecated, use note_get() instead", 582 DeprecationWarning, 583 stacklevel=2, 584 ) 585 return self.note_get(id) 586 587 def NoteCreate(self, NoteData: dict[str, Any]) -> dict[str, Any]: 588 """.. deprecated:: Use :meth:`note_create` instead.""" 589 warnings.warn( 590 "NoteCreate() is deprecated, use note_create() instead", 591 DeprecationWarning, 592 stacklevel=2, 593 ) 594 return self.note_create(NoteData) 595 596 def NoteComment(self, note_id: int, comment: str) -> dict[str, Any]: 597 """.. deprecated:: Use :meth:`note_comment` instead.""" 598 warnings.warn( 599 "NoteComment() is deprecated, use note_comment() instead", 600 DeprecationWarning, 601 stacklevel=2, 602 ) 603 return self.note_comment(note_id, comment) 604 605 def NoteClose(self, note_id: int, comment: Optional[str] = None) -> dict[str, Any]: 606 """.. deprecated:: Use :meth:`note_close` instead.""" 607 warnings.warn( 608 "NoteClose() is deprecated, use note_close() instead", 609 DeprecationWarning, 610 stacklevel=2, 611 ) 612 return self.note_close(note_id, comment) 613 614 def NoteReopen(self, note_id: int, comment: Optional[str] = None) -> dict[str, Any]: 615 """.. deprecated:: Use :meth:`note_reopen` instead.""" 616 warnings.warn( 617 "NoteReopen() is deprecated, use note_reopen() instead", 618 DeprecationWarning, 619 stacklevel=2, 620 ) 621 return self.note_reopen(note_id, comment) 622 623 def NotesSearch( 624 self, query: str, limit: int = 100, closed: int = 7 625 ) -> list[dict[str, Any]]: 626 """.. deprecated:: Use :meth:`notes_search` instead.""" 627 warnings.warn( 628 "NotesSearch() is deprecated, use notes_search() instead", 629 DeprecationWarning, 630 stacklevel=2, 631 ) 632 return self.notes_search(query, limit, closed) 633 634 def _NoteAction( 635 self, path: str, comment: Optional[str] = None, optionalAuth: bool = True 636 ) -> dict[str, Any]: 637 """Internal method - calls _note_action.""" 638 return self._note_action(path, comment, optionalAuth) 639 640 ################################################## 641 # Map - Deprecated CamelCase methods # 642 ################################################## 643 644 def Map( 645 self, min_lon: float, min_lat: float, max_lon: float, max_lat: float 646 ) -> list[dict[str, Any]]: 647 """.. deprecated:: Use :meth:`map` instead.""" 648 warnings.warn( 649 "Map() is deprecated, use map() instead", 650 DeprecationWarning, 651 stacklevel=2, 652 ) 653 return self.map(min_lon, min_lat, max_lon, max_lat) 654 655 ################################################## 656 # Internal method # 657 ################################################## 658 659 def _do( # type: ignore[return-value] # noqa: C901 660 self, action: str, osm_type: str, osm_data: dict[str, Any] 661 ) -> dict[str, Any]: 662 if not self._current_changeset_id: 663 raise errors.NoChangesetOpenError( 664 "You need to open a changeset before uploading data" 665 ) 666 if "timestamp" in osm_data: 667 osm_data.pop("timestamp") 668 osm_data["changeset"] = self._current_changeset_id 669 if action == "create": 670 if osm_data.get("id", -1) > 0: 671 raise errors.OsmTypeAlreadyExistsError( 672 f"This {osm_type} already exists" 673 ) 674 try: 675 result = self._session._put( 676 f"/api/0.6/{osm_type}/create", 677 xmlbuilder._xml_build(osm_type, osm_data, data=self), 678 ) 679 except errors.ApiError as e: 680 if e.status == 409 and re.search( 681 r"The changeset .* was closed at .*", e.payload 682 ): 683 raise errors.ChangesetClosedApiError( 684 e.status, e.reason, e.payload 685 ) from e 686 elif e.status == 409: 687 raise errors.VersionMismatchApiError( 688 e.status, e.reason, e.payload 689 ) from e 690 elif e.status == 412: 691 raise errors.PreconditionFailedApiError( 692 e.status, e.reason, e.payload 693 ) from e 694 else: 695 raise 696 osm_data["id"] = int(result.strip()) 697 osm_data["version"] = 1 698 return osm_data 699 elif action == "modify": 700 try: 701 result = self._session._put( 702 f"/api/0.6/{osm_type}/{osm_data['id']}", 703 xmlbuilder._xml_build(osm_type, osm_data, data=self), 704 ) 705 except errors.ApiError as e: 706 logger.error(e.reason) 707 if e.status == 409 and re.search( 708 r"The changeset .* was closed at .*", e.payload 709 ): 710 raise errors.ChangesetClosedApiError( 711 e.status, e.reason, e.payload 712 ) from e 713 elif e.status == 409: 714 raise errors.VersionMismatchApiError( 715 e.status, e.reason, e.payload 716 ) from e 717 elif e.status == 412: 718 raise errors.PreconditionFailedApiError( 719 e.status, e.reason, e.payload 720 ) from e 721 else: 722 raise 723 osm_data["version"] = int(result.strip()) 724 return osm_data 725 elif action == "delete": 726 try: 727 result = self._session._delete( 728 f"/api/0.6/{osm_type}/{osm_data['id']}", 729 xmlbuilder._xml_build(osm_type, osm_data, data=self), 730 ) 731 except errors.ApiError as e: 732 if e.status == 409 and re.search( 733 r"The changeset .* was closed at .*", e.payload 734 ): 735 raise errors.ChangesetClosedApiError( 736 e.status, e.reason, e.payload 737 ) from e 738 elif e.status == 409: 739 raise errors.VersionMismatchApiError( 740 e.status, e.reason, e.payload 741 ) from e 742 elif e.status == 412: 743 raise errors.PreconditionFailedApiError( 744 e.status, e.reason, e.payload 745 ) from e 746 else: 747 raise 748 osm_data["version"] = int(result.strip()) 749 osm_data["visible"] = False 750 return osm_data 751 752 def _add_changeset_data(self, change_data: list[dict[str, Any]], type: str) -> str: 753 data = "" 754 for changed_element in change_data: 755 changed_element["changeset"] = self._current_changeset_id 756 xml_data = xmlbuilder._xml_build(type, changed_element, False, data=self) 757 data += xml_data.decode("utf-8") 758 return data 759 760 def _assign_id_and_version( 761 self, response_data: list[Element], request_data: list[dict[str, Any]] 762 ) -> None: 763 for response, element in zip(response_data, request_data): 764 element["id"] = int(response.getAttribute("new_id")) 765 element["version"] = int(response.getAttribute("new_version"))
Main class of osmapi, instanciate this class to use osmapi
64 def __init__( 65 self, 66 username: Optional[str] = None, 67 password: Optional[str] = None, 68 passwordfile: Optional[str] = None, 69 appid: str = "", 70 created_by: str = f"osmapi/{__version__}", 71 api: str = "https://www.openstreetmap.org", 72 session: Optional[requests.Session] = None, 73 timeout: int = 30, 74 ) -> None: 75 """ 76 Initialized the OsmApi object. 77 78 There are two different ways to authenticate a user. 79 Either `username` and `password` are supplied directly or the path 80 to a `passwordfile` is given, where on the first line username 81 and password must be colon-separated (<user>:<pass>). 82 83 To credit the application that supplies changes to OSM, an `appid` 84 can be provided. This is a string identifying the application. 85 If this is omitted "osmapi" is used. 86 87 It is possible to configure the URL to connect to using the `api` 88 parameter. By default this is the SSL version of the production API 89 of OpenStreetMap, for testing purposes, one might prefer the official 90 test instance at "api06.dev.openstreetmap.org" or any other valid 91 OSM-API. To use an encrypted connection (HTTPS) simply add 'https://' 92 in front of the hostname of the `api` parameter (e.g. 93 https://api.openstreetmap.com). 94 95 The `session` parameter can be used to provide a custom requests 96 http session object (requests.Session). This might be useful for 97 OAuth authentication, custom adapters, hooks etc. 98 99 Finally the `timeout` parameter is used by the http session to 100 throw an expcetion if the the timeout (in seconds) has passed without 101 an answer from the server. 102 """ 103 # Get username 104 self._username: Optional[str] = None 105 if username: 106 self._username = username 107 elif passwordfile: 108 with open(passwordfile) as f: 109 pass_line = f.readline() 110 self._username = pass_line.partition(":")[0].strip() 111 112 # Get password 113 self._password: Optional[str] = None 114 if password: 115 self._password = password 116 elif passwordfile: 117 with open(passwordfile) as f: 118 for line in f: 119 key, _, value = line.strip().partition(":") 120 if key == self._username: 121 self._password = value 122 123 # Get API 124 self._api: str = api.strip("/") 125 126 # Get created_by 127 if not appid: 128 self._created_by: str = created_by 129 else: 130 self._created_by = f"{appid} ({created_by})" 131 132 # Initialisation 133 self._current_changeset_id: int = 0 134 135 # Http connection 136 self.http_session: Optional[requests.Session] = session 137 self._timeout: int = timeout 138 auth: Optional[tuple[str, str]] = None 139 if self._username and self._password: 140 auth = (self._username, self._password) 141 self._session: http.OsmApiSession = http.OsmApiSession( 142 self._api, 143 self._created_by, 144 auth=auth, 145 session=self.http_session, 146 timeout=self._timeout, 147 )
Initialized the OsmApi object.
There are two different ways to authenticate a user.
Either username and password are supplied directly or the path
to a passwordfile is given, where on the first line username
and password must be colon-separated (
To credit the application that supplies changes to OSM, an appid
can be provided. This is a string identifying the application.
If this is omitted "osmapi" is used.
It is possible to configure the URL to connect to using the api
parameter. By default this is the SSL version of the production API
of OpenStreetMap, for testing purposes, one might prefer the official
test instance at "api06.dev.openstreetmap.org" or any other valid
OSM-API. To use an encrypted connection (HTTPS) simply add 'https://'
in front of the hostname of the api parameter (e.g.
https://api.openstreetmap.com).
The session parameter can be used to provide a custom requests
http session object (requests.Session). This might be useful for
OAuth authentication, custom adapters, hooks etc.
Finally the timeout parameter is used by the http session to
throw an expcetion if the the timeout (in seconds) has passed without
an answer from the server.
169 def Capabilities(self) -> dict[str, dict[str, Any]]: 170 """ 171 Returns the API capabilities as a dict. 172 173 .. deprecated:: 174 Use :meth:`capabilities` instead. 175 176 The capabilities can be used by a client to 177 gain insights of the server in use. 178 """ 179 warnings.warn( 180 "Capabilities() is deprecated, use capabilities() instead", 181 DeprecationWarning, 182 stacklevel=2, 183 ) 184 return self.capabilities()
Returns the API capabilities as a dict.
Deprecated since version :
Use capabilities() instead.
The capabilities can be used by a client to gain insights of the server in use.
190 def NodeGet(self, NodeId: int, NodeVersion: int = -1) -> dict[str, Any]: 191 """.. deprecated:: Use :meth:`node_get` instead.""" 192 warnings.warn( 193 "NodeGet() is deprecated, use node_get() instead", 194 DeprecationWarning, 195 stacklevel=2, 196 ) 197 return self.node_get(NodeId, NodeVersion)
Deprecated since version Use node_get() instead..
199 def NodeCreate(self, NodeData: dict[str, Any]) -> Optional[dict[str, Any]]: 200 """.. deprecated:: Use :meth:`node_create` instead.""" 201 warnings.warn( 202 "NodeCreate() is deprecated, use node_create() instead", 203 DeprecationWarning, 204 stacklevel=2, 205 ) 206 return self.node_create(NodeData)
Deprecated since version Use node_create() instead..
208 def NodeUpdate(self, NodeData: dict[str, Any]) -> Optional[dict[str, Any]]: 209 """.. deprecated:: Use :meth:`node_update` instead.""" 210 warnings.warn( 211 "NodeUpdate() is deprecated, use node_update() instead", 212 DeprecationWarning, 213 stacklevel=2, 214 ) 215 return self.node_update(NodeData)
Deprecated since version Use node_update() instead..
217 def NodeDelete(self, NodeData: dict[str, Any]) -> Optional[dict[str, Any]]: 218 """.. deprecated:: Use :meth:`node_delete` instead.""" 219 warnings.warn( 220 "NodeDelete() is deprecated, use node_delete() instead", 221 DeprecationWarning, 222 stacklevel=2, 223 ) 224 return self.node_delete(NodeData)
Deprecated since version Use node_delete() instead..
226 def NodeHistory(self, NodeId: int) -> dict[int, dict[str, Any]]: 227 """.. deprecated:: Use :meth:`node_history` instead.""" 228 warnings.warn( 229 "NodeHistory() is deprecated, use node_history() instead", 230 DeprecationWarning, 231 stacklevel=2, 232 ) 233 return self.node_history(NodeId)
Deprecated since version Use node_history() instead..
235 def NodeWays(self, NodeId: int) -> list[dict[str, Any]]: 236 """.. deprecated:: Use :meth:`node_ways` instead.""" 237 warnings.warn( 238 "NodeWays() is deprecated, use node_ways() instead", 239 DeprecationWarning, 240 stacklevel=2, 241 ) 242 return self.node_ways(NodeId)
Deprecated since version Use node_ways() instead..
244 def NodeRelations(self, NodeId: int) -> list[dict[str, Any]]: 245 """.. deprecated:: Use :meth:`node_relations` instead.""" 246 warnings.warn( 247 "NodeRelations() is deprecated, use node_relations() instead", 248 DeprecationWarning, 249 stacklevel=2, 250 ) 251 return self.node_relations(NodeId)
Deprecated since version Use node_relations() instead..
253 def NodesGet(self, NodeIdList: list[int]) -> dict[int, dict[str, Any]]: 254 """.. deprecated:: Use :meth:`nodes_get` instead.""" 255 warnings.warn( 256 "NodesGet() is deprecated, use nodes_get() instead", 257 DeprecationWarning, 258 stacklevel=2, 259 ) 260 return self.nodes_get(NodeIdList)
Deprecated since version Use nodes_get() instead..
266 def WayGet(self, WayId: int, WayVersion: int = -1) -> dict[str, Any]: 267 """.. deprecated:: Use :meth:`way_get` instead.""" 268 warnings.warn( 269 "WayGet() is deprecated, use way_get() instead", 270 DeprecationWarning, 271 stacklevel=2, 272 ) 273 return self.way_get(WayId, WayVersion)
Deprecated since version Use way_get() instead..
275 def WayCreate(self, WayData: dict[str, Any]) -> Optional[dict[str, Any]]: 276 """.. deprecated:: Use :meth:`way_create` instead.""" 277 warnings.warn( 278 "WayCreate() is deprecated, use way_create() instead", 279 DeprecationWarning, 280 stacklevel=2, 281 ) 282 return self.way_create(WayData)
Deprecated since version Use way_create() instead..
284 def WayUpdate(self, WayData: dict[str, Any]) -> Optional[dict[str, Any]]: 285 """.. deprecated:: Use :meth:`way_update` instead.""" 286 warnings.warn( 287 "WayUpdate() is deprecated, use way_update() instead", 288 DeprecationWarning, 289 stacklevel=2, 290 ) 291 return self.way_update(WayData)
Deprecated since version Use way_update() instead..
293 def WayDelete(self, WayData: dict[str, Any]) -> Optional[dict[str, Any]]: 294 """.. deprecated:: Use :meth:`way_delete` instead.""" 295 warnings.warn( 296 "WayDelete() is deprecated, use way_delete() instead", 297 DeprecationWarning, 298 stacklevel=2, 299 ) 300 return self.way_delete(WayData)
Deprecated since version Use way_delete() instead..
302 def WayHistory(self, WayId: int) -> dict[int, dict[str, Any]]: 303 """.. deprecated:: Use :meth:`way_history` instead.""" 304 warnings.warn( 305 "WayHistory() is deprecated, use way_history() instead", 306 DeprecationWarning, 307 stacklevel=2, 308 ) 309 return self.way_history(WayId)
Deprecated since version Use way_history() instead..
311 def WayRelations(self, WayId: int) -> list[dict[str, Any]]: 312 """.. deprecated:: Use :meth:`way_relations` instead.""" 313 warnings.warn( 314 "WayRelations() is deprecated, use way_relations() instead", 315 DeprecationWarning, 316 stacklevel=2, 317 ) 318 return self.way_relations(WayId)
Deprecated since version Use way_relations() instead..
320 def WayFull(self, WayId: int) -> list[dict[str, Any]]: 321 """.. deprecated:: Use :meth:`way_full` instead.""" 322 warnings.warn( 323 "WayFull() is deprecated, use way_full() instead", 324 DeprecationWarning, 325 stacklevel=2, 326 ) 327 return self.way_full(WayId)
Deprecated since version Use way_full() instead..
329 def WaysGet(self, WayIdList: list[int]) -> dict[int, dict[str, Any]]: 330 """.. deprecated:: Use :meth:`ways_get` instead.""" 331 warnings.warn( 332 "WaysGet() is deprecated, use ways_get() instead", 333 DeprecationWarning, 334 stacklevel=2, 335 ) 336 return self.ways_get(WayIdList)
Deprecated since version Use ways_get() instead..
342 def RelationGet(self, RelationId: int, RelationVersion: int = -1) -> dict[str, Any]: 343 """.. deprecated:: Use :meth:`relation_get` instead.""" 344 warnings.warn( 345 "RelationGet() is deprecated, use relation_get() instead", 346 DeprecationWarning, 347 stacklevel=2, 348 ) 349 return self.relation_get(RelationId, RelationVersion)
Deprecated since version Use relation_get() instead..
351 def RelationCreate(self, RelationData: dict[str, Any]) -> Optional[dict[str, Any]]: 352 """.. deprecated:: Use :meth:`relation_create` instead.""" 353 warnings.warn( 354 "RelationCreate() is deprecated, use relation_create() instead", 355 DeprecationWarning, 356 stacklevel=2, 357 ) 358 return self.relation_create(RelationData)
Deprecated since version Use relation_create() instead..
360 def RelationUpdate(self, RelationData: dict[str, Any]) -> Optional[dict[str, Any]]: 361 """.. deprecated:: Use :meth:`relation_update` instead.""" 362 warnings.warn( 363 "RelationUpdate() is deprecated, use relation_update() instead", 364 DeprecationWarning, 365 stacklevel=2, 366 ) 367 return self.relation_update(RelationData)
Deprecated since version Use relation_update() instead..
369 def RelationDelete(self, RelationData: dict[str, Any]) -> Optional[dict[str, Any]]: 370 """.. deprecated:: Use :meth:`relation_delete` instead.""" 371 warnings.warn( 372 "RelationDelete() is deprecated, use relation_delete() instead", 373 DeprecationWarning, 374 stacklevel=2, 375 ) 376 return self.relation_delete(RelationData)
Deprecated since version Use relation_delete() instead..
378 def RelationHistory(self, RelationId: int) -> dict[int, dict[str, Any]]: 379 """.. deprecated:: Use :meth:`relation_history` instead.""" 380 warnings.warn( 381 "RelationHistory() is deprecated, use relation_history() instead", 382 DeprecationWarning, 383 stacklevel=2, 384 ) 385 return self.relation_history(RelationId)
Deprecated since version Use relation_history() instead..
387 def RelationRelations(self, RelationId: int) -> list[dict[str, Any]]: 388 """.. deprecated:: Use :meth:`relation_relations` instead.""" 389 warnings.warn( 390 "RelationRelations() is deprecated, use relation_relations() instead", 391 DeprecationWarning, 392 stacklevel=2, 393 ) 394 return self.relation_relations(RelationId)
Deprecated since version Use relation_relations() instead..
396 def RelationFullRecur(self, RelationId: int) -> list[dict[str, Any]]: 397 """.. deprecated:: Use :meth:`relation_full_recur` instead.""" 398 warnings.warn( 399 "RelationFullRecur() is deprecated, use relation_full_recur() instead", 400 DeprecationWarning, 401 stacklevel=2, 402 ) 403 return self.relation_full_recur(RelationId)
Deprecated since version Use relation_full_recur() instead..
405 def RelationFull(self, RelationId: int) -> list[dict[str, Any]]: 406 """.. deprecated:: Use :meth:`relation_full` instead.""" 407 warnings.warn( 408 "RelationFull() is deprecated, use relation_full() instead", 409 DeprecationWarning, 410 stacklevel=2, 411 ) 412 return self.relation_full(RelationId)
Deprecated since version Use relation_full() instead..
414 def RelationsGet(self, RelationIdList: list[int]) -> dict[int, dict[str, Any]]: 415 """.. deprecated:: Use :meth:`relations_get` instead.""" 416 warnings.warn( 417 "RelationsGet() is deprecated, use relations_get() instead", 418 DeprecationWarning, 419 stacklevel=2, 420 ) 421 return self.relations_get(RelationIdList)
Deprecated since version Use relations_get() instead..
427 @contextmanager 428 def Changeset( 429 self, ChangesetTags: Optional[dict[str, str]] = None 430 ) -> Generator[int, None, None]: 431 """.. deprecated:: Use :meth:`changeset` instead.""" 432 warnings.warn( 433 "Changeset() is deprecated, use changeset() instead", 434 DeprecationWarning, 435 stacklevel=2, 436 ) 437 with self.changeset(ChangesetTags) as changeset_id: 438 yield changeset_id
Deprecated since version Use changeset() instead..
440 def ChangesetGet( 441 self, ChangesetId: int, include_discussion: bool = False 442 ) -> dict[str, Any]: 443 """.. deprecated:: Use :meth:`changeset_get` instead.""" 444 warnings.warn( 445 "ChangesetGet() is deprecated, use changeset_get() instead", 446 DeprecationWarning, 447 stacklevel=2, 448 ) 449 return self.changeset_get(ChangesetId, include_discussion)
Deprecated since version Use changeset_get() instead..
451 def ChangesetUpdate(self, ChangesetTags: Optional[dict[str, str]] = None) -> int: 452 """.. deprecated:: Use :meth:`changeset_update` instead.""" 453 warnings.warn( 454 "ChangesetUpdate() is deprecated, use changeset_update() instead", 455 DeprecationWarning, 456 stacklevel=2, 457 ) 458 return self.changeset_update(ChangesetTags)
Deprecated since version Use changeset_update() instead..
460 def ChangesetCreate(self, ChangesetTags: Optional[dict[str, str]] = None) -> int: 461 """.. deprecated:: Use :meth:`changeset_create` instead.""" 462 warnings.warn( 463 "ChangesetCreate() is deprecated, use changeset_create() instead", 464 DeprecationWarning, 465 stacklevel=2, 466 ) 467 return self.changeset_create(ChangesetTags)
Deprecated since version Use changeset_create() instead..
469 def ChangesetClose(self) -> int: 470 """.. deprecated:: Use :meth:`changeset_close` instead.""" 471 warnings.warn( 472 "ChangesetClose() is deprecated, use changeset_close() instead", 473 DeprecationWarning, 474 stacklevel=2, 475 ) 476 return self.changeset_close()
Deprecated since version Use changeset_close() instead..
478 def ChangesetUpload( 479 self, ChangesData: list[dict[str, Any]] 480 ) -> list[dict[str, Any]]: 481 """.. deprecated:: Use :meth:`changeset_upload` instead.""" 482 warnings.warn( 483 "ChangesetUpload() is deprecated, use changeset_upload() instead", 484 DeprecationWarning, 485 stacklevel=2, 486 ) 487 return self.changeset_upload(ChangesData)
Deprecated since version Use changeset_upload() instead..
489 def ChangesetDownload(self, ChangesetId: int) -> list[dict[str, Any]]: 490 """.. deprecated:: Use :meth:`changeset_download` instead.""" 491 warnings.warn( 492 "ChangesetDownload() is deprecated, use changeset_download() instead", 493 DeprecationWarning, 494 stacklevel=2, 495 ) 496 return self.changeset_download(ChangesetId)
Deprecated since version Use changeset_download() instead..
498 def ChangesetsGet( # noqa 499 self, 500 min_lon: Optional[float] = None, 501 min_lat: Optional[float] = None, 502 max_lon: Optional[float] = None, 503 max_lat: Optional[float] = None, 504 userid: Optional[int] = None, 505 username: Optional[str] = None, 506 closed_after: Optional[str] = None, 507 created_before: Optional[str] = None, 508 only_open: bool = False, 509 only_closed: bool = False, 510 ) -> dict[int, dict[str, Any]]: 511 """.. deprecated:: Use :meth:`changesets_get` instead.""" 512 warnings.warn( 513 "ChangesetsGet() is deprecated, use changesets_get() instead", 514 DeprecationWarning, 515 stacklevel=2, 516 ) 517 return self.changesets_get( 518 min_lon, 519 min_lat, 520 max_lon, 521 max_lat, 522 userid, 523 username, 524 closed_after, 525 created_before, 526 only_open, 527 only_closed, 528 )
Deprecated since version Use changesets_get() instead..
530 def ChangesetComment(self, ChangesetId: int, comment: str) -> dict[str, Any]: 531 """.. deprecated:: Use :meth:`changeset_comment` instead.""" 532 warnings.warn( 533 "ChangesetComment() is deprecated, use changeset_comment() instead", 534 DeprecationWarning, 535 stacklevel=2, 536 ) 537 return self.changeset_comment(ChangesetId, comment)
Deprecated since version Use changeset_comment() instead..
539 def ChangesetSubscribe(self, ChangesetId: int) -> dict[str, Any]: 540 """.. deprecated:: Use :meth:`changeset_subscribe` instead.""" 541 warnings.warn( 542 "ChangesetSubscribe() is deprecated, use changeset_subscribe() instead", 543 DeprecationWarning, 544 stacklevel=2, 545 ) 546 return self.changeset_subscribe(ChangesetId)
Deprecated since version Use changeset_subscribe() instead..
548 def ChangesetUnsubscribe(self, ChangesetId: int) -> dict[str, Any]: 549 """.. deprecated:: Use :meth:`changeset_unsubscribe` instead.""" 550 warnings.warn( 551 "ChangesetUnsubscribe() is deprecated, use changeset_unsubscribe() instead", 552 DeprecationWarning, 553 stacklevel=2, 554 ) 555 return self.changeset_unsubscribe(ChangesetId)
Deprecated since version Use changeset_unsubscribe() instead..
561 def NotesGet( 562 self, 563 min_lon: float, 564 min_lat: float, 565 max_lon: float, 566 max_lat: float, 567 limit: int = 100, 568 closed: int = 7, 569 ) -> list[dict[str, Any]]: 570 """.. deprecated:: Use :meth:`notes_get` instead.""" 571 warnings.warn( 572 "NotesGet() is deprecated, use notes_get() instead", 573 DeprecationWarning, 574 stacklevel=2, 575 ) 576 return self.notes_get(min_lon, min_lat, max_lon, max_lat, limit, closed)
Deprecated since version Use notes_get() instead..
578 def NoteGet(self, id: int) -> dict[str, Any]: 579 """.. deprecated:: Use :meth:`note_get` instead.""" 580 warnings.warn( 581 "NoteGet() is deprecated, use note_get() instead", 582 DeprecationWarning, 583 stacklevel=2, 584 ) 585 return self.note_get(id)
Deprecated since version Use note_get() instead..
587 def NoteCreate(self, NoteData: dict[str, Any]) -> dict[str, Any]: 588 """.. deprecated:: Use :meth:`note_create` instead.""" 589 warnings.warn( 590 "NoteCreate() is deprecated, use note_create() instead", 591 DeprecationWarning, 592 stacklevel=2, 593 ) 594 return self.note_create(NoteData)
Deprecated since version Use note_create() instead..
596 def NoteComment(self, note_id: int, comment: str) -> dict[str, Any]: 597 """.. deprecated:: Use :meth:`note_comment` instead.""" 598 warnings.warn( 599 "NoteComment() is deprecated, use note_comment() instead", 600 DeprecationWarning, 601 stacklevel=2, 602 ) 603 return self.note_comment(note_id, comment)
Deprecated since version Use note_comment() instead..
605 def NoteClose(self, note_id: int, comment: Optional[str] = None) -> dict[str, Any]: 606 """.. deprecated:: Use :meth:`note_close` instead.""" 607 warnings.warn( 608 "NoteClose() is deprecated, use note_close() instead", 609 DeprecationWarning, 610 stacklevel=2, 611 ) 612 return self.note_close(note_id, comment)
Deprecated since version Use note_close() instead..
614 def NoteReopen(self, note_id: int, comment: Optional[str] = None) -> dict[str, Any]: 615 """.. deprecated:: Use :meth:`note_reopen` instead.""" 616 warnings.warn( 617 "NoteReopen() is deprecated, use note_reopen() instead", 618 DeprecationWarning, 619 stacklevel=2, 620 ) 621 return self.note_reopen(note_id, comment)
Deprecated since version Use note_reopen() instead..
623 def NotesSearch( 624 self, query: str, limit: int = 100, closed: int = 7 625 ) -> list[dict[str, Any]]: 626 """.. deprecated:: Use :meth:`notes_search` instead.""" 627 warnings.warn( 628 "NotesSearch() is deprecated, use notes_search() instead", 629 DeprecationWarning, 630 stacklevel=2, 631 ) 632 return self.notes_search(query, limit, closed)
Deprecated since version Use notes_search() instead..
644 def Map( 645 self, min_lon: float, min_lat: float, max_lon: float, max_lat: float 646 ) -> list[dict[str, Any]]: 647 """.. deprecated:: Use :meth:`map` instead.""" 648 warnings.warn( 649 "Map() is deprecated, use map() instead", 650 DeprecationWarning, 651 stacklevel=2, 652 ) 653 return self.map(min_lon, min_lat, max_lon, max_lat)
Deprecated since version Use map() instead..
Inherited Members
- osmapi.node.NodeMixin
- node_get
- node_create
- node_update
- node_delete
- node_history
- node_ways
- node_relations
- nodes_get
- osmapi.way.WayMixin
- way_get
- way_create
- way_update
- way_delete
- way_history
- way_relations
- way_full
- ways_get
- osmapi.relation.RelationMixin
- relation_get
- relation_create
- relation_update
- relation_delete
- relation_history
- relation_relations
- relation_full_recur
- relation_full
- relations_get
- osmapi.changeset.ChangesetMixin
- changeset
- changeset_get
- changeset_update
- changeset_create
- changeset_close
- changeset_upload
- changeset_download
- changesets_get
- changeset_comment
- changeset_subscribe
- changeset_unsubscribe