Giter Club home page Giter Club logo

osmapi's Introduction

osmapi

Build osmapi Version License Coverage Code style: black pre-commit

Python wrapper for the OSM API (requires Python >= 3.8)

Installation

Install osmapi from PyPi by using pip:

pip install osmapi

Documentation

The documentation is generated using pdoc and can be viewed online.

The build the documentation locally, you can use

make docs

This project uses GitHub Pages to publish its documentation. To update the online documentation, you need to re-generate the documentation with the above command and update the master branch of this repository.

Examples

To test this library, please create an account on the development server of OpenStreetMap (https://api06.dev.openstreetmap.org).

Check the examples directory to find more example code.

Read from OpenStreetMap

>>> import osmapi
>>> api = osmapi.OsmApi()
>>> print(api.NodeGet(123))
{u'changeset': 532907, u'uid': 14298,
u'timestamp': u'2007-09-29T09:19:17Z',
u'lon': 10.790009299999999, u'visible': True,
u'version': 1, u'user': u'Mede',
u'lat': 59.9503044, u'tag': {}, u'id': 123}

Write to OpenStreetMap

>>> import osmapi
>>> api = osmapi.OsmApi(api="https://api06.dev.openstreetmap.org", username = u"metaodi", password = u"*******")
>>> api.ChangesetCreate({u"comment": u"My first test"})
>>> print(api.NodeCreate({u"lon":1, u"lat":1, u"tag": {}}))
{u'changeset': 532907, u'lon': 1, u'version': 1, u'lat': 1, u'tag': {}, u'id': 164684}
>>> api.ChangesetClose()

OAuth authentication

Username/Password authentication will be deprecated in July 2024 (see official OWG announcemnt for details). In order to use this library in the future, you'll need to use OAuth 2.0.

To use OAuth 2.0, you must register an application with an OpenStreetMap account, either on the development server or on the production server. Once this registration is done, you'll get a client_id and a client_secret that you can use to authenticate users.

Example code using cli-oauth2 on the development server, replace OpenStreetMapDevAuth with OpenStreetMapAuth to use the production server:

import osmapi
from oauthcli import OpenStreetMapDevAuth

client_id = "<client_id>"
client_secret = "<client_secret>"

auth = OpenStreetMapDevAuth(
    client_id, client_secret, ['read_prefs', 'write_map']
).auth_code()

api = osmapi.OsmApi(
    api="https://api06.dev.openstreetmap.org",
    session=auth.session
)

with api.Changeset({"comment": "My first test"}) as changeset_id:
    print(f"Part of Changeset {changeset_id}")
    node1 = api.NodeCreate({"lon": 1, "lat": 1, "tag": {}})
    print(node1)

An alternative way using the requests-oauthlib library can be found in the examples.

User agent / credit for application

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.

api = osmapi.OsmApi(
    api="https://api06.dev.openstreetmap.org",
    appid="MyOSM Script"
)

If then changesets are made using this osmapi instance, they get a tag created_by with the following content: MyOSM Script (osmapi/<version>)

Example changeset of Kort using osmapi

Note about imports / automated edits

Scripted imports and automated edits should only be carried out by those with experience and understanding of the way the OpenStreetMap community creates maps, and only with careful planning and consultation with the local community.

See the Import/Guidelines and Automated Edits/Code of Conduct for more information.

Development

If you want to help with the development of osmapi, you should clone this repository and install the requirements:

make deps

Better yet use the provided setup.sh script to create a virtual env and install this package in it.

You can lint the source code using this command:

make lint

And if you want to reformat the files (using the black code style) simply run:

make format

To run the tests use the following command:

make test

Release

To create a new release, follow these steps (please respect Semantic Versioning):

  1. Adapt the version number in osmapi/__init__.py
  2. Update the CHANGELOG with the version
  3. Re-build the documentation (make docs)
  4. Create a pull request to merge develop into master (make sure the tests pass!)
  5. Create a new release/tag on GitHub (on the master branch)
  6. The publication on PyPI happens via GitHub Actions on every tagged commit

Attribution

This project was orginally developed by Etienne Chové. This repository is a copy of the original code from SVN (http://svn.openstreetmap.org/applications/utils/python_lib/OsmApi/OsmApi.py), with the goal to enable easy contribution via GitHub and release of this package via PyPI.

See also the OSM wiki: http://wiki.openstreetmap.org/wiki/Osmapi

osmapi's People

Contributors

a-detiste avatar austinhartzheim avatar dependabot[bot] avatar eumiro avatar julienpalard avatar lilithwittmann avatar matkoniecz avatar metaodi avatar michaelvl avatar susrisha avatar zverik avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

osmapi's Issues

bugfix for ChangesetUpload

line 501
data += u"<"+change["action"]+">\n"
must be
data += u"<"+change["data"]["action"]+">\n"

line 508
data += u"<"+change["action"]+">\n"
must be
data += u"</"+change["data"]["action"]+">\n"

line 516
data can be none : return is none for upload with only delete data (to be verified)
fix with :
if data != None:
...
(indent code)

line 520
if ChangesData[i]["action"] == "delete":
must be
if ChangesData[i]["data"]["action"] == "delete":

line 741:
autosize = self._chnagesetautosize
must be
autosize = self._changesetautosize

empty notes list crashes api

import osmapi
api = osmapi.OsmApi()
print(api.NotesGet(-93.8472901, 35.9763601, -80, 36.176360100000004, limit=1, closed=0))
print(api.NotesGet(-93.8472901, 35.9763601, -93.6472901, 36.176360100000004, limit=1, closed=0))

results in

[{'lon': -80.33461, 'lat': 36.0379985, 'id': '3506423', 'status': 'open', 'date_created': datetime.datetime(2023, 1, 6, 3, 4, 9), 'date_closed': None, 'comments': [{'date': datetime.datetime(2023, 1, 6, 3, 4, 9), 'action': 'opened', 'text': '1760 jonestown Rd\nBusiness office, Triad Semiconductor\n\nvia StreetComplete 50.1', 'html': '<p>1760 jonestown Rd\n<br />Business office, Triad Semiconductor</p>\n\n<p>via StreetComplete 50.1</p>', 'uid': '18189196', 'user': 'Scollywoggle'}]}]
Traceback (most recent call last):
  File "/home/mateusz/.local/lib/python3.8/site-packages/osmapi/OsmApi.py", line 2076, in _OsmResponseToDom
    first_element = all_data[0]
IndexError: list index out of range

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "test.py", line 4, in <module>
    print(api.NotesGet(-93.8472901, 35.9763601, -93.6472901, 36.176360100000004, limit=1, closed=0))
  File "/home/mateusz/.local/lib/python3.8/site-packages/osmapi/OsmApi.py", line 1599, in NotesGet
    return self.ParseNotes(data)
  File "/home/mateusz/.local/lib/python3.8/site-packages/osmapi/OsmApi.py", line 1841, in ParseNotes
    noteElements = self._OsmResponseToDom(data, tag="note")
  File "/home/mateusz/.local/lib/python3.8/site-packages/osmapi/OsmApi.py", line 2078, in _OsmResponseToDom
    raise XmlResponseInvalidError(
osmapi.OsmApi.XmlResponseInvalidError: The XML response from the OSM API is invalid: IndexError('list index out of range')

note that the first call worked - because it had some notes to return

Passing unicode into minidom

This issue concerns the latest 'requests' based osmapi.

I think the use of requests 'response.text' in '_http_request' and thus passing unicode into minidom is problematic. I think the proper way to do this is to use the raw data 'request.content' for passing into minidom. Subsequently minidom will read the encoding from the xml header (e.g. '') and handle the raw data occording to this encoding information.

I seem to be able to trigger unicode issues with the following code:

import osmapi
a = osmapi.OsmApi()
c = a.ChangesetDownload(37393499)

which generates this unicode exception:

Traceback (most recent call last):
File "", line 1, in
File "osmapi/OsmApi.py", line 1324, in ChangesetDownload
return self.ParseOsc(data)
File "osmapi/OsmApi.py", line 1751, in ParseOsc
data = xml.dom.minidom.parseString(data)
File "/usr/lib/python2.7/xml/dom/minidom.py", line 1928, in parseString
return expatbuilder.parseString(string)
File "/usr/lib/python2.7/xml/dom/expatbuilder.py", line 940, in parseString
return builder.parseString(string)
File "/usr/lib/python2.7/xml/dom/expatbuilder.py", line 223, in parseString
parser.Parse(string, True)
UnicodeEncodeError: 'ascii' codec can't encode character u'\xf8' in position 11709: ordinal not in range(128)

Changing '_http_request' to use 'request.content' corrects this issue.

unhelpful crash message

I guess that I provided wrong data but

  File "/usr/local/lib/python3.5/dist-packages/osmapi/OsmApi.py", line 343, in NodeGet
    data = data.getElementsByTagName("node")[0]
IndexError: list index out of range

is unhelpful in diagnosing what went wrong.

Maybe throwing a more readable exception explaining what is wrong would be a better idea?

too many elements cause 414 error

when attempting to download a big number of elements (say - using WaysGet method) ends in 'Request-URI Too Long'. it would be nice if osmapi is able to fight this by allowing to finish the request in chunks

Fatal error: Extra content at the end of the document

HI,

I'm having some problem with running osmapi on google application engine (GAE). On my local machine the following function works perfectly.

def insertNewLocation(lat, lon):
    MyApi = OsmApi(username=key.OSM_ID, password=key.OSM_PW)
    MyApi.ChangesetCreate({u"comment": u"node creation test"})
    MyApi.NodeCreate({u"lat": lat, u"lon": lon, u"tag": {u"amenity": u"drinking_water"}})
    MyApi.ChangesetClose()

However, on GAE I get the following exception:

Detected Exception: Request failed: 400 - Bad Request - Cannot parse valid node from xml string 
<?xml version="1.0" encoding="UTF-8"?>
<osm version="0.6" generator="osmapi/0.6.2">
  <changeset visible="true">
    <tag k="comment" v="node creation from SearchAroundBot"/>
    <tag k="createdby" v="osmapi/0.6.2"/>
  </changeset>
</osm>
<?xml version="1.0" encoding="UTF-8"?>
<osm version="0.6" generator="osmapi/0.6.2">
  <node lat="51.830871" lon="5.853506" visible="true" changeset="41475419">
    <tag k="note" v="Created by Telegram SearchAroundBot"/>
    <tag k="amenity" v="drinkingwater"/>
    <tag k="bot" v="yes"/>
  </node>
</osm>
. Fatal error: Extra content at the end of the document at :9.

It looks like an underscore disappeared in the xml on the tag value 'drinking_water', but the problem persists with other values not containing underscores (e.g., 'recycling').

Have you encounter this before?

Perhaps one way to debug this problem is to print the 'correct' xml that is sent to the server from my own machine? Is there any easy way to do that?

Thanks

Add ability to send messages?

I am constantly reaching out to local users with the same message by copy/pasting the markdown into page after page. Would be handy to be able to send a message programmatically to an entire group.

Provide a session object to osmapi

To be able to provide a custom session (e.g. to set custom headers or an already authenticated session) osmapi should allow to pass a session to the constructor.

NodeHistory incomplete result

I am trying to fetch history of nodes, for the ones who have a version more than 10 I won't get a full history but rather from version 10.

code:
node_history = MyApi.NodeHistory(each_id)
print ((node_history[len(node_history)]['timestamp'])-(node_history[1]['timestamp'])).days

example case: node with osm id of 288340413. So instead of getting a dict with length of 11 I get a dict with length of 2.

Add support for GPX endpoints

There are several GPX endpoints in the OSM API, e.g.:

GET /api/0.6/trackpoints?bbox=left,bottom,right,top&page=pageNumber

or

POST /api/0.6/gpx/create

osmapi should support those endpoints.

Related: #102

Don't raise XmlResponseInvalidError when using NodeRelations

Function NodeRelations raises XmlResponseInvalidError when the target element isn't used in any relations. In this situation, OSM API do return an valid XML with an empty <osm> element (Check the definition here). I don't think raising XmlResponseInvalidError in this situation is a proper way to go. It might be better to return an empty list, just like the behavior in osmapi v1.0.0.

Consider to make a change for this? For this function, improving the error handling to deal with this or just rolling back to v1.0.0?

Notes that function NodeWays has the same issue.

Thanks for this library!

It is very useful for what I needed - and once I setup initial layer/interface for it (to handle some things a bit differently or on higher level of abstraction) I never needed to interact with it again.

What is exactly what I want from libraries like this one, so thanks for implementing it well!

Use python `logging` instead of debug=True

Using the standard logging mechanism of Python should improve the usage of this library in different contexts.

Make sure the README is adapted for this change and the different logging levels are explained. Maybe even add an example to show log messages.

JSOM exporter ?

Any plan to add a way to export the created data to JSOM (generate .osm files) instead of direct communication with the server ?

nodename nor servname provided, or not known

api = osmapi.OsmApi(api="localhost:3000")
print api.Capabilities()

output

[Errno 8] nodename nor servname provided, or not known
[Errno 8] nodename nor servname provided, or not known
[Errno 8] nodename nor servname provided, or not known
[Errno 8] nodename nor servname provided, or not known
Traceback (most recent call last):
  File "/Users/hanchao/PycharmProjects/importTest/importTest.py", line 14, in <module>
    print api.Capabilities()
  File "/Library/Python/2.7/site-packages/osmapi/OsmApi.py", line 279, in Capabilities
    data = self._get(uri)
  File "/Library/Python/2.7/site-packages/osmapi/OsmApi.py", line 1979, in _get
    return self._http('GET', path, False, None)
  File "/Library/Python/2.7/site-packages/osmapi/OsmApi.py", line 1959, in _http
    "Give up after %s retries" % i
osmapi.OsmApi.MaximumRetryLimitReachedError: Give up after 5 retries
[Errno 8] nodename nor servname provided, or not known

Process finished with exit code 1

readme example is not working

I attempted to use https://github.com/metaodi/osmapi#write-to-openstreetmap

import osmapi
api = osmapi.OsmApi(api="api06.dev.openstreetmap.org", username = u"Mateusz Konieczny", password = u"XXX")
print "changeset creation started"
api.ChangesetCreate({u"comment": u"My first test"})
print api.NodeCreate({u"lon":1, u"lat":1, u"tag": {}})
api.ChangesetClose()

results in

changeset creation started
Invalid URL 'api06.dev.openstreetmap.org/api/0.6/changeset/create': No schema supplied. Perhaps you meant http://api06.dev.openstreetmap.org/api/0.6/changeset/create?
Invalid URL 'api06.dev.openstreetmap.org/api/0.6/changeset/create': No schema supplied. Perhaps you meant http://api06.dev.openstreetmap.org/api/0.6/changeset/create?
Invalid URL 'api06.dev.openstreetmap.org/api/0.6/changeset/create': No schema supplied. Perhaps you meant http://api06.dev.openstreetmap.org/api/0.6/changeset/create?
Invalid URL 'api06.dev.openstreetmap.org/api/0.6/changeset/create': No schema supplied. Perhaps you meant http://api06.dev.openstreetmap.org/api/0.6/changeset/create?
Invalid URL 'api06.dev.openstreetmap.org/api/0.6/changeset/create': No schema supplied. Perhaps you meant http://api06.dev.openstreetmap.org/api/0.6/changeset/create?
Traceback (most recent call last):
  File "generate_osm_edits.py", line 4, in <module>
    api.ChangesetCreate({u"comment": u"My first test"})
  File "/usr/local/lib/python2.7/dist-packages/osmapi/OsmApi.py", line 1275, in ChangesetCreate
    self._XmlBuild("changeset", {"tag": ChangesetTags})
  File "/usr/local/lib/python2.7/dist-packages/osmapi/OsmApi.py", line 2050, in _put
    return self._http('PUT', path, True, data, return_value=return_value)
  File "/usr/local/lib/python2.7/dist-packages/osmapi/OsmApi.py", line 2027, in _http
    "Give up after %s retries" % i
osmapi.OsmApi.MaximumRetryLimitReachedError: Give up after 5 retries

changing api to

api = osmapi.OsmApi(api="http://api06.dev.openstreetmap.org", username = u"Mateusz Konieczny", password = u"XXX")

results in

changeset creation started
Traceback (most recent call last):
  File "generate_osm_edits.py", line 4, in <module>
    api.ChangesetCreate({u"comment": u"My first test"})
  File "/usr/local/lib/python2.7/dist-packages/osmapi/OsmApi.py", line 1275, in ChangesetCreate
    self._XmlBuild("changeset", {"tag": ChangesetTags})
  File "/usr/local/lib/python2.7/dist-packages/osmapi/OsmApi.py", line 2050, in _put
    return self._http('PUT', path, True, data, return_value=return_value)
  File "/usr/local/lib/python2.7/dist-packages/osmapi/OsmApi.py", line 2010, in _http
    return_value=return_value
  File "/usr/local/lib/python2.7/dist-packages/osmapi/OsmApi.py", line 1984, in _http_request
    raise ApiError(response.status_code, response.reason, payload)
osmapi.OsmApi.ApiError: Request failed: 404 - Not Found - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "http://www.w3.org/TR/html4/loose.dtd">
<html>
<body>
  <img src="/assets/osm_logo.png" style="float:left; margin:10px">
  <div style="float:left;">
    <h1>File not found</h1>  
    <p>Couldn't find a file/directory/API operation by that name on the OpenStreetMap server (HTTP 404)</p>
    <p>Feel free to <a href="http://wiki.openstreetmap.org/wiki/Contact" title="Various contact channels explained">contact</a> the OpenStreetMap community if you have found a broken link / bug. Make a note of the exact URL of your request.</p>
  </div>
</body>
</html>

changing api to

api = osmapi.OsmApi(api="http://master.apis.dev.openstreetmap.org", username = u"Mateusz Konieczny", password = u"XXX")

results in

changeset creation started
Traceback (most recent call last):
  File "generate_osm_edits.py", line 4, in <module>
    api.ChangesetCreate({u"comment": u"My first test"})
  File "/usr/local/lib/python2.7/dist-packages/osmapi/OsmApi.py", line 1275, in ChangesetCreate
    self._XmlBuild("changeset", {"tag": ChangesetTags})
  File "/usr/local/lib/python2.7/dist-packages/osmapi/OsmApi.py", line 2050, in _put
    return self._http('PUT', path, True, data, return_value=return_value)
  File "/usr/local/lib/python2.7/dist-packages/osmapi/OsmApi.py", line 2010, in _http
    return_value=return_value
  File "/usr/local/lib/python2.7/dist-packages/osmapi/OsmApi.py", line 1984, in _http_request
    raise ApiError(response.status_code, response.reason, payload)
osmapi.OsmApi.ApiError: Request failed: 400 - Bad Request - Cannot parse valid changeset from xml string . Must specify a string with one or more characters
pip2 list | grep osmapi
osmapi (1.0.2)

python2 --version
Python 2.7.12

uname -a
Linux grisznak 4.10.0-33-generic #37~16.04.1-Ubuntu SMP Fri Aug 11 14:07:24 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

Prepare for HTTP Basic Auth deprecation

https://www.openstreetmap.org/user/pnorman/diary/401157

The Operations Working Group is looking at what it take to deprecate HTTP Basic Auth and OAuth 1.0a in favour of OAuth 2.0 on the main API in order to improve security and reduce code maintenance.

it seems that it is not happening soon but...

#113 (comment)

the library uses basic auth by default, but by allowing to pass a http session, it should be possible to enable OAuth. If I have a little spare time, I'll trs to come up with some example code. Then we can adapt the library if needed.

Consider more specific exceptions than osmapi.OsmApi.ApiError

osmapi.OsmApi.ApiError: Request failed: 409 - Conflict - b'The changeset 111530865 was closed at 2021-09-22 09:42:47 UTC'

I would like to catch just "adding to closed changeset" errors and it seems that it will require error prone parsing of strings. Is there a better way to do this?

OSM notes

Hello,

do you plan to support GET & POST requests on OSM notes also ?

My password contains a column.

Hi!

Thanks for osmapi!

I'm having a small issue though, but easy to fix: while reading the password from the password file, using line = line.strip().split(":", 1) instead of line = line.strip().split(":") would allow my password to read correctly. As my password contains a column, it currently split in three parts, and the last one is discarded.

Bests.

2.0.2 fails to build due to test failures

The Debian package for 2.0.2 fails to build due to test failures:

There are several AttributeError issues like this:

tests/node_test.py F.....FException ignored in: <function OsmApi.__del__ at 0x7feffbd95ab0>
Traceback (most recent call last):
  File "/build/python-osmapi-2.0.2/.pybuild/cpython3_3.10_osmapi/build/osmapi/OsmApi.py", line 166, in __del__
    self.close()
  File "/build/python-osmapi-2.0.2/.pybuild/cpython3_3.10_osmapi/build/osmapi/OsmApi.py", line 179, in close
    if self._changesetauto:
AttributeError: 'OsmApi' object has no attribute '_changesetauto'

And several TypeError issues like this:

=================================== FAILURES ===================================
_______________________ TestOsmApiNode.test_Capabilities _______________________

self = <tests.capabilities_test.TestOsmApiNode testMethod=test_Capabilities>

    def test_Capabilities(self):
        self._session_mock()
    
>       result = self.api.Capabilities()

tests/capabilities_test.py:9: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
osmapi/OsmApi.py:229: in Capabilities
    data = self._OsmResponseToDom(data, tag="api", single=True)
osmapi/OsmApi.py:2085: in _OsmResponseToDom
    dom = xml.dom.minidom.parseString(response)
/usr/lib/python3.10/xml/dom/minidom.py:1998: in parseString
    return expatbuilder.parseString(string)
/usr/lib/python3.10/xml/dom/expatbuilder.py:925: in parseString
    return builder.parseString(string)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <xml.dom.expatbuilder.ExpatBuilderNS object at 0x7feffba09660>
string = <Mock name='mock.content' id='140668695524880'>

    def parseString(self, string):
        """Parse a document from a string, returning the document node."""
        parser = self.getParser()
        try:
>           parser.Parse(string, True)
E           TypeError: a bytes-like object is required, not 'Mock'

/usr/lib/python3.10/xml/dom/expatbuilder.py:223: TypeError
----------------------------- Captured stdout call -----------------------------
test_Capabilities
<osmapi.OsmApi.OsmApi object at 0x7feffba0b1f0>
None
[]

Full buildlog: python-osmapi.txt

test_deleted_element_raises_exception fails without network

osmapi 1.0.0 fails to build due to test failures in build environments without network (like the Debian build chroots), test_deleted_element_raises_exception is not mocked unlike other tests:

======================================================================
ERROR: test_deleted_element_raises_exception (tests.functional_tests.TestOsmApiFunctional)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python2.7/dist-packages/httpretty/core.py", line 1146, in wrapper
    return test(*args, **kw)
  File "/build/python-osmapi-1.0.0/tests/functional_tests.py", line 16, in test_deleted_element_raises_exception
    api.RelationFull(2911456)
  File "/build/python-osmapi-1.0.0/osmapi/OsmApi.py", line 1134, in RelationFull
    data = self._get(uri)
  File "/build/python-osmapi-1.0.0/osmapi/OsmApi.py", line 1995, in _get
    return self._http('GET', path, False, None)
  File "/build/python-osmapi-1.0.0/osmapi/OsmApi.py", line 1975, in _http
    "Give up after %s retries" % i
MaximumRetryLimitReachedError: Give up after 5 retries
-------------------- >> begin captured stdout << ---------------------
HTTPSConnectionPool(host='www.openstreetmap.org', port=443): Max retries exceeded with url: /api/0.6/relation/2911456/full (Caused by ProxyError('Cannot connect to proxy.', NewConnectionError('<urllib3.connection.VerifiedHTTPSConnection object at 0x7fd89418af90>: Failed to establish a new connection: [Errno 111] Connection refused',)))
HTTPSConnectionPool(host='www.openstreetmap.org', port=443): Max retries exceeded with url: /api/0.6/relation/2911456/full (Caused by ProxyError('Cannot connect to proxy.', NewConnectionError('<urllib3.connection.VerifiedHTTPSConnection object at 0x7fd894129910>: Failed to establish a new connection: [Errno 111] Connection refused',)))
HTTPSConnectionPool(host='www.openstreetmap.org', port=443): Max retries exceeded with url: /api/0.6/relation/2911456/full (Caused by ProxyError('Cannot connect to proxy.', NewConnectionError('<urllib3.connection.VerifiedHTTPSConnection object at 0x7fd894129a50>: Failed to establish a new connection: [Errno 111] Connection refused',)))
HTTPSConnectionPool(host='www.openstreetmap.org', port=443): Max retries exceeded with url: /api/0.6/relation/2911456/full (Caused by ProxyError('Cannot connect to proxy.', NewConnectionError('<urllib3.connection.VerifiedHTTPSConnection object at 0x7fd894129a10>: Failed to establish a new connection: [Errno 111] Connection refused',)))
HTTPSConnectionPool(host='www.openstreetmap.org', port=443): Max retries exceeded with url: /api/0.6/relation/2911456/full (Caused by ProxyError('Cannot connect to proxy.', NewConnectionError('<urllib3.connection.VerifiedHTTPSConnection object at 0x7fd894129b50>: Failed to establish a new connection: [Errno 111] Connection refused',)))

--------------------- >> end captured stdout << ----------------------
-------------------- >> begin captured logging << --------------------
urllib3.connectionpool: DEBUG: Starting new HTTPS connection (1): www.openstreetmap.org
urllib3.connectionpool: DEBUG: Starting new HTTPS connection (1): www.openstreetmap.org
urllib3.connectionpool: DEBUG: Starting new HTTPS connection (1): www.openstreetmap.org
urllib3.connectionpool: DEBUG: Starting new HTTPS connection (1): www.openstreetmap.org
urllib3.connectionpool: DEBUG: Starting new HTTPS connection (1): www.openstreetmap.org
--------------------- >> end captured logging << ---------------------

----------------------------------------------------------------------
Ran 82 tests in 15.345s

Create a more "pythonic" API

The public API of osmapi is not very pythonic, it would be nice to create an alternative - more pythonic - API to be better integrated in the whole python world.

This starts with the camelcase naming of the methods, but also the lack of structure. I'm not yet sure how an ideal structure would look like, but maybe a classic OOP approach wouldn't be too bad, and then having a class for each type of OSM object.

But the current API should stay valid to not break existing code.

Parse() argument 1 must be string or read-only buffer, not None

When i download the data of a Relation I get a Type error

Code to reproduce:

from osmapi import OsmApi
api = OsmApi()
api.RelationFull(2911456) 

Traceback:

/home/xevi/.virtualenvs/changeswithin/lib/python2.7/site-packages/osmapi/OsmApi.pyc in RelationFull(self, RelationId)
1126 uri = "/api/0.6/relation/%s/full" % (RelationId)
1127 data = self._get(uri)
-> 1128 return self.ParseOsm(data)
1129
1130 def RelationsGet(self, RelationIdList):

/home/xevi/.virtualenvs/changeswithin/lib/python2.7/site-packages/osmapi/OsmApi.pyc in ParseOsm(self, data)
1709 }
1710 """
-> 1711 data = xml.dom.minidom.parseString(data)
1712 data = data.getElementsByTagName("osm")[0]
1713 result = []

/usr/lib64/python2.7/xml/dom/minidom.pyc in parseString(string, parser)
1926 if parser is None:
1927 from xml.dom import expatbuilder
-> 1928 return expatbuilder.parseString(string)
1929 else:
1930 from xml.dom import pulldom

/usr/lib64/python2.7/xml/dom/expatbuilder.pyc in parseString(string, namespaces)
938 else:
939 builder = ExpatBuilder()
--> 940 return builder.parseString(string)
941
942

/usr/lib64/python2.7/xml/dom/expatbuilder.pyc in parseString(self, string)
221 parser = self.getParser()
222 try:
--> 223 parser.Parse(string, True)
224 self._setup_subset(string)
225 except ParseEscape:

The version of osmapi:

pip freeze|grep osmapi
osmapi==0.8.1

Upload multiple nodes/ways/relations with one connection

Wouldn't it be much faster to update several objects with a single call instead of doing NodeUpdate after NodeUpdate after NodeUpdate? Maybe have a NodesUpdate([node1, node2, ...]) call that would bundle that up into a single connection/upload to OSM servers.

Provide more detailed exceptions

Currently only a general ApiError exception is thrown, which can then be examined for a more detailed explanation of the error (e.g. the HTTP status code). It would be best to create sub classes of ApiError for the different known error conditions (e.g. 409 Conflic, 404 Not Found).

see http://wiki.openstreetmap.org/wiki/API_v0.6 for a more detailed lists of errors.

This change should not break existing code, as the new exceptions classes can be implemented as sub classes of the existing ApiError.

Add type hints

Type hints are here to stay and improve the developer experience. By providing hints to all functions, the use of osmapi should be easier for developers.

And static code analyzers could help find bugs.

Add the changeset logic as context manager

I imagine to open a changeset using the with keyword, doing some operations and then it is closed automatically.
A similar logic is already there with the destructor, but this is not guaranteed to work and less explicit.

Closing the requests.session

OsmApi should provide a .close() method to close the underlying _session object, to avoid ResourceWarning: unclosed <ssl.SSLSocket warnings.

It could also provide a __enter__ and a __exit__, to implicitly call the close at exit.

Error installing on clean virtualenv

When I install osmapi on a clean virtualenv with python 2.7.11 I get this:
Collecting osmapi
Downloading osmapi-0.7.1.tar.gz
Complete output from command python setup.py egg_info:
Traceback (most recent call last):
File "", line 1, in
File "/tmp/pip-build-_d5sLy/osmapi/setup.py", line 6, in
version = import('osmapi').version
File "osmapi/init.py", line 5, in
from .OsmApi import * # noqa
File "osmapi/OsmApi.py", line 35, in
import requests
ImportError: No module named requests

Error while uploading "osmapi.OsmApi.ApiError: Request failed: 404 - Not Found - b''

I've just started to explore this API and tried to upload a "way" into OSM.

import osmapi
api = osmapi.OsmApi(api = "https://api06.dev.openstreetmap.org", username = "*******", password =******)
cs = api.ChangesetCreate()
start = api.NodeCreate({"lon":39.77188512682915,"lat":40.99645466061746,"visible":True})
stop = api.NodeCreate({"lon":39.77237597107887,"lat":40.99594855924428,"visible":True})
wayPoints = [start["id"], stop["id"]]
way = api.WayCreate({"nd":wayPoints ,"visible":True})
api.ChangesetUpload([{"type":"way","action":"create","data":way}])
api.ChangesetClose()

"way" is the my way object. After the execution, "Request failed: 404 - Not Found - b" this error occured. Am I doing something wrong or uncomplete?

Remove Python 2.7 support

It's long overdue to remove Python 2.7 support and remove all Code specific to Python 2.x from the codebase.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.