naturtag package


naturtag.atlas module

naturtag.cli module

naturtag.constants module

naturtag.image_glob module

naturtag.image_glob.get_images_from_dir(dir: str, recursive: bool = False)List[str][source]

Get all images of supported filetypes from the selected directory.

  • dir – Path to image directory

  • recursive – Recursively get images from subdirectories


Paths of supported image files in the directory

naturtag.image_glob.get_images_from_paths(paths: Union[str, List[str]], recursive: bool = False)List[str][source]

Get all images of supported filetypes from one or more dirs and/or image paths

  • paths – Paths to images and/or image directories

  • recursive – Recursively get images from subdirectories


Combined list of image file paths

naturtag.image_glob.glob_paths(path_patterns: List[str])List[str][source]

Given one to many glob patterns, expand all into a list of matching files


path_patterns – Glob patterns


Expanded list of file paths

naturtag.image_glob.is_image_path(path: str)bool[source]

Determine if a path points to a valid image of a supported type

naturtag.inat_metadata module

Tools to get keyword tags (e.g., for XMP metadata) from iNaturalist observations

naturtag.inat_metadata.convert_dwc_to_xmp(dwc: str)Dict[str, str][source]

Get all DWC terms from XML content containing a SimpleDarwinRecordSet, and format them as XMP tags. For example: 'dwc:species' -> 'Xmp.dwc.species'

naturtag.inat_metadata.get_common_keywords(taxa: List[Dict])List[str][source]

Format a list of taxa into common name keywords. Filters out terms that aren’t useful to keep as tags

naturtag.inat_metadata.get_hierarchical_keywords(keywords: List)List[str][source]

Get the current size of the HTTP request cache, in human-readable format

naturtag.inat_metadata.get_ids_from_url(value: str)Tuple[Optional[int], Optional[int]][source]

If a URL is provided containing an ID, return the taxon and/or observation ID. If it’s an observation, fetch its taxon ID as well.


taxon_id, observation_id


Look for taxon and/or observation IDs from metadata if available

naturtag.inat_metadata.get_keywords(observation_id: Optional[int] = None, taxon_id: Optional[int] = None, common: bool = False, hierarchical: bool = False)List[str][source]

Get all taxonomic keywords for a given observation or taxon

naturtag.inat_metadata.get_min_rank(metadata: Dict[str, str])Tuple[Optional[str], Optional[str]][source]

Get the lowest (most specific) taxonomic rank from tags, if any

naturtag.inat_metadata.get_observation_dwc_terms(observation_id: int)Dict[str, str][source]

Get all DWC terms for an iNaturalist observation

naturtag.inat_metadata.get_observation_from_metadata(metadata)Tuple[Dict, Dict][source]
naturtag.inat_metadata.get_observation_taxon(observation_id: int)int[source]

Get the current taxon ID for the given observation

naturtag.inat_metadata.get_observed_taxa(username: str, include_casual: bool = False)Dict[int, int][source]

Get counts of taxa observed by the user, ordered by number of observations descending

naturtag.inat_metadata.get_rank_idx(rank: str)int[source]
naturtag.inat_metadata.get_taxon_ancestors(taxon_id: int)List[Dict][source]

Get a taxon’s parents

naturtag.inat_metadata.get_taxon_and_obs_from_metadata(metadata)Tuple[Dict, Dict][source]
naturtag.inat_metadata.get_taxon_children(taxon_id: int)List[Dict][source]

Get a taxon’s children

naturtag.inat_metadata.get_taxon_dwc_terms(taxon_id: int)Dict[str, str][source]

Get all DWC terms for an iNaturalist taxon. Since there is no DWC format for GET /taxa, we’ll just search for a random observation with this taxon ID, strip off the observation metadata, and keep only the taxon metadata.


Fetch taxon record from MetaMetadata object: either by ID or rank + name

naturtag.inat_metadata.get_taxon_with_ancestors(taxon_id: int)List[Dict][source]

Get a taxon with all its parents

naturtag.inat_metadata.get_taxonomy_keywords(taxa: List[Dict])List[str][source]

Format a list of taxa into rank keywords

naturtag.inat_metadata.quote(s: str)str[source]

Surround keyword in quotes if it contains whitespace

naturtag.inat_metadata.sort_taxonomy_keywords(keywords: List[str])List[str][source]

Sort keywords by taxonomic rank, where applicable

naturtag.inat_metadata.strip_url(value: str)Optional[int][source]

If a URL is provided containing an ID, return just the ID

naturtag.settings module

Basic utilities for reading and writing settings from config files

naturtag.settings.read_settings()Dict[str, Any][source]

Read settings from the settings file


Stored config state


Read taxon view history, starred, and frequency


Stored taxon view history, starred, and frequency


Reset settings to defaults

naturtag.settings.write_settings(new_config: Dict[str, Any])[source]

Write updated settings to the settings file


new_config (dict) – Updated config state

naturtag.settings.write_stored_taxa(stored_taxa: Dict)[source]

Write taxon view history to file, along with stats on most frequently viewed taxa


taxon history (Complete) –

naturtag.tagger module

naturtag.thumbnails module

Utilities for generating and retrieving image thumbnails


Delete call cached thumbnails

naturtag.thumbnails.flip_all(path: str)[source]

Vertically flip all images in a directory. Mainly for debugging purposes.

naturtag.thumbnails.generate_thumbnail(source: Union[BinaryIO, str], thumbnail_path: str, fmt: Optional[str] = None, size: str = 'medium', default_flip: bool = True)[source]

Generate and store a thumbnail from the source image

  • source (str) – File path or URI for image source

  • thumbnail_path (str) – Destination path for thumbnail

  • fmt (str) – Image format to specify to PIL, if it can’t be auto-detected

  • size (str) – One of: ‘small’, ‘medium’, ‘large’


The path of the new thumbnail

Return type


naturtag.thumbnails.generate_thumbnail_from_bytes(image_bytes, source: str, **kwargs)[source]

Like generate_thumbnail(), but takes raw image bytes instead of a path

naturtag.thumbnails.generate_thumbnail_from_url(url: str, size: str)[source]

Like generate_thumbnail(), but downloads an image from a URL

naturtag.thumbnails.get_format(source: str)str[source]

Account for various edge cases when getting an image format based on a file extension


source – File path or URI for image source


Format, if found; otherwise, defaults to jpg

naturtag.thumbnails.get_orientated_image(source, default_flip: bool = True)<module ‘PIL.Image’ from ‘/home/docs/checkouts/’>[source]

Load and rotate/transpose image according to EXIF orientation, if any. If missing orientation and the image was fetched from iNat, it will be vertically mirrored. (?)

naturtag.thumbnails.get_thumbnail(source: str, **kwargs)str[source]

Get a cached thumbnail for an image, if one already exists; otherwise, generate a new one. See generate_thumbnail() for size options.


source – File path or URI for image source


Path to thumbnail image

naturtag.thumbnails.get_thumbnail_cache_size()Tuple[int, str][source]

Get the current size of the thumbnail cache, in number of files and human-readable total file size

naturtag.thumbnails.get_thumbnail_hash(source: str)str[source]

Get a unique string based on the source to use as a filename or atlas resource ID

naturtag.thumbnails.get_thumbnail_if_exists(source: str)Optional[str][source]

Get a cached thumbnail for an image, if one already exists, but if not, don’t generate a new one


source – File path or URI for image source


The path of the new thumbnail, if found; otherwise None

naturtag.thumbnails.get_thumbnail_path(source: str)str[source]

Determine the thumbnail filename based on a hash of the original file path


source – File path or URI for image source

naturtag.thumbnails.get_thumbnail_size(size: str)Tuple[int, int][source]

Get one of the predefined thumbnail dimensions from a size string


size – One of: ‘small’, ‘medium’, ‘large’


X and Y dimensions of thumbnail size

naturtag.thumbnails.to_monochrome(source, fmt)[source]

Convert an image to monochrome

naturtag.ui module

naturtag.validation module

Type conversion, validation, and formatting utilities

naturtag.validation.convert_coord_pair(value: str)Optional[Tuple[float, float]][source]
naturtag.validation.convert_float(value: Any)Optional[float][source]

Convert a value to a float, if valid; return None otherwise

naturtag.validation.convert_int_dict(int_dict)Dict[int, int][source]

Convert JSON string keys to ints

naturtag.validation.format_const(value: str)str[source]
naturtag.validation.format_dimensions(dimensions: Union[Tuple[int, int], Dict[str, int]])Tuple[int, int][source]

Slightly simplify ‘dimensions’ response attribute into (width, height) tuple


Convert a file size in bytes into a human-readable format

naturtag.validation.is_expired(timestamp, expiry_hours)[source]

Determine if a timestamp is older than a given expiration length