class_docstr: Represents a resource, that can be configured easily, which knows
  how to acquire itself (perhaps via HTTP).
  
  The key interface method is :meth:`path` - typically *all* external calls
  will be made to that method. To get hold of an appropriate
  :class:`Downloader` instance the :func:`Downloader.from_config` static
  method should be considered.
  
  Parameters
  ----------
  url_template
      The template of the full URL representing this
      resource.
  
  target_path_template
      The template of the full path to the file
      that this Downloader represents. Typically the path will be a
      subdirectory of ``config['data_dir']``, but this is not a strict
      requirement. If the file does not exist when calling
      :meth:`Downloader.path` it will be downloaded to this location.
  
  pre_downloaded_path_template: optional
      The template of a full path of a file which has been downloaded
      outside of this Downloader which should be used as the file that
      this resource represents. If the file does not exist when
      :meth:`Downloader.path` is called it will not be downloaded
      to this location (unlike the ``target_path_template`` argument).
  
  Note
  ----
      All ``*_template`` arguments should be formattable using the
      standard :meth:`string.format` rules. The formatting itself
      is not done until a call to a subsequent method (such as
      :meth:`Downloader.path`).
docstr: The ``from_config`` static method implements the logic for acquiring a
  Downloader (sub)class instance from the config dictionary.
  
  Parameters
  ----------
  specification
      Should be iterable, as it will be traversed in
      reverse order to find the most appropriate Downloader instance
      for this specification.  An example specification is
      ``('shapefiles', 'natural_earth')`` for the Natural Earth
      shapefiles.
  config_dict: optional
      typically this is left as None to use the
      default ``cartopy.config`` "downloaders" dictionary.
  
  Examples
  --------
  
  >>> from cartopy.io import Downloader
  >>>
  >>> dnldr = Downloader('https://example.com/{name}', './{name}.txt')
  >>> config = {('level_1', 'level_2'): dnldr}
  >>> d1 = Downloader.from_config(('level_1', 'level_2', 'level_3'),
  ...                             config_dict=config)
  >>> print(d1.url_template)
  https://example.com/{name}
  >>> print(d1.url({'name': 'item_name'}))
  https://example.com/item_name
docstr_tok: ["The","``","from_config","``","static","method","implements","the","logic","for","acquiring","a","Downloader","(","sub",")","class","instance","from","the","config","dictionary",".","Parameters","--","--","--","--","--","specification","Should","be","iterable",",","as","it","will","be","traversed","in","reverse","order","to","find","the","most","appropriate","Downloader","instance","for","this","specification",".","An","example","specification","is","``","(","'shapefiles","'",",","'natural_earth","'",")","``","for","the","Natural","Earth","shapefiles",".","config_dict",":","optional","typically","this","is","left","as","None","to","use","the","default","``","cartopy.config","``","``","downloaders","''","dictionary",".","Examples","--","--","--","--",">",">",">","from","cartopy.io","import","Downloader",">",">",">",">",">",">","dnldr","=","Downloader","(","'https",":","\/\/example.com\/","{","name","}","'",",","'.\/","{","name","}",".txt","'",")",">",">",">","config","=","{","(","'level_1","'",",","'level_2","'",")",":","dnldr","}",">",">",">","d1","=","Downloader.from_config","(","(","'level_1","'",",","'level_2","'",",","'level_3","'",")",",","...","config_dict=config",")",">",">",">","print","(","d1.url_template",")","https",":","\/\/example.com\/","{","name","}",">",">",">","print","(","d1.url","(","{","'name","'",":","'item_name","'","}",")",")","https",":","\/\/example.com\/item_name"]
code: def from_config(specification, config_dict=None):
      """
      The ``from_config`` static method implements the logic for acquiring a
      Downloader (sub)class instance from the config dictionary.
  
      Parameters
      ----------
      specification
          Should be iterable, as it will be traversed in
          reverse order to find the most appropriate Downloader instance
          for this specification.  An example specification is
          ``('shapefiles', 'natural_earth')`` for the Natural Earth
          shapefiles.
      config_dict: optional
          typically this is left as None to use the
          default ``cartopy.config`` "downloaders" dictionary.
  
      Examples
      --------
  
      >>> from cartopy.io import Downloader
      >>>
      >>> dnldr = Downloader('https://example.com/{name}', './{name}.txt')
      >>> config = {('level_1', 'level_2'): dnldr}
      >>> d1 = Downloader.from_config(('level_1', 'level_2', 'level_3'),
      ...                             config_dict=config)
      >>> print(d1.url_template)
      https://example.com/{name}
      >>> print(d1.url({'name': 'item_name'}))
      https://example.com/item_name
  
      """
      spec_depth = len(specification)
      if config_dict is None:
          downloaders = config["downloaders"]
      else:
          downloaders = config_dict
  
      result_downloader = None
  
      for i in range(spec_depth, 0, -1):
          lookup = specification[:i]
          downloadable_item = downloaders.get(lookup, None)
          if downloadable_item is not None:
              result_downloader = downloadable_item
              break
  
      if result_downloader is None:
          # should never really happen, but could if the user does
          # some strange things like not having any downloaders defined
          # in the config...
          raise ValueError(
              "No generic downloadable item in the config "
              f"dictionary for {specification}"
          )
  
      return result_downloader
  
imports: import collections
  from pathlib import Path
  import string
  from urllib.request import urlopen
  import warnings
  from cartopy import config
label_desc: Use image node_id 8 for calling the Downloader obj's underlying member method code with example usage: obj.from_config(specification, config_dict) and returns: result_downloader