{"id":24494837,"url":"https://github.com/docentyt/osm_easy_api","last_synced_at":"2026-04-01T20:31:32.473Z","repository":{"id":102420161,"uuid":"609213917","full_name":"docentYT/osm_easy_api","owner":"docentYT","description":"Python package for parsing osm diffs and communicating with the osm api.","archived":false,"fork":false,"pushed_at":"2024-09-16T18:09:09.000Z","size":346,"stargazers_count":10,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-25T14:06:09.514Z","etag":null,"topics":["openstreetmap","openstreetmap-api","python"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/docentYT.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"custom":["https://tipply.pl/u/docent"]}},"created_at":"2023-03-03T16:03:36.000Z","updated_at":"2024-09-16T18:09:13.000Z","dependencies_parsed_at":null,"dependency_job_id":"8cb89cbe-89df-4349-8487-46214185241e","html_url":"https://github.com/docentYT/osm_easy_api","commit_stats":{"total_commits":89,"total_committers":3,"mean_commits":"29.666666666666668","dds":0.1460674157303371,"last_synced_commit":"820788a69020500739797ab44a233132da26f5cd"},"previous_names":[],"tags_count":19,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/docentYT%2Fosm_easy_api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/docentYT%2Fosm_easy_api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/docentYT%2Fosm_easy_api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/docentYT%2Fosm_easy_api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/docentYT","download_url":"https://codeload.github.com/docentYT/osm_easy_api/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248813827,"owners_count":21165631,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["openstreetmap","openstreetmap-api","python"],"created_at":"2025-01-21T20:17:35.649Z","updated_at":"2026-04-01T20:31:32.468Z","avatar_url":"https://github.com/docentYT.png","language":"Python","readme":"\u003ch1 align=\"center\"\u003eosm_easy_api\u003c/h1\u003e\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://github.com/docentYT/osm_easy_api/actions/workflows/tests.yaml/badge.svg\" /\u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/docentYT/osm_easy_api/main/coverage-badge.svg\" /\u003e\n  \u003ca href=\"https://pypi.org/project/osm-easy-api/\"\u003e\n    \u003cimg src=\"https://img.shields.io/pypi/v/osm_easy_api\" /\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://pypi.org/project/osm-easy-api/\"\u003e\n    \u003cimg src=\"https://img.shields.io/pypi/dm/osm_easy_api\" alt=\"pypi downloads\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://pypi.org/project/osm-easy-api/\"\u003e\n    \u003cimg alt=\"python versions\" src=\"https://img.shields.io/pypi/pyversions/osm_easy_api\" target=\"_blank\" /\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\u003ca href=\"https://www.openstreetmap.org/user/kwiatek_123\"\u003eMe on OpenStreetMap\u003c/a\u003e\u003c/p\u003e\n\n\u003e Python package for parsing osm diffs and communicating with the OpenStreetMap api.\n\n### What's the point of this package?\n\nThis package was created to provide an easy way to create automated scripts and programs that use diff and/or osm api. The main advantage is the classes (data_classes) that provide data of elements (node, way, relation, OsmChange, etc.) in a readable way and the possibility to use them in diff and api without worrying about missing data or dictionaries. You can easily find nodes in diff, add a tag to them and send the corrected version to osm.\n\n## Installation\n\nWorks on python \u003e= 3.10. (Due to new typehints standard)\n\nInstall `osm_easy_api` from [PyPi](https://pypi.org/project/osm-easy-api/):\n```\npip install osm_easy_api\n``` \n\n## Documentation\n\nYou can view documentation on [github-pages](https://docentyt.github.io/osm_easy_api/osm_easy_api.html).\n\nDocumentation is build using [pdoc](https://pdoc.dev).\nTo run docs on your machine use preferred command: `pdoc --docformat google --no-show-source osm_easy_api !osm_easy_api.utils`.\n\n## OAuth 2.0\nDue to the deprecation of HTTP Basic Auth you need an access token to use most api endpoints. To obtain an access token we recommend using https://tools.interactivemaps.xyz/token/.\n\n\n## Examples\n\n### DIFF\n\n#### Print trees\n\n```py\nfrom osm_easy_api.diff import Diff, Frequency\nfrom osm_easy_api.data_classes import Node\n\n# Download diff from last hour.\nd = Diff(Frequency.HOUR)\n\n# Get Meta namedtuple for diff metadata and generator that parse diff file.\nmeta, gen = d.get(tags=\"natural\")\n\n# Print all created, modified and deleted Nodes with natural=tree tag.\nfor action, element in gen:\n    if type(element) == Node and element.tags.get(\"natural\") == \"tree\":\n        print(action, element.id)\n```\n\n#### Print incorrectly tagged single tress\n\n```py\nfrom osm_easy_api.diff import Diff, Frequency\nfrom osm_easy_api.data_classes import Action, Node\n\nd = Diff(Frequency.DAY)\n\nmeta, gen = d.get(tags=\"natural\")\n\nfor action, element in gen:\n    if type(element) == Node:\n        if action == Action.CREATE or action == Action.MODIFY:\n            if element.tags.get(\"natural\") == \"wood\":\n                print(element)\n```\nExample output:\n```\nNode(id = 10208486717, visible = None, version = 1, changeset_id = 129216075, timestamp = 2022-11-22T00:16:44Z, user_id = 17471721, tags = {'leaf_type': 'broadleaved', 'natural': 'wood'}, latitude = 48.6522286, longitude = 12.583809, )\n```\n\n### API\n\n#### Add missing wikidata tag\n\n```py\nfrom osm_easy_api.api import Api\nfrom osm_easy_api.data_classes import Node, Tags\n\napi = Api(USER_AGENT, \"https://master.apis.dev.openstreetmap.org\", ACCESS_TOKEN)\n\nnode = api.elements.get(Node, 4296460336) # We are getting Node with id 4296460336 where we want to add a new tag to\nnode.tags.add(\"wikidata\", \"Qexample\") # Add a new tag to node.\n\nmy_changeset = api.changeset.create(\"Add missing wikidata tag\", Tags({\"automatic\": \"yes\"})) # Create new changeset with description and tag\napi.elements.update(node, my_changeset) # Send new version of a node to osm\napi.changeset.close(my_changeset) # Close changeset.\n```\n\n## Notes\n\nNote that the following codes do the same thing\n```py\nfrom osm_easy_api.diff import Diff, Frequency\n\nd = Diff(Frequency.DAY)\n\nmeta, gen = d.get()\n\nfor action, element in gen:\n    if element.tags.get(\"shop\") == \"convenience\":\n        print(element)\n```\n```py\nfrom osm_easy_api.diff import Diff, Frequency\nfrom osm_easy_api.data_classes import Tags\n\nd = Diff(Frequency.DAY)\n\nmeta, gen = d.get(tags=Tags({\"shop\": \"convenience\"}))\n\nfor action, element in gen:\n        print(element)\n```\nbut the second seems to be faster.\n\nAlso you can use OsmChange object if you don't want to use generator\n```py\nfrom osm_easy_api.diff import Diff, Frequency\nfrom osm_easy_api.data_classes import Action, Node\n\nd = Diff(Frequency.MINUTE)\n\nosmChange = d.get(generator=False)\n\ndeleted_nodes = osmChange.get(Node, Action.DELETE)\nfor node in deleted_nodes:\n    print(node.id)\n```\nbut it can consume large amounts of ram and use of this method is not recommended for large diff's.\n\n## Tests\n\nYou will need to install `test-requirements.txt`. You can use tox.\nTo run tests manually use `python -m unittest discover`.\n","funding_links":["https://tipply.pl/u/docent"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdocentyt%2Fosm_easy_api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdocentyt%2Fosm_easy_api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdocentyt%2Fosm_easy_api/lists"}