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"))
logger = <Logger osmapi.OsmApi (WARNING)>
 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

OsmApi( username: Optional[str] = None, password: Optional[str] = None, passwordfile: Optional[str] = None, appid: str = '', created_by: str = 'osmapi/5.0.0', api: str = 'https://www.openstreetmap.org', session: Optional[requests.sessions.Session] = None, timeout: int = 30)
 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.

http_session: Optional[requests.sessions.Session]
def close(self) -> None:
161    def close(self) -> None:
162        if self._session:
163            self._session.close()
def Capabilities(self) -> dict[str, dict[str, typing.Any]]:
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.

def NodeGet(self, NodeId: int, NodeVersion: int = -1) -> dict[str, typing.Any]:
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..

def NodeCreate(self, NodeData: dict[str, typing.Any]) -> Optional[dict[str, Any]]:
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..

def NodeUpdate(self, NodeData: dict[str, typing.Any]) -> Optional[dict[str, Any]]:
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..

def NodeDelete(self, NodeData: dict[str, typing.Any]) -> Optional[dict[str, Any]]:
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..

def NodeHistory(self, NodeId: int) -> dict[int, dict[str, typing.Any]]:
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..

def NodeWays(self, NodeId: int) -> list[dict[str, typing.Any]]:
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..

def NodeRelations(self, NodeId: int) -> list[dict[str, typing.Any]]:
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..

def NodesGet(self, NodeIdList: list[int]) -> dict[int, dict[str, typing.Any]]:
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..

def WayGet(self, WayId: int, WayVersion: int = -1) -> dict[str, typing.Any]:
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..

def WayCreate(self, WayData: dict[str, typing.Any]) -> Optional[dict[str, Any]]:
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..

def WayUpdate(self, WayData: dict[str, typing.Any]) -> Optional[dict[str, Any]]:
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..

def WayDelete(self, WayData: dict[str, typing.Any]) -> Optional[dict[str, Any]]:
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..

def WayHistory(self, WayId: int) -> dict[int, dict[str, typing.Any]]:
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..

def WayRelations(self, WayId: int) -> list[dict[str, typing.Any]]:
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..

def WayFull(self, WayId: int) -> list[dict[str, typing.Any]]:
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..

def WaysGet(self, WayIdList: list[int]) -> dict[int, dict[str, typing.Any]]:
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..

def RelationGet( self, RelationId: int, RelationVersion: int = -1) -> dict[str, typing.Any]:
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..

def RelationCreate(self, RelationData: dict[str, typing.Any]) -> Optional[dict[str, Any]]:
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..

def RelationUpdate(self, RelationData: dict[str, typing.Any]) -> Optional[dict[str, Any]]:
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..

def RelationDelete(self, RelationData: dict[str, typing.Any]) -> Optional[dict[str, Any]]:
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..

def RelationHistory(self, RelationId: int) -> dict[int, dict[str, typing.Any]]:
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..

def RelationRelations(self, RelationId: int) -> list[dict[str, typing.Any]]:
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..

def RelationFullRecur(self, RelationId: int) -> list[dict[str, typing.Any]]:
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..

def RelationFull(self, RelationId: int) -> list[dict[str, typing.Any]]:
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..

def RelationsGet(self, RelationIdList: list[int]) -> dict[int, dict[str, typing.Any]]:
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..

@contextmanager
def Changeset( self, ChangesetTags: Optional[dict[str, str]] = None) -> Generator[int, NoneType, NoneType]:
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..

def ChangesetGet( self, ChangesetId: int, include_discussion: bool = False) -> dict[str, typing.Any]:
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..

def ChangesetUpdate(self, ChangesetTags: Optional[dict[str, str]] = None) -> int:
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..

def ChangesetCreate(self, ChangesetTags: Optional[dict[str, str]] = None) -> int:
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..

def ChangesetClose(self) -> int:
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..

def ChangesetUpload( self, ChangesData: list[dict[str, typing.Any]]) -> list[dict[str, typing.Any]]:
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..

def ChangesetDownload(self, ChangesetId: int) -> list[dict[str, typing.Any]]:
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..

def ChangesetsGet( self, min_lon: Optional[float] = None, min_lat: Optional[float] = None, max_lon: Optional[float] = None, max_lat: Optional[float] = None, userid: Optional[int] = None, username: Optional[str] = None, closed_after: Optional[str] = None, created_before: Optional[str] = None, only_open: bool = False, only_closed: bool = False) -> dict[int, dict[str, typing.Any]]:
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..

def ChangesetComment(self, ChangesetId: int, comment: str) -> dict[str, typing.Any]:
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..

def ChangesetSubscribe(self, ChangesetId: int) -> dict[str, typing.Any]:
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..

def ChangesetUnsubscribe(self, ChangesetId: int) -> dict[str, typing.Any]:
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..

def NotesGet( self, min_lon: float, min_lat: float, max_lon: float, max_lat: float, limit: int = 100, closed: int = 7) -> list[dict[str, typing.Any]]:
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..

def NoteGet(self, id: int) -> dict[str, typing.Any]:
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..

def NoteCreate(self, NoteData: dict[str, typing.Any]) -> dict[str, typing.Any]:
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..

def NoteComment(self, note_id: int, comment: str) -> dict[str, typing.Any]:
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..

def NoteClose( self, note_id: int, comment: Optional[str] = None) -> dict[str, typing.Any]:
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..

def NoteReopen( self, note_id: int, comment: Optional[str] = None) -> dict[str, typing.Any]:
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..

def NotesSearch( self, query: str, limit: int = 100, closed: int = 7) -> list[dict[str, typing.Any]]:
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..

def Map( self, min_lon: float, min_lat: float, max_lon: float, max_lat: float) -> list[dict[str, typing.Any]]:
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..