From 869a2c539ba35892d996ee6221f04023652c85e3 Mon Sep 17 00:00:00 2001 From: Geoff Boeing Date: Wed, 28 Feb 2024 21:49:16 -0800 Subject: [PATCH 1/6] deprecate some settings module settings and save_graph_xml function params --- CHANGELOG.md | 6 ++ osmnx/_downloader.py | 37 ++++++++ osmnx/_nominatim.py | 10 +++ osmnx/_overpass.py | 37 ++++++++ osmnx/elevation.py | 9 ++ osmnx/io.py | 82 ++++++----------- osmnx/osm_xml.py | 209 +++++++++++++++++++++++++++++++++---------- osmnx/settings.py | 100 ++++++++++++--------- tests/lint_test.sh | 8 +- 9 files changed, 351 insertions(+), 147 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a18232424..a91612711 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 1.9.2 (TBD) + +- deprecate settings module's default_accept_language, default_referer, default_user_agent, memory, and timeout settings +- deprecate settings module's osm_xml_node_attrs, osm_xml_node_tags, osm_xml_way_attrs, and osm_xml_way_tags settings +- deprecate save_graph_xml function's node_tags, node_attrs, edge_tags, edge_attrs, edge_tag_aggs, merge_edges, oneway, api_version, and precision parameters + ## 1.9.1 (2024-02-01) - fix deprecation warning in simplification.simplify_graph function (#1126) diff --git a/osmnx/_downloader.py b/osmnx/_downloader.py index ebe9add83..282da3c0c 100644 --- a/osmnx/_downloader.py +++ b/osmnx/_downloader.py @@ -6,6 +6,7 @@ from hashlib import sha1 from pathlib import Path from urllib.parse import urlparse +from warnings import warn import requests from requests.exceptions import JSONDecodeError @@ -150,6 +151,33 @@ def _get_http_headers(user_agent=None, referer=None, accept_language=None): ------- headers : dict """ + if settings.default_accept_language is None: + settings.default_accept_language = settings.http_accept_language + else: + msg = ( + "`settings.default_accept_language` is deprecated and will be removed " + "in the v2.0.0 release: use `settings.http_accept_language` instead" + ) + warn(msg, FutureWarning, stacklevel=2) + + if settings.default_referer is None: + settings.default_referer = settings.http_referer + else: + msg = ( + "`settings.default_referer` is deprecated and will be removed in the " + "v2.0.0 release: use `settings.http_referer` instead" + ) + warn(msg, FutureWarning, stacklevel=2) + + if settings.default_user_agent is None: + settings.default_user_agent = settings.http_user_agent + else: + msg = ( + "`settings.default_user_agent` is deprecated and will be removed in " + "the v2.0.0 release: use `settings.http_user_agent` instead" + ) + warn(msg, FutureWarning, stacklevel=2) + if user_agent is None: user_agent = settings.default_user_agent if referer is None: @@ -185,6 +213,15 @@ def _resolve_host_via_doh(hostname): ip_address : string resolved IP address of host, or hostname itself if resolution failed """ + if settings.timeout is None: + settings.timeout = settings.requests_timeout + else: + msg = ( + "`settings.timeout` is deprecated and will be removed in the v2.0.0 " + "release: use `settings.requests_timeout` instead" + ) + warn(msg, FutureWarning, stacklevel=2) + if settings.doh_url_template is None: # if user has set the url template to None, return hostname itself utils.log("User set `doh_url_template=None`, requesting host by name", level=lg.WARNING) diff --git a/osmnx/_nominatim.py b/osmnx/_nominatim.py index 95e6f794a..466814f7e 100644 --- a/osmnx/_nominatim.py +++ b/osmnx/_nominatim.py @@ -3,6 +3,7 @@ import logging as lg import time from collections import OrderedDict +from warnings import warn import requests @@ -84,6 +85,15 @@ def _nominatim_request(params, request_type="search", pause=1, error_pause=60): ------- response_json : dict """ + if settings.timeout is None: + settings.timeout = settings.requests_timeout + else: + msg = ( + "`settings.timeout` is deprecated and will be removed in the v2.0.0 " + "release: use `settings.requests_timeout` instead" + ) + warn(msg, FutureWarning, stacklevel=2) + if request_type not in {"search", "reverse", "lookup"}: # pragma: no cover msg = 'Nominatim request_type must be "search", "reverse", or "lookup"' raise ValueError(msg) diff --git a/osmnx/_overpass.py b/osmnx/_overpass.py index 0704a18f8..513eea8a8 100644 --- a/osmnx/_overpass.py +++ b/osmnx/_overpass.py @@ -3,6 +3,7 @@ import datetime as dt import logging as lg import time +from warnings import warn import numpy as np import requests @@ -122,6 +123,15 @@ def _get_overpass_pause(base_endpoint, recursive_delay=5, default_duration=60): ------- pause : int """ + if settings.timeout is None: + settings.timeout = settings.requests_timeout + else: + msg = ( + "`settings.timeout` is deprecated and will be removed in the " + "v2.0.0 release: use `settings.requests_timeout` instead" + ) + warn(msg, FutureWarning, stacklevel=2) + if not settings.overpass_rate_limit: # if overpass rate limiting is False, then there is zero pause return 0 @@ -183,6 +193,24 @@ def _make_overpass_settings(): ------- string """ + if settings.timeout is None: + settings.timeout = settings.requests_timeout + else: + msg = ( + "`settings.timeout` is deprecated and will be removed in the " + "v2.0.0 release: use `settings.requests_timeout` instead" + ) + warn(msg, FutureWarning, stacklevel=2) + + if settings.memory is None: + settings.memory = settings.overpass_memory + else: + msg = ( + "`settings.memory` is deprecated and will be removed in the " + " v2.0.0 release: use `settings.overpass_memory` instead" + ) + warn(msg, FutureWarning, stacklevel=2) + maxsize = "" if settings.memory is None else f"[maxsize:{settings.memory}]" return settings.overpass_settings.format(timeout=settings.timeout, maxsize=maxsize) @@ -371,6 +399,15 @@ def _overpass_request(data, pause=None, error_pause=60): ------- response_json : dict """ + if settings.timeout is None: + settings.timeout = settings.requests_timeout + else: + msg = ( + "`settings.timeout` is deprecated and will be removed in the " + "v2.0.0 release: use `settings.requests_timeout` instead" + ) + warn(msg, FutureWarning, stacklevel=2) + # resolve url to same IP even if there is server round-robin redirecting _downloader._config_dns(settings.overpass_endpoint) diff --git a/osmnx/elevation.py b/osmnx/elevation.py index 15990c63b..2e700326b 100644 --- a/osmnx/elevation.py +++ b/osmnx/elevation.py @@ -293,6 +293,15 @@ def _elevation_request(url, pause): ------- response_json : dict """ + if settings.timeout is None: + settings.timeout = settings.requests_timeout + else: + msg = ( + "`settings.timeout` is deprecated and will be removed in the v2.0.0 " + "release: use `settings.requests_timeout` instead" + ) + warn(msg, FutureWarning, stacklevel=2) + # check if request already exists in cache cached_response_json = _downloader._retrieve_from_cache(url) if cached_response_json is not None: diff --git a/osmnx/io.py b/osmnx/io.py index e70e1ce18..84e0aa8c1 100644 --- a/osmnx/io.py +++ b/osmnx/io.py @@ -276,15 +276,16 @@ def load_graphml( def save_graph_xml( data, filepath=None, - node_tags=settings.osm_xml_node_tags, - node_attrs=settings.osm_xml_node_attrs, - edge_tags=settings.osm_xml_way_tags, - edge_attrs=settings.osm_xml_way_attrs, - oneway=False, - merge_edges=True, + node_tags=None, + node_attrs=None, + edge_tags=None, + edge_attrs=None, + oneway=None, + merge_edges=None, edge_tag_aggs=None, - api_version=0.6, - precision=6, + api_version=None, + precision=None, + way_tag_aggs=None, ): """ Save graph to disk as an OSM-formatted XML .osm file. @@ -298,62 +299,36 @@ def save_graph_xml( you have downloaded or generated elsewhere, use the `graph.graph_from_xml` function. - Note: for large networks this function can take a long time to run. Before - using this function, make sure you configured OSMnx as described in the - example below when you created the graph. - - Example - ------- - >>> import osmnx as ox - >>> utn = ox.settings.useful_tags_node - >>> oxna = ox.settings.osm_xml_node_attrs - >>> oxnt = ox.settings.osm_xml_node_tags - >>> utw = ox.settings.useful_tags_way - >>> oxwa = ox.settings.osm_xml_way_attrs - >>> oxwt = ox.settings.osm_xml_way_tags - >>> utn = list(set(utn + oxna + oxnt)) - >>> utw = list(set(utw + oxwa + oxwt)) - >>> ox.settings.all_oneway = True - >>> ox.settings.useful_tags_node = utn - >>> ox.settings.useful_tags_way = utw - >>> G = ox.graph_from_place('Piedmont, CA, USA', network_type='drive') - >>> ox.save_graph_xml(G, filepath='./data/graph.osm') - Parameters ---------- - data : networkx multi(di)graph OR a length 2 iterable of nodes/edges - geopandas GeoDataFrames + data : networkx.MultiDiGraph + the input graph filepath : string or pathlib.Path - path to the .osm file including extension. if None, use default data - folder + graph.osm + do not use, deprecated node_tags : list - osm node tags to include in output OSM XML + do not use, deprecated node_attrs: list - osm node attributes to include in output OSM XML + do not use, deprecated edge_tags : list - osm way tags to include in output OSM XML + do not use, deprecated edge_attrs : list - osm way attributes to include in output OSM XML + do not use, deprecated oneway : bool - the default oneway value used to fill this tag where missing + do not use, deprecated merge_edges : bool - if True merges graph edges such that each OSM way has one entry - and one entry only in the OSM XML. Otherwise, every OSM way - will have a separate entry for each node pair it contains. - edge_tag_aggs : list of length-2 string tuples - useful only if merge_edges is True, this argument allows the user - to specify edge attributes to aggregate such that the merged - OSM way entry tags accurately represent the sum total of - their component edge attributes. For example, if the user - wants the OSM way to have a "length" attribute, the user must - specify `edge_tag_aggs=[('length', 'sum')]` in order to tell - this method to aggregate the lengths of the individual - component edges. Otherwise, the length attribute will simply - reflect the length of the first edge associated with the way. + do not use, deprecated + edge_tag_aggs : tuple + do not use, deprecated api_version : float - OpenStreetMap API version to write to the XML file header + do not use, deprecated precision : int - number of decimal places to round latitude and longitude values + do not use, deprecated + way_tag_aggs : dict + Keys are OSM way tag keys and values are aggregation functions + (anything accepted as an argument by pandas.agg). Allows user to + aggregate graph edge attribute values into single OSM way values. If + None, or if some tag's key does not exist in the dict, the way + attribute will be assigned the value of the first edge of the way. Returns ------- @@ -371,6 +346,7 @@ def save_graph_xml( edge_tag_aggs, api_version, precision, + way_tag_aggs, ) diff --git a/osmnx/osm_xml.py b/osmnx/osm_xml.py index 28e479876..bcdedd549 100644 --- a/osmnx/osm_xml.py +++ b/osmnx/osm_xml.py @@ -109,15 +109,16 @@ def _opener(filepath, encoding): def save_graph_xml( data, filepath=None, - node_tags=settings.osm_xml_node_tags, - node_attrs=settings.osm_xml_node_attrs, - edge_tags=settings.osm_xml_way_tags, - edge_attrs=settings.osm_xml_way_attrs, - oneway=False, - merge_edges=True, + node_tags=None, + node_attrs=None, + edge_tags=None, + edge_attrs=None, + oneway=None, + merge_edges=None, edge_tag_aggs=None, - api_version=0.6, - precision=6, + api_version=None, + precision=None, + way_tag_aggs=None, ): """ Do not use: deprecated. @@ -128,8 +129,8 @@ def save_graph_xml( Parameters ---------- - data : networkx.multidigraph - do not use, deprecated + data : networkx.MultiDiGraph + the input graph filepath : string or pathlib.Path do not use, deprecated node_tags : list @@ -144,12 +145,18 @@ def save_graph_xml( do not use, deprecated merge_edges : bool do not use, deprecated - edge_tag_aggs : list of length-2 string tuples + edge_tag_aggs : tuple do not use, deprecated api_version : float do not use, deprecated precision : int do not use, deprecated + way_tag_aggs : dict + Keys are OSM way tag keys and values are aggregation functions + (anything accepted as an argument by pandas.agg). Allows user to + aggregate graph edge attribute values into single OSM way values. If + None, or if some tag's key does not exist in the dict, the way + attribute will be assigned the value of the first edge of the way. Returns ------- @@ -174,65 +181,175 @@ def save_graph_xml( edge_tag_aggs, api_version, precision, + way_tag_aggs, ) -def _save_graph_xml( +def _save_graph_xml( # noqa: C901 data, - filepath=None, - node_tags=settings.osm_xml_node_tags, - node_attrs=settings.osm_xml_node_attrs, - edge_tags=settings.osm_xml_way_tags, - edge_attrs=settings.osm_xml_way_attrs, - oneway=False, - merge_edges=True, - edge_tag_aggs=None, - api_version=0.6, - precision=6, + filepath, + node_tags, + node_attrs, + edge_tags, + edge_attrs, + oneway, + merge_edges, + edge_tag_aggs, + api_version, + precision, + way_tag_aggs, ): """ Save graph to disk as an OSM-formatted UTF-8 encoded XML .osm file. Parameters ---------- - data : networkx multi(di)graph OR a length 2 iterable of nodes/edges - geopandas GeoDataFrames + data : networkx.MultiDiGraph + the input graph filepath : string or pathlib.Path - path to the .osm file including extension. if None, use default data - folder + graph.osm + do not use, deprecated node_tags : list - osm node tags to include in output OSM XML + do not use, deprecated node_attrs: list - osm node attributes to include in output OSM XML + do not use, deprecated edge_tags : list - osm way tags to include in output OSM XML + do not use, deprecated edge_attrs : list - osm way attributes to include in output OSM XML + do not use, deprecated oneway : bool - the default oneway value used to fill this tag where missing + do not use, deprecated merge_edges : bool - if True merges graph edges such that each OSM way has one entry - and one entry only in the OSM XML. Otherwise, every OSM way - will have a separate entry for each node pair it contains. - edge_tag_aggs : list of length-2 string tuples - useful only if merge_edges is True, this argument allows the user - to specify edge attributes to aggregate such that the merged - OSM way entry tags accurately represent the sum total of - their component edge attributes. For example, if the user - wants the OSM way to have a "length" attribute, the user must - specify `edge_tag_aggs=[('length', 'sum')]` in order to tell - this method to aggregate the lengths of the individual - component edges. Otherwise, the length attribute will simply - reflect the length of the first edge associated with the way. + do not use, deprecated + edge_tag_aggs : tuple + do not use, deprecated api_version : float - OpenStreetMap API version to write to the XML file header + do not use, deprecated precision : int - number of decimal places to round latitude and longitude values + do not use, deprecated + way_tag_aggs : dict + Keys are OSM way tag keys and values are aggregation functions + (anything accepted as an argument by pandas.agg). Allows user to + aggregate graph edge attribute values into single OSM way values. If + None, or if some tag's key does not exist in the dict, the way + attribute will be assigned the value of the first edge of the way. Returns ------- None """ + if settings.osm_xml_node_attrs is None: + settings.osm_xml_node_attrs = [ + "id", + "timestamp", + "uid", + "user", + "version", + "changeset", + "lat", + "lon", + ] + else: + msg = ( + "`settings.osm_xml_node_attrs` is deprecated and will be removed " + "in the v2.0.0 release" + ) + warn(msg, FutureWarning, stacklevel=2) + + if settings.osm_xml_node_tags is None: + settings.osm_xml_node_tags = ["highway"] + else: + msg = ( + "`settings.osm_xml_node_tags` is deprecated and will be removed " + "in the v2.0.0 release" + ) + warn(msg, FutureWarning, stacklevel=2) + + if settings.osm_xml_way_attrs is None: + settings.osm_xml_way_attrs = ["id", "timestamp", "uid", "user", "version", "changeset"] + else: + msg = ( + "`settings.osm_xml_way_attrs` is deprecated and will be removed " + "in the v2.0.0 release" + ) + warn(msg, FutureWarning, stacklevel=2) + + if settings.osm_xml_way_tags is None: + settings.osm_xml_way_tags = ["highway", "lanes", "maxspeed", "name", "oneway"] + else: + msg = "`settings.osm_xml_way_tags` is deprecated and will be removed in the v2.0.0 release" + warn(msg, FutureWarning, stacklevel=2) + + if node_tags is None: + node_tags = settings.osm_xml_node_tags + else: + msg = ( + "the `node_tags` parameter is deprecated and will be removed in the v2.0.0 release: " + "use `settings.useful_tags_node` instead starting in v2.0.0" + ) + warn(msg, FutureWarning, stacklevel=2) + + if node_attrs is None: + node_attrs = settings.osm_xml_node_attrs + else: + msg = "the `node_attrs` parameter is deprecated and will be removed in the v2.0.0 release" + warn(msg, FutureWarning, stacklevel=2) + + if edge_tags is None: + edge_tags = settings.osm_xml_way_tags + else: + msg = ( + "the `edge_tags` parameter is deprecated and will be removed in the v2.0.0 release: " + "use `settings.useful_tags_way` instead starting in v2.0.0" + ) + warn(msg, FutureWarning, stacklevel=2) + + if edge_attrs is None: + edge_attrs = settings.osm_xml_way_attrs + else: + msg = "the `edge_attrs` parameter is deprecated and will be removed in the v2.0.0 release" + warn(msg, FutureWarning, stacklevel=2) + + if oneway is None: + oneway = False + else: + msg = "the `oneway` parameter is deprecated and will be removed in the v2.0.0 release" + warn(msg, FutureWarning, stacklevel=2) + + if merge_edges is None: + merge_edges = True + else: + msg = "the `merge_edges` parameter is deprecated and will be removed in the v2.0.0 release" + warn(msg, FutureWarning, stacklevel=2) + + if edge_tag_aggs is None: + if way_tag_aggs is not None: + edge_tag_aggs = way_tag_aggs.items() + else: + msg = ( + "the `edge_tag_aggs` parameter is deprecated and will be removed in the v2.0.0 release: " + "use `way_tag_aggs` instead" + ) + warn(msg, FutureWarning, stacklevel=2) + + if api_version is None: + api_version = 0.6 + else: + msg = "the `api_version` parameter is deprecated and will be removed in the v2.0.0 release" + warn(msg, FutureWarning, stacklevel=2) + + if precision is None: + precision = 6 + else: + msg = "the `precision` parameter is deprecated and will be removed in the v2.0.0 release" + warn(msg, FutureWarning, stacklevel=2) + + if not isinstance(data, nx.MultiDiGraph): + msg = "the graph to save as XML must be of type MultiDiGraph, starting in v2.0.0" + warn(msg, FutureWarning, stacklevel=2) + elif data.graph.get("simplified", False): + msg = "starting in v2.0.0, graph must be unsimplified to save as OSM XML" + warn(msg, FutureWarning, stacklevel=2) + # default filepath if none was provided filepath = Path(settings.data_folder) / "graph.osm" if filepath is None else Path(filepath) diff --git a/osmnx/settings.py b/osmnx/settings.py index 7edafb836..3c38fce63 100644 --- a/osmnx/settings.py +++ b/osmnx/settings.py @@ -10,7 +10,7 @@ bidirectional_network_types : list Network types for which a fully bidirectional graph will be created. Default is `["walk"]`. -cache_folder : string or pathlib.Path +cache_folder : str or pathlib.Path Path to folder in which to save/load HTTP response cache, if the `use_cache` setting equals `True`. Default is `"./cache"`. cache_only_mode : bool @@ -21,12 +21,12 @@ only query Overpass one request at a time) then using the local cache to quickly build many graphs simultaneously with multiprocessing. Default is `False`. -data_folder : string or pathlib.Path +data_folder : str or pathlib.Path Path to folder in which to save/load graph files by default. Default is `"./data"`. -default_accept_language : string - HTTP header accept-language. Default is `"en"`. -default_access : string +default_accept_language : str + Do not use, deprecated. Use `http_accept_language` instead. +default_access : str Default filter for OSM "access" key. Default is `'["access"!~"private"]'`. Note that also filtering out "access=no" ways prevents including transit-only bridges (e.g., Tilikum Crossing) from appearing in drivable @@ -35,77 +35,82 @@ it is accessible, so we can't filter out all "access=no" ways by default. Best to be permissive here then remove complicated combinations of tags programatically after the full graph is downloaded and constructed. -default_crs : string +default_crs : str Default coordinate reference system to set when creating graphs. Default is `"epsg:4326"`. -default_referer : string - HTTP header referer. Default is - `"OSMnx Python package (https://github.com/gboeing/osmnx)"`. -default_user_agent : string - HTTP header user-agent. Default is - `"OSMnx Python package (https://github.com/gboeing/osmnx)"`. -doh_url_template : string +default_referer : str + Do not use, deprecated. Use `http_referer` instead. +default_user_agent : str + Do not use, deprecated. Use `http_user_agent` instead. +doh_url_template : str Endpoint to resolve DNS-over-HTTPS if local DNS resolution fails. Set to None to disable DoH, but see `downloader._config_dns` documentation for caveats. Default is: `"https://8.8.8.8/resolve?name={hostname}"` -elevation_url_template : string +elevation_url_template : str Endpoint of the Google Maps Elevation API (or equivalent), containing exactly two parameters: `locations` and `key`. Default is: `"https://maps.googleapis.com/maps/api/elevation/json?locations={locations}&key={key}"` One example of an alternative equivalent would be Open Topo Data: `"https://api.opentopodata.org/v1/aster30m?locations={locations}&key={key}"` -imgs_folder : string or pathlib.Path +http_accept_language : str + HTTP header accept-language. Default is `"en"`. Note that Nominatim's + default language is "en" and it can sort result importance scores + differently if a different language is specified. +http_referer : str + HTTP header referer. Default is + `"OSMnx Python package (https://github.com/gboeing/osmnx)"`. +http_user_agent : str + HTTP header user-agent. Default is + `"OSMnx Python package (https://github.com/gboeing/osmnx)"`. +imgs_folder : str or pathlib.Path Path to folder in which to save plotted images by default. Default is `"./images"`. log_file : bool If True, save log output to a file in logs_folder. Default is `False`. -log_filename : string +log_filename : str Name of the log file, without file extension. Default is `"osmnx"`. log_console : bool If True, print log output to the console (terminal window). Default is `False`. log_level : int One of Python's logger.level constants. Default is `logging.INFO`. -log_name : string +log_name : str Name of the logger. Default is `"OSMnx"`. -logs_folder : string or pathlib.Path +logs_folder : str or pathlib.Path Path to folder in which to save log files. Default is `"./logs"`. max_query_area_size : int Maximum area for any part of the geometry in meters: any polygon bigger than this will get divided up for multiple queries to the API. Default is `2500000000`. memory : int - Overpass server memory allocation size for the query, in bytes. If - None, server will use its default allocation size. Use with caution. - Default is `None`. -nominatim_endpoint : string + Do not use, deprecated. Use `overpass_memory` instead. +nominatim_endpoint : str The base API url to use for Nominatim queries. Default is `"https://nominatim.openstreetmap.org/"`. -nominatim_key : string +nominatim_key : str Your Nominatim API key, if you are using an API instance that requires one. Default is `None`. osm_xml_node_attrs : list - Node attributes for saving .osm XML files with `save_graph_xml` function. - Default is `["id", "timestamp", "uid", "user", "version", "changeset", - "lat", "lon"]`. + Do not use, deprecated. osm_xml_node_tags : list - Node tags for saving .osm XML files with `save_graph_xml` function. - Default is `["highway"]`. + Do not use, deprecated. osm_xml_way_attrs : list - Edge attributes for saving .osm XML files with `save_graph_xml` function. - Default is `["id", "timestamp", "uid", "user", "version", "changeset"]`. + Do not use, deprecated. osm_xml_way_tags : list - Edge tags for for saving .osm XML files with `save_graph_xml` function. - Default is `["highway", "lanes", "maxspeed", "name", "oneway"]`. -overpass_endpoint : string + Do not use, deprecated. +overpass_endpoint : str The base API url to use for Overpass queries. Default is `"https://overpass-api.de/api"`. +overpass_memory : int | None + Overpass server memory allocation size for the query, in bytes. If + None, server will choose its default allocation size. Use with caution. + Default is `None`. overpass_rate_limit : bool If True, check the Overpass server status endpoint for how long to pause before making request. Necessary if server uses slot management, but can be set to False if you are running your own overpass instance without rate limiting. Default is `True`. -overpass_settings : string +overpass_settings : str Settings string for Overpass queries. Default is `"[out:json][timeout:{timeout}]{maxsize}"`. By default, the {timeout} and {maxsize} values are set dynamically by OSMnx when used. @@ -117,9 +122,11 @@ a local certificate file. More info on options such as auth, cert, verify, and proxies can be found in the requests package advanced docs. Default is `{}`. -timeout : int +requests_timeout : int The timeout interval in seconds for HTTP requests, and (when applicable) - for API to use while running the query. Default is `180`. + for Overpass server to use for executing the query. Default is `180`. +timeout : int + Do not use, deprecated. Use `requests_timeout` instead. use_cache : bool If True, cache HTTP responses locally instead of calling API repeatedly for the same request. Default is `True`. @@ -140,15 +147,18 @@ cache_folder = "./cache" cache_only_mode = False data_folder = "./data" -default_accept_language = "en" +default_accept_language = None default_access = '["access"!~"private"]' default_crs = "epsg:4326" -default_referer = "OSMnx Python package (https://github.com/gboeing/osmnx)" -default_user_agent = "OSMnx Python package (https://github.com/gboeing/osmnx)" +default_referer = None +default_user_agent = None doh_url_template = "https://8.8.8.8/resolve?name={hostname}" elevation_url_template = ( "https://maps.googleapis.com/maps/api/elevation/json?locations={locations}&key={key}" ) +http_accept_language = "en" +http_referer = "OSMnx Python package (https://github.com/gboeing/osmnx)" +http_user_agent = "OSMnx Python package (https://github.com/gboeing/osmnx)" imgs_folder = "./images" log_console = False log_file = False @@ -160,15 +170,17 @@ memory = None nominatim_endpoint = "https://nominatim.openstreetmap.org/" nominatim_key = None -osm_xml_node_attrs = ["id", "timestamp", "uid", "user", "version", "changeset", "lat", "lon"] -osm_xml_node_tags = ["highway"] -osm_xml_way_attrs = ["id", "timestamp", "uid", "user", "version", "changeset"] -osm_xml_way_tags = ["highway", "lanes", "maxspeed", "name", "oneway"] +osm_xml_node_attrs = None +osm_xml_node_tags = None +osm_xml_way_attrs = None +osm_xml_way_tags = None overpass_endpoint = "https://overpass-api.de/api" +overpass_memory = None overpass_rate_limit = True overpass_settings = "[out:json][timeout:{timeout}]{maxsize}" requests_kwargs: dict = {} -timeout = 180 +requests_timeout = 180 +timeout = None use_cache = True useful_tags_node = ["ref", "highway"] useful_tags_way = [ diff --git a/tests/lint_test.sh b/tests/lint_test.sh index 9302e9ef8..d572e6bf3 100644 --- a/tests/lint_test.sh +++ b/tests/lint_test.sh @@ -12,12 +12,12 @@ find . -type f -name ".coverage*" -delete pre-commit run --all-files # test building and validating the package -hatch build --clean -twine check --strict ./dist/* +#hatch build --clean +#twine check --strict ./dist/* # build the docs -make -C ./docs html -python -m sphinx -b linkcheck ./docs/source ./docs/build/linkcheck +#make -C ./docs html +#python -m sphinx -b linkcheck ./docs/source ./docs/build/linkcheck # run the tests and report the test coverage pytest --cov=./osmnx --cov-report=term-missing --verbose From 9407a826e1f693b68242966fb77d5a4e720397a1 Mon Sep 17 00:00:00 2001 From: Geoff Boeing Date: Thu, 29 Feb 2024 20:07:50 -0800 Subject: [PATCH 2/6] deprecate settings.nominatim_endpoint and settings.overpass_endpoint --- osmnx/_nominatim.py | 12 +++++++++++- osmnx/_overpass.py | 18 ++++++++++++++---- osmnx/settings.py | 18 ++++++++++++------ 3 files changed, 37 insertions(+), 11 deletions(-) diff --git a/osmnx/_nominatim.py b/osmnx/_nominatim.py index 466814f7e..2defa0ee9 100644 --- a/osmnx/_nominatim.py +++ b/osmnx/_nominatim.py @@ -94,12 +94,22 @@ def _nominatim_request(params, request_type="search", pause=1, error_pause=60): ) warn(msg, FutureWarning, stacklevel=2) + if settings.nominatim_endpoint is None: + nominatim_endpoint = settings.nominatim_url + else: + nominatim_endpoint = settings.nominatim_endpoint + msg = ( + "`settings.nominatim_endpoint` is deprecated and will be removed in the " + "v2.0.0 release: use `settings.nominatim_url` instead" + ) + warn(msg, FutureWarning, stacklevel=2) + if request_type not in {"search", "reverse", "lookup"}: # pragma: no cover msg = 'Nominatim request_type must be "search", "reverse", or "lookup"' raise ValueError(msg) # prepare Nominatim API URL and see if request already exists in cache - url = settings.nominatim_endpoint.rstrip("/") + "/" + request_type + url = nominatim_endpoint.rstrip("/") + "/" + request_type params["key"] = settings.nominatim_key prepared_url = requests.Request("GET", url, params=params).prepare().url cached_response_json = _downloader._retrieve_from_cache(prepared_url) diff --git a/osmnx/_overpass.py b/osmnx/_overpass.py index 513eea8a8..44b929509 100644 --- a/osmnx/_overpass.py +++ b/osmnx/_overpass.py @@ -408,11 +408,21 @@ def _overpass_request(data, pause=None, error_pause=60): ) warn(msg, FutureWarning, stacklevel=2) + if settings.overpass_endpoint is None: + overpass_endpoint = settings.overpass_url + else: + overpass_endpoint = settings.overpass_endpoint + msg = ( + "`settings.overpass_endpoint` is deprecated and will be removed in the " + "v2.0.0 release: use `settings.overpass_url` instead" + ) + warn(msg, FutureWarning, stacklevel=2) + # resolve url to same IP even if there is server round-robin redirecting - _downloader._config_dns(settings.overpass_endpoint) + _downloader._config_dns(overpass_endpoint) # prepare the Overpass API URL and see if request already exists in cache - url = settings.overpass_endpoint.rstrip("/") + "/interpreter" + url = overpass_endpoint.rstrip("/") + "/interpreter" prepared_url = requests.Request("GET", url, params=data).prepare().url cached_response_json = _downloader._retrieve_from_cache(prepared_url) if cached_response_json is not None: @@ -420,7 +430,7 @@ def _overpass_request(data, pause=None, error_pause=60): # pause then request this URL if pause is None: - this_pause = _get_overpass_pause(settings.overpass_endpoint) + this_pause = _get_overpass_pause(overpass_endpoint) domain = _downloader._hostname_from_url(url) utils.log(f"Pausing {this_pause} second(s) before making HTTP POST request to {domain!r}") time.sleep(this_pause) @@ -437,7 +447,7 @@ def _overpass_request(data, pause=None, error_pause=60): # handle 429 and 504 errors by pausing then recursively re-trying request if response.status_code in {429, 504}: # pragma: no cover - this_pause = error_pause + _get_overpass_pause(settings.overpass_endpoint) + this_pause = error_pause + _get_overpass_pause(overpass_endpoint) msg = ( f"{domain!r} responded {response.status_code} {response.reason}: " f"we'll retry in {this_pause} secs" diff --git a/osmnx/settings.py b/osmnx/settings.py index 3c38fce63..aca725cca 100644 --- a/osmnx/settings.py +++ b/osmnx/settings.py @@ -85,11 +85,13 @@ memory : int Do not use, deprecated. Use `overpass_memory` instead. nominatim_endpoint : str - The base API url to use for Nominatim queries. Default is - `"https://nominatim.openstreetmap.org/"`. + Do not use, deprecated. Use `nominatim_url` instead. nominatim_key : str Your Nominatim API key, if you are using an API instance that requires one. Default is `None`. +nominatim_url : str + The base API url to use for Nominatim queries. Default is + `"https://nominatim.openstreetmap.org/"`. osm_xml_node_attrs : list Do not use, deprecated. osm_xml_node_tags : list @@ -99,8 +101,7 @@ osm_xml_way_tags : list Do not use, deprecated. overpass_endpoint : str - The base API url to use for Overpass queries. Default is - `"https://overpass-api.de/api"`. + Do not use, deprecated. Use `overpass_url` instead. overpass_memory : int | None Overpass server memory allocation size for the query, in bytes. If None, server will choose its default allocation size. Use with caution. @@ -116,6 +117,9 @@ {maxsize} values are set dynamically by OSMnx when used. To query, for example, historical OSM data as of a certain date: `'[out:json][timeout:90][date:"2019-10-28T19:20:00Z"]'`. Use with caution. +overpass_url : str + The base API url to use for Overpass queries. Default is + `"https://overpass-api.de/api"`. requests_kwargs : dict Optional keyword args to pass to the requests package when connecting to APIs, for example to configure authentication or provide a path to @@ -168,16 +172,18 @@ logs_folder = "./logs" max_query_area_size = 50 * 1000 * 50 * 1000 memory = None -nominatim_endpoint = "https://nominatim.openstreetmap.org/" +nominatim_endpoint = None nominatim_key = None +nominatim_url = "https://nominatim.openstreetmap.org/" osm_xml_node_attrs = None osm_xml_node_tags = None osm_xml_way_attrs = None osm_xml_way_tags = None -overpass_endpoint = "https://overpass-api.de/api" +overpass_endpoint = None overpass_memory = None overpass_rate_limit = True overpass_settings = "[out:json][timeout:{timeout}]{maxsize}" +overpass_url = "https://overpass-api.de/api" requests_kwargs: dict = {} requests_timeout = 180 timeout = None From 14001ca85d65f7d9a38f791c8603b946a83544b5 Mon Sep 17 00:00:00 2001 From: Geoff Boeing Date: Thu, 29 Feb 2024 20:10:34 -0800 Subject: [PATCH 3/6] dev version --- osmnx/_version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osmnx/_version.py b/osmnx/_version.py index 76f6c9552..b18086afe 100644 --- a/osmnx/_version.py +++ b/osmnx/_version.py @@ -1,3 +1,3 @@ """OSMnx package version information.""" -__version__ = "1.9.1" +__version__ = "1.9.2-dev" From 40fee9a7011a8a7d10193485b52b375d08dbad05 Mon Sep 17 00:00:00 2001 From: Geoff Boeing Date: Thu, 29 Feb 2024 20:35:44 -0800 Subject: [PATCH 4/6] fix deprecations --- osmnx/_downloader.py | 20 ++++++++++++-------- osmnx/_nominatim.py | 7 ++++--- osmnx/_overpass.py | 22 +++++++++++++--------- osmnx/elevation.py | 7 ++++--- osmnx/osm_xml.py | 20 ++++++++++++-------- 5 files changed, 45 insertions(+), 31 deletions(-) diff --git a/osmnx/_downloader.py b/osmnx/_downloader.py index 282da3c0c..7a5914edf 100644 --- a/osmnx/_downloader.py +++ b/osmnx/_downloader.py @@ -152,8 +152,9 @@ def _get_http_headers(user_agent=None, referer=None, accept_language=None): headers : dict """ if settings.default_accept_language is None: - settings.default_accept_language = settings.http_accept_language + default_accept_language = settings.http_accept_language else: + default_accept_language = settings.default_accept_language msg = ( "`settings.default_accept_language` is deprecated and will be removed " "in the v2.0.0 release: use `settings.http_accept_language` instead" @@ -161,8 +162,9 @@ def _get_http_headers(user_agent=None, referer=None, accept_language=None): warn(msg, FutureWarning, stacklevel=2) if settings.default_referer is None: - settings.default_referer = settings.http_referer + default_referer = settings.http_referer else: + default_referer = settings.default_referer msg = ( "`settings.default_referer` is deprecated and will be removed in the " "v2.0.0 release: use `settings.http_referer` instead" @@ -170,8 +172,9 @@ def _get_http_headers(user_agent=None, referer=None, accept_language=None): warn(msg, FutureWarning, stacklevel=2) if settings.default_user_agent is None: - settings.default_user_agent = settings.http_user_agent + default_user_agent = settings.http_user_agent else: + default_user_agent = settings.default_user_agent msg = ( "`settings.default_user_agent` is deprecated and will be removed in " "the v2.0.0 release: use `settings.http_user_agent` instead" @@ -179,11 +182,11 @@ def _get_http_headers(user_agent=None, referer=None, accept_language=None): warn(msg, FutureWarning, stacklevel=2) if user_agent is None: - user_agent = settings.default_user_agent + user_agent = default_user_agent if referer is None: - referer = settings.default_referer + referer = default_referer if accept_language is None: - accept_language = settings.default_accept_language + accept_language = default_accept_language headers = requests.utils.default_headers() headers.update( @@ -214,8 +217,9 @@ def _resolve_host_via_doh(hostname): resolved IP address of host, or hostname itself if resolution failed """ if settings.timeout is None: - settings.timeout = settings.requests_timeout + timeout = settings.requests_timeout else: + timeout = settings.timeout msg = ( "`settings.timeout` is deprecated and will be removed in the v2.0.0 " "release: use `settings.requests_timeout` instead" @@ -230,7 +234,7 @@ def _resolve_host_via_doh(hostname): err_msg = f"Failed to resolve {hostname!r} IP via DoH, requesting host by name" try: url = settings.doh_url_template.format(hostname=hostname) - response = requests.get(url, timeout=settings.timeout) + response = requests.get(url, timeout=timeout) data = response.json() # if we cannot reach DoH server or resolve host, return hostname itself diff --git a/osmnx/_nominatim.py b/osmnx/_nominatim.py index 2defa0ee9..8119a8dea 100644 --- a/osmnx/_nominatim.py +++ b/osmnx/_nominatim.py @@ -86,8 +86,9 @@ def _nominatim_request(params, request_type="search", pause=1, error_pause=60): response_json : dict """ if settings.timeout is None: - settings.timeout = settings.requests_timeout + timeout = settings.requests_timeout else: + timeout = settings.timeout msg = ( "`settings.timeout` is deprecated and will be removed in the v2.0.0 " "release: use `settings.requests_timeout` instead" @@ -122,11 +123,11 @@ def _nominatim_request(params, request_type="search", pause=1, error_pause=60): time.sleep(pause) # transmit the HTTP GET request - utils.log(f"Get {prepared_url} with timeout={settings.timeout}") + utils.log(f"Get {prepared_url} with timeout={timeout}") response = requests.get( url, params=params, - timeout=settings.timeout, + timeout=timeout, headers=_downloader._get_http_headers(), **settings.requests_kwargs, ) diff --git a/osmnx/_overpass.py b/osmnx/_overpass.py index 44b929509..18a9db1f6 100644 --- a/osmnx/_overpass.py +++ b/osmnx/_overpass.py @@ -124,8 +124,9 @@ def _get_overpass_pause(base_endpoint, recursive_delay=5, default_duration=60): pause : int """ if settings.timeout is None: - settings.timeout = settings.requests_timeout + timeout = settings.requests_timeout else: + timeout = settings.timeout msg = ( "`settings.timeout` is deprecated and will be removed in the " "v2.0.0 release: use `settings.requests_timeout` instead" @@ -141,7 +142,7 @@ def _get_overpass_pause(base_endpoint, recursive_delay=5, default_duration=60): response = requests.get( url, headers=_downloader._get_http_headers(), - timeout=settings.timeout, + timeout=timeout, **settings.requests_kwargs, ) status = response.text.split("\n")[4] @@ -194,8 +195,9 @@ def _make_overpass_settings(): string """ if settings.timeout is None: - settings.timeout = settings.requests_timeout + timeout = settings.requests_timeout else: + timeout = settings.timeout msg = ( "`settings.timeout` is deprecated and will be removed in the " "v2.0.0 release: use `settings.requests_timeout` instead" @@ -203,16 +205,17 @@ def _make_overpass_settings(): warn(msg, FutureWarning, stacklevel=2) if settings.memory is None: - settings.memory = settings.overpass_memory + memory = settings.overpass_memory else: + memory = settings.memory msg = ( "`settings.memory` is deprecated and will be removed in the " " v2.0.0 release: use `settings.overpass_memory` instead" ) warn(msg, FutureWarning, stacklevel=2) - maxsize = "" if settings.memory is None else f"[maxsize:{settings.memory}]" - return settings.overpass_settings.format(timeout=settings.timeout, maxsize=maxsize) + maxsize = "" if memory is None else f"[maxsize:{memory}]" + return settings.overpass_settings.format(timeout=timeout, maxsize=maxsize) def _make_overpass_polygon_coord_strs(polygon): @@ -400,8 +403,9 @@ def _overpass_request(data, pause=None, error_pause=60): response_json : dict """ if settings.timeout is None: - settings.timeout = settings.requests_timeout + timeout = settings.requests_timeout else: + timeout = settings.timeout msg = ( "`settings.timeout` is deprecated and will be removed in the " "v2.0.0 release: use `settings.requests_timeout` instead" @@ -436,11 +440,11 @@ def _overpass_request(data, pause=None, error_pause=60): time.sleep(this_pause) # transmit the HTTP POST request - utils.log(f"Post {prepared_url} with timeout={settings.timeout}") + utils.log(f"Post {prepared_url} with timeout={timeout}") response = requests.post( url, data=data, - timeout=settings.timeout, + timeout=timeout, headers=_downloader._get_http_headers(), **settings.requests_kwargs, ) diff --git a/osmnx/elevation.py b/osmnx/elevation.py index 2e700326b..b654b25ae 100644 --- a/osmnx/elevation.py +++ b/osmnx/elevation.py @@ -294,8 +294,9 @@ def _elevation_request(url, pause): response_json : dict """ if settings.timeout is None: - settings.timeout = settings.requests_timeout + timeout = settings.requests_timeout else: + timeout = settings.timeout msg = ( "`settings.timeout` is deprecated and will be removed in the v2.0.0 " "release: use `settings.requests_timeout` instead" @@ -313,10 +314,10 @@ def _elevation_request(url, pause): time.sleep(pause) # transmit the HTTP GET request - utils.log(f"Get {url} with timeout={settings.timeout}") + utils.log(f"Get {url} with timeout={timeout}") response = requests.get( url, - timeout=settings.timeout, + timeout=timeout, headers=_downloader._get_http_headers(), **settings.requests_kwargs, ) diff --git a/osmnx/osm_xml.py b/osmnx/osm_xml.py index bcdedd549..f13ef34d7 100644 --- a/osmnx/osm_xml.py +++ b/osmnx/osm_xml.py @@ -238,7 +238,7 @@ def _save_graph_xml( # noqa: C901 None """ if settings.osm_xml_node_attrs is None: - settings.osm_xml_node_attrs = [ + osm_xml_node_attrs = [ "id", "timestamp", "uid", @@ -249,6 +249,7 @@ def _save_graph_xml( # noqa: C901 "lon", ] else: + osm_xml_node_attrs = settings.osm_xml_node_attrs msg = ( "`settings.osm_xml_node_attrs` is deprecated and will be removed " "in the v2.0.0 release" @@ -256,8 +257,9 @@ def _save_graph_xml( # noqa: C901 warn(msg, FutureWarning, stacklevel=2) if settings.osm_xml_node_tags is None: - settings.osm_xml_node_tags = ["highway"] + osm_xml_node_tags = ["highway"] else: + osm_xml_node_tags = settings.osm_xml_node_tags msg = ( "`settings.osm_xml_node_tags` is deprecated and will be removed " "in the v2.0.0 release" @@ -265,8 +267,9 @@ def _save_graph_xml( # noqa: C901 warn(msg, FutureWarning, stacklevel=2) if settings.osm_xml_way_attrs is None: - settings.osm_xml_way_attrs = ["id", "timestamp", "uid", "user", "version", "changeset"] + osm_xml_way_attrs = ["id", "timestamp", "uid", "user", "version", "changeset"] else: + osm_xml_way_attrs = settings.osm_xml_way_attrs msg = ( "`settings.osm_xml_way_attrs` is deprecated and will be removed " "in the v2.0.0 release" @@ -274,13 +277,14 @@ def _save_graph_xml( # noqa: C901 warn(msg, FutureWarning, stacklevel=2) if settings.osm_xml_way_tags is None: - settings.osm_xml_way_tags = ["highway", "lanes", "maxspeed", "name", "oneway"] + osm_xml_way_tags = ["highway", "lanes", "maxspeed", "name", "oneway"] else: + osm_xml_way_tags = settings.osm_xml_way_tags msg = "`settings.osm_xml_way_tags` is deprecated and will be removed in the v2.0.0 release" warn(msg, FutureWarning, stacklevel=2) if node_tags is None: - node_tags = settings.osm_xml_node_tags + node_tags = osm_xml_node_tags else: msg = ( "the `node_tags` parameter is deprecated and will be removed in the v2.0.0 release: " @@ -289,13 +293,13 @@ def _save_graph_xml( # noqa: C901 warn(msg, FutureWarning, stacklevel=2) if node_attrs is None: - node_attrs = settings.osm_xml_node_attrs + node_attrs = osm_xml_node_attrs else: msg = "the `node_attrs` parameter is deprecated and will be removed in the v2.0.0 release" warn(msg, FutureWarning, stacklevel=2) if edge_tags is None: - edge_tags = settings.osm_xml_way_tags + edge_tags = osm_xml_way_tags else: msg = ( "the `edge_tags` parameter is deprecated and will be removed in the v2.0.0 release: " @@ -304,7 +308,7 @@ def _save_graph_xml( # noqa: C901 warn(msg, FutureWarning, stacklevel=2) if edge_attrs is None: - edge_attrs = settings.osm_xml_way_attrs + edge_attrs = osm_xml_way_attrs else: msg = "the `edge_attrs` parameter is deprecated and will be removed in the v2.0.0 release" warn(msg, FutureWarning, stacklevel=2) From 0e77fbee6e9fdbca0a5c6ae4b2ddf22f5c714a18 Mon Sep 17 00:00:00 2001 From: Geoff Boeing Date: Thu, 29 Feb 2024 20:38:13 -0800 Subject: [PATCH 5/6] update changelog --- CHANGELOG.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a91612711..35dc767d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,9 +2,9 @@ ## 1.9.2 (TBD) -- deprecate settings module's default_accept_language, default_referer, default_user_agent, memory, and timeout settings -- deprecate settings module's osm_xml_node_attrs, osm_xml_node_tags, osm_xml_way_attrs, and osm_xml_way_tags settings -- deprecate save_graph_xml function's node_tags, node_attrs, edge_tags, edge_attrs, edge_tag_aggs, merge_edges, oneway, api_version, and precision parameters +- deprecate settings module's default_accept_language, default_referer, default_user_agent, memory, nominatim_endpoint, overpass_endpoint, and timeout settings (#1138) +- deprecate settings module's osm_xml_node_attrs, osm_xml_node_tags, osm_xml_way_attrs, and osm_xml_way_tags settings (#1138) +- deprecate save_graph_xml function's node_tags, node_attrs, edge_tags, edge_attrs, edge_tag_aggs, merge_edges, oneway, api_version, and precision parameters (#1138) ## 1.9.1 (2024-02-01) From d22444a72e432f9e0a3d6abe223be66fba728854 Mon Sep 17 00:00:00 2001 From: Geoff Boeing Date: Thu, 29 Feb 2024 20:54:29 -0800 Subject: [PATCH 6/6] params are deprecated because function is deprecated --- osmnx/osm_xml.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/osmnx/osm_xml.py b/osmnx/osm_xml.py index f13ef34d7..b30a671bc 100644 --- a/osmnx/osm_xml.py +++ b/osmnx/osm_xml.py @@ -130,7 +130,7 @@ def save_graph_xml( Parameters ---------- data : networkx.MultiDiGraph - the input graph + do not use, deprecated filepath : string or pathlib.Path do not use, deprecated node_tags : list @@ -152,11 +152,7 @@ def save_graph_xml( precision : int do not use, deprecated way_tag_aggs : dict - Keys are OSM way tag keys and values are aggregation functions - (anything accepted as an argument by pandas.agg). Allows user to - aggregate graph edge attribute values into single OSM way values. If - None, or if some tag's key does not exist in the dict, the way - attribute will be assigned the value of the first edge of the way. + do not use, deprecated Returns -------