### Setup Development Environment with venv Source: https://github.com/fraymio/modis-tools/blob/main/README.md Create and activate a virtual environment using venv, then install project dependencies from requirements.txt. ```bash python -m venv .venv source .venv/bin/activate pip install -r requirements.txt ``` -------------------------------- ### Install pre-commit Source: https://github.com/fraymio/modis-tools/blob/main/README.md Install the pre-commit tool using pip. This is used to format code before committing. ```bash pip install pre-commit ``` -------------------------------- ### Regular Use of ModisSession After Setup Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/api-reference/auth-functions.md Demonstrates creating `ModisSession` and associated clients after initial setup, without needing to pass credentials explicitly. ```python from modis_tools.auth import ModisSession from modis_tools.resources import CollectionApi, GranuleApi # No need to pass credentials session = ModisSession() collection_client = CollectionApi(session=session) granule_client = GranuleApi(session=session) ``` -------------------------------- ### Install Multiple Extra Dependencies Source: https://github.com/fraymio/modis-tools/blob/main/README.md Install multiple extra dependency sets, such as 'test' and 'gdal', by separating them with a comma. ```python pip install -e .[test,gdal] ``` -------------------------------- ### Install Production Dependencies Source: https://github.com/fraymio/modis-tools/blob/main/README.md Install all production dependencies for the project using pip. ```python pip install -r requirements.txt ``` -------------------------------- ### Install Modis-Tools Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/README.md Install the modis-tools package using pip. ```bash pip install modis-tools ``` -------------------------------- ### Download Granules with Specific Extensions Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/configuration.md Example of specifying a single file extension for downloads. ```python ext="hdf" ``` -------------------------------- ### ModisSession Constructor Examples Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/api-reference/ModisSession.md Demonstrates how to instantiate ModisSession using username and password, reading from a .netrc file, or as a context manager. ```python from modis_tools.auth import ModisSession # Using username and password session = ModisSession(username="myuser", password="mypass") # Or from .netrc file session = ModisSession() # Using as context manager with ModisSession(username="user", password="pass") as authenticated_session: # Use authenticated_session for requests pass ``` -------------------------------- ### Download Granules with Multiple Priority Extensions Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/configuration.md Example of specifying multiple file extensions in priority order for downloads. ```python ext=("hdf", "h5", "nc") ``` -------------------------------- ### Querying Granules Source: https://github.com/fraymio/modis-tools/blob/main/README.md Demonstrates how to query for granules using the GranuleApi, with examples of time and limit parameters. ```APIDOC ## Querying Granules ### Description This snippet shows how to use the `GranuleApi` to search for granules. You can specify various query parameters, including time ranges and a limit for the number of results. ### Method `GranuleApi.query()` ### Parameters - **start_date** (datetime, string, dict, tuple) - Optional - The start date for the granule query. - **limit** (integer) - Optional - The maximum number of granules to return. ### Request Example ```python # Assuming granule_client is already initialized and potentially filtered by collection granules = granule_client.query(start_date="2019-02-02", limit=50) ``` ### Response Returns a generator yielding matching granule objects. ``` -------------------------------- ### Date Format Examples Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/quick-reference.md Illustrates various equivalent formats for representing dates, including `datetime` objects, strings, tuples, and dictionaries. Also shows examples of `timedelta` for date differences. ```python # All equivalent for start_date/end_date start = datetime(2016, 1, 1) start = "2016-01-01" start = (2016, 1, 1) start = {"year": 2016, "month": 1, "day": 1} # Time delta examples time_delta = timedelta(365) time_delta = 365 # days is default time_delta = {"weeks": 52, "days": 1} ``` -------------------------------- ### Perform a GET Request to a Resource Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/api-reference/ModisApi.md Use the `get` property to make a GET request to the configured resource URL. This example retrieves MODIS collections based on a short name. ```python api = ModisApi(username="user", password="pass") api.resource = "collections" response = api.get(params={"short_name": "MOD13A1"}) ``` -------------------------------- ### Install modis-tools Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/quick-reference.md Install the modis-tools package using pip. Optional dependencies for GDAL/OGR geometry support and testing can be installed with extras. ```bash pip install modis-tools ``` ```bash pip install -e ".[gdal]" # For GDAL/OGR geometry support ``` ```bash pip install -e ".[gdal,test]" # For both GDAL and testing ``` -------------------------------- ### Example Granule API Query with CMR Parameters Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/configuration.md This example demonstrates how to query granules using specific filters like instrument, platform, and cloud cover. It also shows how to pass additional CMR API parameters using dictionary unpacking for bracket notation. ```python granules = granule_client.query( start_date="2016-01-01", instrument="MODIS", platform="Aqua", cloud_cover="[0,50]", **{"options[science_keywords][0][category]": "ATMOSPHERE"} ) ``` -------------------------------- ### Basic Modis-Tools Workflow Example Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/README.md Demonstrates authenticating with Earthdata, finding a collection, querying granules within a date range and bounding box, and downloading the granules. Uses all available CPU cores for downloading. ```python from modis_tools.auth import ModisSession from modis_tools.resources import CollectionApi, GranuleApi from modis_tools.granule_handler import GranuleHandler # Authenticate session = ModisSession(username="user", password="pass") # Find a collection collections = CollectionApi(session=session).query( short_name="MOD13A1", version="061" ) # Query granules for a region and date range granule_client = GranuleApi.from_collection(collections[0], session=session) granules = granule_client.query( start_date="2016-01-01", end_date="2016-12-31", bounding_box=[2.14, 4.00, 15.29, 14.27] ) # Download all granules file_paths = GranuleHandler.download_from_granules( granules, modis_session=session, threads=-1 # Use all CPU cores ) ``` -------------------------------- ### DateParams example: With datetime objects and time_delta Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/api-reference/request-helpers.md Demonstrates initializing DateParams with explicit datetime objects for the start date and a time delta, then converting to CMR format. ```python # With datetime objects from datetime import datetime start = datetime(2016, 1, 1, 12, 30, 45) params = DateParams(start_date=start, time_delta=30) print(params.to_dict()) # {"temporal": "2016-01-01T12:30:45Z,2016-01-31T12:30:45Z"} ``` -------------------------------- ### Install Development Dependencies for Testing Source: https://github.com/fraymio/modis-tools/blob/main/README.md Install development dependencies, including testing tools, using pip in editable mode. ```python pip install -e .[test] ``` -------------------------------- ### DateParams example: Using time_delta Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/api-reference/request-helpers.md Shows how to use `time_delta` to automatically calculate the end date when only the start date is provided. ```python # Using time_delta params = DateParams(start_date="2016-01-01", time_delta=365) print(params.end_date) # 2017-01-01 00:00:00 ``` -------------------------------- ### Initial Setup for ModisSession Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/api-reference/auth-functions.md Stores Earthdata credentials in the ~/.netrc file for future use, allowing `ModisSession` to be created without explicit username and password. ```python from modis_tools.auth import add_earthdata_netrc, ModisSession # Store credentials for future use (one-time) add_earthdata_netrc(username="myuser", password="mypass") ``` -------------------------------- ### Example Usage: Bounding Box Query Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/api-reference/request-helpers.md Demonstrates creating a SpatialQuery object with a bounding box tuple and printing its CMR API dictionary representation. ```python from modis_tools.request_helpers import SpatialQuery # Bounding box query bbox = (2.1448863675, 4.002583177, 15.289420717, 14.275061098) query = SpatialQuery(bounding_box=bbox) print(query.to_dict()) # {"bounding_box": "2.1448863675,4.002583177,15.289420717,14.275061098"} ``` -------------------------------- ### One-time .netrc Setup Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/configuration.md Configures Earthdata login credentials in a .netrc file for persistent authentication. Subsequent uses do not require explicit credential passing. ```python # One-time setup from modis_tools.auth import add_earthdata_netrc add_earthdata_netrc(username="user", password="pass") # Subsequent use: no credentials needed from modis_tools.auth import ModisSession session = ModisSession() ``` -------------------------------- ### Efficient Data Downloading with Modis-Tools Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/quick-reference.md This example demonstrates how to efficiently download granules by reusing a ModisSession and querying collections. It utilizes generators, limits results per year, and enables parallel downloads using `threads=-1`. Ensure you have a valid username and password for `ModisSession`. ```python session = ModisSession(username="user", password="pass") # Collection query (cheap) collection_client = CollectionApi(session=session) collections = collection_client.query(short_name="MOD13A1", version="061") # Reuse session and collection for multiple granule queries for year in range(2010, 2021): granule_client = GranuleApi.from_collection(collections[0], session=session) granules = granule_client.query( start_date=f"{year}-01-01", end_date=f"{year}-12-31", limit=50 ) files = GranuleHandler.download_from_granules(granules, session, threads=-1) ``` -------------------------------- ### Complete Flow Example with GranuleApi Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/api-reference/decorators.md Shows a full execution flow where `GranuleApi.query` is called with specific date and spatial parameters, demonstrating how the `@params_args` decorator internally processes these into the `params` argument for the API request. ```python from modis_tools.resources import GranuleApi from modis_tools.auth import ModisSession session = ModisSession(username="user", password="pass") client = GranuleApi(session=session) # Call query with date and spatial parameters granules = client.query( start_date="2016-01-01", end_date="2016-12-31", bounding_box=(2.14, 4.00, 15.29, 14.27), limit=50 ) # Internally, the decorator: # 1. Creates DateParams(start_date="2016-01-01", end_date="2016-12-31") # 2. Creates SpatialQuery(bounding_box=(2.14, 4.00, 15.29, 14.27)) # 3. Converts to dicts and merges into params # 4. Calls the actual query method with processed params ``` -------------------------------- ### Handle No File Content Error During Download Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/errors.md This example shows how to handle cases where a downloaded file is empty or has a Content-Length of 1 byte or less. It suggests checking credentials or file availability. ```python from modis_tools.granule_handler import GranuleHandler from modis_tools.auth import ModisSession session = ModisSession(username="user", password="pass") try: file_paths = GranuleHandler.download_from_granules( granules, session ) except FileNotFoundError as e: print(f"Download failed: {e}") # May indicate expired credentials or deleted file ``` -------------------------------- ### ModisSession as Context Manager Example Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/api-reference/ModisSession.md Shows how to use ModisSession within a 'with' statement to make authenticated requests to NASA Earthdata APIs. ```python with ModisSession(username="user", password="pass") as session: # Use session to make authenticated requests response = session.get("https://cmr.earthdata.nasa.gov/search/collections.json") ``` -------------------------------- ### Initialize DateParams with dictionary Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/api-reference/request-helpers.md Initialize DateParams using a dictionary of keyword arguments for the datetime constructor for the start date. ```python DateParams(start_date={"year": 2016, "month": 1, "day": 1}) ``` -------------------------------- ### .netrc File Format Example Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/api-reference/auth-functions.md Illustrates the standard netrc file format used for storing machine-readable login information, including machine, login, and password. ```text machine urs.earthdata.nasa.gov login myusername password mypassword ``` -------------------------------- ### Spatial Query Examples Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/quick-reference.md Demonstrates different ways to represent spatial data for queries, including bounding boxes, Shapely geometries, GeoJSON, GeoDataFrames, and OGR Geometries. ```python # Bounding box (xmin, ymin, xmax, ymax) bbox = (2.14, 4.00, 15.29, 14.27) # Shapely geometry from shapely.geometry import Polygon, Point polygon = Polygon([...]) point = Point(0, 0) # GeoJSON dict geojson = { "type": "Polygon", "coordinates": [[[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]]] } # GeoDataFrame (GeoPandas) gdf = gpd.read_file("file.geojson") geom = gdf.geometry[0] # OGR Geometry (GDAL) ds = ogr.Open("file.geojson") feature = ds.GetLayer().GetNextFeature() geometry = feature.geometry() ``` -------------------------------- ### Example Usage: GeoJSON Point Geometry Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/api-reference/request-helpers.md Demonstrates creating a SpatialQuery object with a GeoJSON Point dictionary and printing its CMR API dictionary representation. ```python from modis_tools.request_helpers import SpatialQuery geom_dict = { "type": "Point", "coordinates": [0.5, 0.5] } query = SpatialQuery(spatial=geom_dict) print(query.to_dict()) # {"point": "0.5,0.5"} ``` -------------------------------- ### Parameter Filtering Example Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/api-reference/decorators.md Illustrates how arguments matching a RequestsArg's __init__ signature are extracted and removed from kwargs, while others are passed through. ```python # DateParams.__init__ signature includes: start_date, end_date, time_delta # These are extracted and removed from **fkwargs # Other kwargs remain and are passed through query( start_date="2016-01-01", # Extracted for DateParams limit=50, # Not in DateParams, passed through other_param="value" # Passed through ) ``` -------------------------------- ### Query MODIS Collections Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/types.md Example of how to query MODIS collections using the CollectionApi. This snippet demonstrates initializing a ModisSession and CollectionApi, then querying for collections by short name and version. ```python from modis_tools.resources import CollectionApi from modis_tools.auth import ModisSession session = ModisSession(username="user", password="pass") client = CollectionApi(session=session) collections = client.query(short_name="MOD13A1", version="061") for collection in collections: print(f"ID: {collection.id}") print(f"Short Name: {collection.short_name}") print(f"Version: {collection.version_id}") print(f"Title: {collection.title}") print(f"Summary: {collection.summary}") ``` -------------------------------- ### Example Usage: Shapely Polygon Geometry Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/api-reference/request-helpers.md Demonstrates creating a SpatialQuery object with a Shapely Polygon and printing its CMR API dictionary representation. ```python from modis_tools.request_helpers import SpatialQuery from shapely.geometry import Polygon geom = Polygon([ (0, 0), (1, 0), (1, 1), (0, 1), (0, 0) ]) query = SpatialQuery(spatial=geom) print(query.to_dict()) # {"polygon": "0,0,1,0,1,1,0,1,0,0"} ``` -------------------------------- ### Default Download Parameters Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/configuration.md Specifies default parameters for granule downloads, such as filtering for downloadable products, setting a maximum page size, and sorting by start date. ```python { "downloadable": "true", # Only downloadable products "page_size": 2000, # CMR max page size "sort_key": "-start_date", # Newest first } ``` -------------------------------- ### Get time delta from DateParams Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/api-reference/request-helpers.md Access the read-only `time_delta` property of a DateParams object to get the calculated difference between start and end dates. ```python params = DateParams(start_date="2016-01-01", end_date="2016-12-31") print(params.time_delta) # timedelta(364) ``` -------------------------------- ### DateParams example: Open-ended range Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/api-reference/request-helpers.md Illustrates creating an open-ended date range by providing only the start date and converting it to CMR API format. ```python # Open-ended params = DateParams(start_date="2016-01-01") print(params.time_delta) # None print(params.to_dict()) # {"temporal": "2016-01-01T00:00:00Z,"} ``` -------------------------------- ### Authentication using .netrc File Source: https://github.com/fraymio/modis-tools/blob/main/README.md Explains how to configure authentication using a ~/.netrc file, allowing client initialization without explicit credentials. ```APIDOC ## Authentication using .netrc File ### Description This snippet shows how to set up authentication using an Earthdata entry in your `~/.netrc` file. Once configured, you can create API clients without explicitly providing your username and password. ### Setup ```python from modis_tools.auth import add_earthdata_netrc, remove_earthdata_netrc username = "your_username" password = "your_password" # Add Earthdata credentials to ~/.netrc (run once) add_earthdata_netrc(username, password) ``` ### Usage ```python from modis_tools.auth import ModisSession, remove_earthdata_netrc from modis_tools.resources import GranuleApi # Sessions and clients can now be created without explicit credentials session = ModisSession() granule_client = GranuleApi() # Optional: Remove Earthdata credentials from ~/.netrc # remove_earthdata_netrc() ``` ``` -------------------------------- ### Change API Response MIME Type Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/api-reference/ModisApi.md Modify the `mime_type` property to change the format of API responses. This example sets the MIME type to XML and then performs a GET request. ```python api.mime_type = "xml" response = api.get() # Returns XML response ``` -------------------------------- ### Install GDAL Extra Dependency Source: https://github.com/fraymio/modis-tools/blob/main/README.md Install the GDAL extra dependency for spatial querying capabilities using ogr.Geometry objects. Assumes GDAL libraries are already installed. ```python pip install -e .[gdal] ``` -------------------------------- ### Upload to PyPI Source: https://github.com/fraymio/modis-tools/blob/main/README.md Upload the distribution files to the main PyPI repository. Use '__token__' as username and an API token as password if MFA is enabled. ```bash twine upload dist/* ``` -------------------------------- ### Get Granule URL Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/quick-reference.md Retrieve the direct HTTP URL for a granule, specifying the desired file extension. ```python get_url_from_granule(granule, ext) → HttpUrl ``` -------------------------------- ### Initialize DateParams with datetime object Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/api-reference/request-helpers.md Use this to initialize DateParams when you have a Python datetime object for the start date. ```python from datetime import datetime DateParams(start_date=datetime(2016, 1, 1)) ``` -------------------------------- ### Build Source Archive and Wheel Source: https://github.com/fraymio/modis-tools/blob/main/README.md Create the source archive and wheel distribution files for the project using the build package. ```python python -m build ``` -------------------------------- ### Initialize DateParams with timedelta object Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/api-reference/request-helpers.md Use this to initialize DateParams when providing a start date and a timedelta object for the duration. ```python from datetime import timedelta DateParams(start_date="2016-01-01", time_delta=timedelta(365)) ``` -------------------------------- ### Initialize CollectionApi Client Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/api-reference/CollectionApi.md Creates a client for querying MODIS collections. Provide either an authenticated session or Earthdata username and password. ```python from modis_tools.resources import CollectionApi from modis_tools.auth import ModisSession # With explicit credentials client = CollectionApi(username="myuser", password="mypass") # With existing session session = ModisSession(username="myuser", password="mypass") client = CollectionApi(session=session) ``` -------------------------------- ### Run All Tests Source: https://github.com/fraymio/modis-tools/blob/main/README.md Execute the entire test suite, including both unit and integration tests. ```bash pytest ``` -------------------------------- ### Initialize DateParams with tuple Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/api-reference/request-helpers.md Initialize DateParams using a tuple representing (year, month, day) for the start date. ```python DateParams(start_date=(2016, 1, 1)) ``` -------------------------------- ### Initialize ModisApi with Credentials or Session Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/api-reference/ModisApi.md Instantiate the ModisApi client using either explicit username and password or an existing authenticated session object. ```python from modis_tools.api import ModisApi from modis_tools.auth import ModisSession # Create with explicit credentials api = ModisApi(username="user", password="pass") # Create with existing session session = ModisSession(username="user", password="pass") api = ModisApi(session=session) ``` -------------------------------- ### Initialize DateParams with integer time delta Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/api-reference/request-helpers.md Initialize DateParams with a start date and an integer representing the time delta in days. ```python DateParams(start_date="2016-01-01", time_delta=365) ``` -------------------------------- ### Download with Progress Tracking and Threads Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/quick-reference.md Download granules using multiple threads for faster performance and include a progress bar for tracking download status. Specify the number of concurrent download threads. ```python from modis_tools.granule_handler import GranuleHandler from modis_tools.resources import GranuleApi from modis_tools.auth import ModisSession session = ModisSession(username="user", password="pass") client = GranuleApi(session=session) granules = list(client.query(start_date="2016-01-01", limit=50)) # Use multiple threads for faster downloads with progress bar file_paths = GranuleHandler.download_from_granules( granules, modis_session=session, path="/data", threads=4 # 4 concurrent downloads ) ``` -------------------------------- ### Initialize SpatialQuery with Shapely Geometry Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/api-reference/request-helpers.md Use this snippet to initialize SpatialQuery with a Shapely geometry object. Ensure Shapely is installed and imported. ```python from shapely.geometry import Point, Polygon geom = Polygon([(0, 0), (1, 0), (1, 1), (0, 1)]) SpatialQuery(spatial=geom) ``` -------------------------------- ### Authentication with Username and Password Source: https://github.com/fraymio/modis-tools/blob/main/README.md Demonstrates how to authenticate using a username and password to create a ModisSession and initialize CollectionApi or GranuleApi clients. ```APIDOC ## Authentication with Username and Password ### Description This snippet shows how to authenticate with the Modis Tools API using your Earthdata username and password. You can create a reusable session object or pass credentials directly when initializing API clients. ### Code Example ```python from modis_tools.auth import ModisSession from modis_tools.resources import CollectionApi username = "your_username" password = "your_password" # Using a reusable session session = ModisSession(username=username, password=password) collection_client = CollectionApi(session=session) # Alternatively, pass credentials directly # collection_client = CollectionApi(username=username, password=password) ``` ``` -------------------------------- ### Initialize SpatialQuery with OGR Geometry Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/api-reference/request-helpers.md Use this snippet to initialize SpatialQuery with an OGR geometry object. Ensure GDAL is installed and imported. ```python from osgeo import ogr ds = ogr.Open("file.geojson") layer = ds.GetLayer() feature = layer.GetNextFeature() SpatialQuery(spatial=feature.geometry) ``` -------------------------------- ### API Options Configuration Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/README.md Configure API options using constructor parameters for date/time, spatial, and download settings. Supports ISO strings, datetime objects, integer days, tuples, geometry objects, and boolean flags. ```python # Date/time parameters start_date="2016-01-01" # ISO string end_date=datetime(2016, 12, 31) # datetime object time_delta=365 # integer days # Spatial parameters bounding_box=(xmin, ymin, xmax, ymax) # tuple spatial=my_shapely_geometry # geometry object # Download options threads=-1 # parallel download workers path="/data" # save directory ext=("hdf", "h5", "nc") # file type priority force=False # skip existing files ``` -------------------------------- ### Get Download URL from Granule Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/module-overview.md Retrieves the direct download URL for a given granule object, specifying the desired file extension. ```python get_url_from_granule(granule, ext) ``` -------------------------------- ### Example Usage: GeoPandas Geometry Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/api-reference/request-helpers.md Demonstrates creating a SpatialQuery object using a geometry from a GeoPandas GeoDataFrame and printing its geometry type. ```python import geopandas as gpd from modis_tools.request_helpers import SpatialQuery gdf = gpd.read_file("areas.geojson") query = SpatialQuery(spatial=gdf.geometry[0]) print(query.geom_type) # geometry type ``` -------------------------------- ### DateParams example: Simple range Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/api-reference/request-helpers.md Demonstrates creating a DateParams object for a simple date range and converting it to CMR API format. ```python from modis_tools.request_helpers import DateParams # Simple range params = DateParams(start_date="2016-01-01", end_date="2016-12-31") print(params.to_dict()) # {"temporal": "2016-01-01T00:00:00Z,2016-12-31T00:00:00Z"} ``` -------------------------------- ### Download MOD13A1 for a Region and Time Period Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/quick-reference.md This workflow demonstrates finding a collection, querying granules within a bounding box and date range, and downloading them using GranuleHandler. It utilizes all available CPU cores for downloading. ```python from modis_tools.auth import ModisSession from modis_tools.resources import CollectionApi, GranuleApi from modis_tools.granule_handler import GranuleHandler # Authenticate session = ModisSession(username="user", password="pass") # Find collection collection_client = CollectionApi(session=session) collections = collection_client.query(short_name="MOD13A1", version="061") collection = collections[0] # Query granules for region and date range granule_client = GranuleApi.from_collection(collection, session=session) nigeria_bbox = [2.1448863675, 4.002583177, 15.289420717, 14.275061098] granules = granule_client.query( start_date="2016-01-01", end_date="2016-12-31", bounding_box=nigeria_bbox ) # Download all granules file_paths = GranuleHandler.download_from_granules( granules, modis_session=session, path="/data/modis", threads=-1 # Use all CPU cores ) for path in file_paths: print(f"Downloaded: {path}") ``` -------------------------------- ### GranuleApi Class Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/INDEX.txt The GranuleApi class facilitates querying granules, with detailed explanations of `query()` parameters and examples for date and spatial queries. ```APIDOC ## Class GranuleApi ### Description API client for querying Modis granules. ### Methods - **query(collection_id, **kwargs)**: Executes a query to retrieve granule data for a specific collection. Supports date, spatial, and other filtering parameters. ### Example Usage ```python from modis import ModisApi api = ModisApi() granules = api.granule.query('MODIS_L1B_CAL', start_date='2023-01-01', end_date='2023-01-31') ``` ``` -------------------------------- ### Get geom_type property for SpatialQuery Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/api-reference/request-helpers.md Demonstrates how to access the `geom_type` property of a SpatialQuery object to determine the geometry type recognized by the CMR API. ```python query = SpatialQuery(bounding_box=(0, 0, 1, 1)) print(query.geom_type) # "bounding_box" from shapely.geometry import Point query = SpatialQuery(spatial=Point(0.5, 0.5)) print(query.geom_type) # "point" ``` -------------------------------- ### Override Default Download Parameters Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/configuration.md Demonstrates how to override default download parameters, such as changing the sort order for granules. ```python granules = granule_client.query( start_date="2016-01-01", sort_key="+start_date" # Override: oldest first ) ``` -------------------------------- ### Creating GranuleApi from Collection Source: https://github.com/fraymio/modis-tools/blob/main/README.md Shows how to initialize a GranuleApi client pre-filtered for granules belonging to a specific collection. ```APIDOC ## Creating GranuleApi from Collection ### Description This snippet demonstrates how to create a `GranuleApi` instance that is pre-configured to query granules associated with a specific collection. This is achieved using the `from_collection` class method. ### Method `GranuleApi.from_collection(collection)` ### Parameters - **collection** (object) - Required - A collection object obtained from a `CollectionApi` query. ### Request Example ```python # Assuming 'collections' is a list of collection objects from a previous query # For example: collections = collection_client.query(short_name="MOD13A1", version="061") if collections: granule_client = GranuleApi.from_collection(collections[0]) # Now you can query granules for this specific collection ``` ``` -------------------------------- ### Initialize ModisSession Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/configuration.md Instantiate a ModisSession object. Provide either username and password, or an existing HTTPBasicAuth object. If no credentials are provided, it attempts to read from ~/.netrc. ```python ModisSession( username: Optional[str] = None, password: Optional[str] = None, auth: Optional[HTTPBasicAuth] = None, ) ``` -------------------------------- ### Authenticate with .netrc File Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/quick-reference.md Set up persistent authentication by adding Earthdata .netrc credentials. Subsequent sessions will use these credentials automatically. ```python from modis_tools.auth import add_earthdata_netrc, ModisSession # One-time setup add_earthdata_netrc(username="user", password="pass") # Future sessions need no credentials session = ModisSession() ``` -------------------------------- ### Initialize CollectionApi Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/quick-reference.md Create an instance of CollectionApi to interact with collection data. Requires an active ModisSession. ```python CollectionApi(session=None, username=None, password=None) ``` -------------------------------- ### Check Distribution Files Source: https://github.com/fraymio/modis-tools/blob/main/README.md Verify the integrity and correctness of the built distribution files before uploading. ```bash twine check dist/* ``` -------------------------------- ### Spatial Parameters for Queries Source: https://github.com/fraymio/modis-tools/blob/main/README.md Explains how to use spatial parameters like 'spatial' and 'bounding_box' with various geometry formats. ```APIDOC ## Spatial Parameters for Queries ### Description This section covers the use of `spatial` and `bounding_box` parameters for geographically filtering your queries. The library supports various geometry formats, including OGR, Shapely, and GeoJSON. ### Parameters - **spatial** (OGR Geometry, Shapely Geometry, GeoJSON Feature/Geometry) - Defines a spatial area for filtering. Queries are in `(longitude, latitude)` order. - **bounding_box** (list, tuple, OGR Geometry) - Defines a rectangular bounding box for filtering. If provided as a list or tuple, it should be in the order `(xmin, ymin, xmax, ymax)`. If it's a geometry object, its envelope will be used. ### Usage Examples ```python import geopandas as gpd from osgeo import ogr # Example using GeoPandas df = gpd.read_file("/path/to/your/shapefile.geojson") geometry = df.geometry[0] granules_geo = granule_client.query(start_date="2017-01-01", end_date="2018-12-31", spatial=geometry) # Example using OGR datasource = ogr.GetDriverByName("GeoJSON").Open("/path/to/your/geojson.geojson") layer = datasource.GetLayer() feature = layer.GetNextFeature() geometry_ogr = feature.geometry granules_ogr = granule_client.query(start_date="2015-09-01", bounding_box=geometry_ogr) # Example using a list/tuple for bounding_box bbox_list = [-10.0, -20.0, 10.0, 0.0] # (xmin, ymin, xmax, ymax) granules_bbox = granule_client.query(bounding_box=bbox_list) ``` ### Notes - Multipolygons and geometry collections are converted to their convex hulls for simpler queries. - All spatial queries should use `(longitude, latitude)` order. ``` -------------------------------- ### Internal GET Request with Authentication Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/api-reference/GranuleHandler.md Fetches a file from a given URL using a ModisSession for authentication. Handles redirects and cookie validation, with an option to stream the response. ```python @classmethod def _get( cls, url: HttpUrl, modis_session: ModisSession, stream: Optional[bool] = True, ) -> Response: ``` -------------------------------- ### Request Helper Classes Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/INDEX.txt Contains helper classes for formatting request parameters, such as DateParams for date formatting and SpatialQuery for geometry handling, along with format examples. ```APIDOC ## Request Helper Classes ### Classes - **DateParams**: Utility for formatting date parameters. - **SpatialQuery**: Utility for handling spatial query geometries. ### Example Usage ```python from modis.request_helpers import DateParams, SpatialQuery date_param = DateParams(start='2023-01-01', end='2023-01-31') spatial_param = SpatialQuery(geometry={'type': 'Point', 'coordinates': [-105, 40]}) ``` ``` -------------------------------- ### Handle ModisSession Initialization Error Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/errors.md This snippet demonstrates how to handle exceptions that occur during ModisSession initialization due to missing credentials or configuration. It shows how to catch the exception and then re-initialize the session with valid credentials. ```python from modis_tools.auth import ModisSession # Raises Exception if no .netrc and no credentials try: session = ModisSession() except Exception as e: print(f"Auth failed: {e}") # Handle by providing credentials session = ModisSession(username="user", password="pass") ``` -------------------------------- ### DateParams Constructor Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/types.md Initializes DateParams with optional start date, end date, and time delta. Accepts various input types for dates and time deltas. ```python def __init__( self, start_date: Optional[Any] = None, end_date: Optional[Any] = None, time_delta: Optional[Any] = None, ) ``` -------------------------------- ### Parallel Downloads with Threads Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/api-reference/GranuleHandler.md Configure the number of threads for concurrent downloads. Use -1 for all CPU cores or -2 to use all but one core. ```python # Use all CPU cores file_paths = GranuleHandler.download_from_granules( granules, modis_session=session, threads=-1 ) # Use all but one CPU core file_paths = GranuleHandler.download_from_granules( granules, modis_session=session, threads=-2, path="/data" ) ``` -------------------------------- ### Basic Usage of params_args Decorator Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/api-reference/decorators.md Demonstrates how to use the `@params_args` decorator with `DateParams` and `SpatialQuery` to process keyword arguments into a merged `params` dictionary for an API call. Shows the internal processing steps. ```python from modis_tools.decorators import params_args from modis_tools.request_helpers import DateParams, SpatialQuery @params_args(DateParams, SpatialQuery) def query(self, *, params=None, **kwargs): # DateParams and SpatialQuery kwargs are processed and merged into params # params now contains {"temporal": "...", "bounding_box": "..."} return self.api.get(params=params, **kwargs) # When called: query( start_date="2016-01-01", end_date="2016-12-31", bounding_box=(0, 0, 1, 1), other_param="value" ) # Internally: # 1. DateParams(start_date="2016-01-01", end_date="2016-12-31") # -> {"temporal": "2016-01-01T00:00:00Z,2016-12-31T00:00:00Z"} # 2. SpatialQuery(bounding_box=(0, 0, 1, 1)) # -> {"bounding_box": "0,0,1,1"} # 3. Merged params: { # "temporal": "2016-01-01T00:00:00Z,2016-12-31T00:00:00Z", # "bounding_box": "0,0,1,1" # } # 4. query() called with params={...}, other_param="value" ``` -------------------------------- ### Querying Collections Source: https://github.com/fraymio/modis-tools/blob/main/README.md Demonstrates how to query for collections using the CollectionApi, specifying parameters like short name and version. ```APIDOC ## Querying Collections ### Description This snippet shows how to use the `CollectionApi` to search for collections. You can pass various query parameters directly to the `query()` method, mirroring those available in the Earthdata Search API. ### Method `CollectionApi.query()` ### Parameters - **short_name** (string) - Required - The short name of the collection. - **version** (string) - Required - The version of the collection. ### Request Example ```python # Assuming collection_client is already initialized collections = collection_client.query(short_name="MOD13A1", version="061") ``` ### Response Returns a list of matching collection objects. ``` -------------------------------- ### Initialize SpatialQuery with Shapely Bounding Box Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/api-reference/request-helpers.md Use this snippet to initialize SpatialQuery with a Shapely geometry object representing a bounding box. Ensure Shapely is installed and imported. ```python from shapely.geometry import box geom = box(0, 0, 1, 1) SpatialQuery(bounding_box=geom) ``` -------------------------------- ### Create an Unauthenticated API Instance Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/api-reference/ModisApi.md Access the `no_auth` property to get a copy of the API instance without authentication headers. This is useful for accessing public CMR endpoints. ```python api = ModisApi(username="user", password="pass") public_api = api.no_auth response = public_api.get() # No auth headers sent ``` -------------------------------- ### Download MODIS Granules with Type Hints Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/quick-reference.md Downloads MODIS granules within a specified date range and returns a list of local file paths. Requires ModisSession and GranuleApi. ```python from typing import Iterator, List, Optional from modis_tools.auth import ModisSession from modis_tools.resources import GranuleApi from modis_tools.models import Granule from pathlib import Path def download_granules( product: str, version: str, start: str, end: str, output_dir: Optional[str] = None, ) -> List[Path]: """Download MODIS granules and return file paths.""" session: ModisSession = ModisSession(username="user", password="pass") client: GranuleApi = GranuleApi(session=session) granules: Iterator[Granule] = client.query( start_date=start, end_date=end, limit=100 ) from modis_tools.granule_handler import GranuleHandler files: List[Path] = GranuleHandler.download_from_granules( granules, modis_session=session, path=output_dir ) return files ``` -------------------------------- ### Upload to TestPyPI Source: https://github.com/fraymio/modis-tools/blob/main/README.md Upload the distribution files to the TestPyPI repository for testing purposes. Use '__token__' as username and an API token as password if MFA is enabled. ```bash twine upload -r testpypi dist/* ``` -------------------------------- ### Initialize SpatialQuery with OGR Bounding Box Geometry Source: https://github.com/fraymio/modis-tools/blob/main/_autodocs/api-reference/request-helpers.md Use this snippet to initialize SpatialQuery with an OGR geometry object representing a bounding box. Ensure GDAL is installed and imported. ```python from osgeo import ogr geom = ogr.CreateGeometryFromWkt("POLYGON((0 0, 1 0, 1 1, 0 1, 0 0))") SpatialQuery(bounding_box=geom) ```