Python CMR is an easy to use wrapper to the NASA EOSDIS Common Metadata Repository API.

Overview

This repository is a copy of jddeal/python_cmr which is no longer maintained. It has been copied here with the permission of the original author for the purpose of continuing to develop a python library that can be used for CMR access.


Python CMR

CodeQL

Python CMR is an easy to use wrapper to the NASA EOSDIS Common Metadata Repository API. This package aims to make querying the API intuitive and less error-prone by providing methods that will preemptively check for invalid input and handle the URL encoding the CMR API expects.

Getting access to NASA's earth science metadata is as simple as this:

>> for collection in collections: >>> print(collection["short_name"]) AST_L1A AST_L1AE AST_L1T >>> api = GranuleQuery() >>> granules = api.short_name("AST_L1T").point(-112.73, 42.5).get(3) >>> for granule in granules: >>> print(granule["title"]) SC:AST_L1T.003:2149105822 SC:AST_L1T.003:2149105820 SC:AST_L1T.003:2149155037 ">
>>> from cmr import CollectionQuery, GranuleQuery

>>> api = CollectionQuery()
>>> collections = api.archive_center("LP DAAC").keyword("AST_L1*").get(5)

>>> for collection in collections:
>>>   print(collection["short_name"])
AST_L1A
AST_L1AE
AST_L1T

>>> api = GranuleQuery()
>>> granules = api.short_name("AST_L1T").point(-112.73, 42.5).get(3)

>>> for granule in granules:
>>>   print(granule["title"])
SC:AST_L1T.003:2149105822
SC:AST_L1T.003:2149105820
SC:AST_L1T.003:2149155037

Installation

To install from pypi:

$ pip install python-cmr

To install from github, perhaps to try out the dev branch:

$ git clone https://github.com/jddeal/python-cmr
$ cd python-cmr
$ pip install .

Examples

This library is broken into two classes, CollectionQuery and GranuleQuery. Each of these classes provide a large set of methods used to build a query for CMR. Not all parameters provided by the CMR API are covered by this version of python-cmr.

The following methods are available to both collecton and granule queries:

>> api.version("006") # search for granules at a specific longitude and latitude >>> api.point(-112.73, 42.5) # search for granules in an area bound by a box (lower left lon/lat, upper right lon/lat) >>> api.bounding_box(-112.70, 42.5, -110, 44.5) # search for granules in a polygon (these need to be in counter clockwise order and the # last coordinate must match the first in order to close the polygon) >>> api.polygon([(-100, 40), (-110, 40), (-105, 38), (-100, 40)]) # search for granules in a line >>> api.line([(-100, 40), (-90, 40), (-95, 38)]) # search for granules in an open or closed date range >>> api.temporal("2016-10-10T01:02:00Z", "2016-10-12T00:00:30Z") >>> api.temporal("2016-10-10T01:02:00Z", None) >>> api.temporal(datetime(2016, 10, 10, 1, 2, 0), datetime.now()) # only include granules available for download >>> api.downloadable() # only include granules that are unavailable for download >>> api.online_only() # search for collections/granules associated with or identified by concept IDs # note: often the ECHO collection ID can be used here as well # note: when using CollectionQuery, only collection concept IDs can be passed # note: when uses GranuleQuery, passing a collection's concept ID will filter by granules associated # with that particular collection. >>> api.concept_id("C1299783579-LPDAAC_ECS") >>> api.concept_id(["G1327299284-LPDAAC_ECS", "G1326330014-LPDAAC_ECS"]) # search by provider >>> api.provider('POCLOUD') ">
# search for granules matching a specific product/short_name
>>> api.short_name("AST_L1T")

# search for granules matching a specific version
>>> api.version("006")

# search for granules at a specific longitude and latitude
>>> api.point(-112.73, 42.5)

# search for granules in an area bound by a box (lower left lon/lat, upper right lon/lat)
>>> api.bounding_box(-112.70, 42.5, -110, 44.5)

# search for granules in a polygon (these need to be in counter clockwise order and the
# last coordinate must match the first in order to close the polygon)
>>> api.polygon([(-100, 40), (-110, 40), (-105, 38), (-100, 40)])

# search for granules in a line
>>> api.line([(-100, 40), (-90, 40), (-95, 38)])

# search for granules in an open or closed date range
>>> api.temporal("2016-10-10T01:02:00Z", "2016-10-12T00:00:30Z")
>>> api.temporal("2016-10-10T01:02:00Z", None)
>>> api.temporal(datetime(2016, 10, 10, 1, 2, 0), datetime.now())

# only include granules available for download
>>> api.downloadable()

# only include granules that are unavailable for download
>>> api.online_only()

# search for collections/granules associated with or identified by concept IDs
# note: often the ECHO collection ID can be used here as well
# note: when using CollectionQuery, only collection concept IDs can be passed
# note: when uses GranuleQuery, passing a collection's concept ID will filter by granules associated
#       with that particular collection.
>>> api.concept_id("C1299783579-LPDAAC_ECS")
>>> api.concept_id(["G1327299284-LPDAAC_ECS", "G1326330014-LPDAAC_ECS"])

# search by provider
>>> api.provider('POCLOUD')

Granule searches support these methods (in addition to the shared methods above):

>> api.orbit_number(5000) # filter by the day/night flag >>> api.day_night_flag("day") # filter by cloud cover percentage range >>> api.cloud_cover(25, 75) # filter by specific instrument or platform >>> api.instrument("MODIS") >>> api.platform("Terra") ">
# search for a granule by its unique ID
>>> api.granule_ur("SC:AST_L1T.003:2150315169")
# search for granules from a specific orbit
>>> api.orbit_number(5000)

# filter by the day/night flag
>>> api.day_night_flag("day")

# filter by cloud cover percentage range
>>> api.cloud_cover(25, 75)

# filter by specific instrument or platform
>>> api.instrument("MODIS")
>>> api.platform("Terra")

Collection searches support these methods (in addition to the shared methods above):

>> api.keyword("M*D09") # search by native_id >>> api.native_id('native_id') # filter by tool concept id >>> api.tool_concept_id('TL2092786348-POCLOUD') # filter by service concept id >>> api.service_concept_id('S1962070864-POCLOUD') ">
# search for collections from a specific archive center
>>> api.archive_center("LP DAAC")

# case insensitive, wildcard enabled text search through most collection fields
>>> api.keyword("M*D09")

# search by native_id
>>> api.native_id('native_id')

# filter by tool concept id
>>> api.tool_concept_id('TL2092786348-POCLOUD')

# filter by service concept id
>>> api.service_concept_id('S1962070864-POCLOUD')

Service searches support the following methods

# Search via provider
>>> api = ServiceQuery()
>>> api.provider('POCLOUD')

# Search via native_id
>>> api.native_id('POCLOUD_podaac_l2_cloud_subsetter')

# Search via name
>>> api.name('PODAAC L2 Cloud Subsetter')

Tool searches support the following methods

# Search via provider
>>> api = ToolQuery()
>>> api.provider('POCLOUD')

# Search via native_id
>>> api.native_id('POCLOUD_hitide')

# Search via name
>>> api.name('hitide')

As an alternative to chaining methods together to set the parameters of your query, a method exists to allow you to pass your parameters as keyword arguments:

# search for AST_L1T version 003 granules at latitude 42, longitude -100
>>> api.parameters(
    short_name="AST_L1T",
    version="003",
    point=(-100, 42)
)

Note: the kwarg key should match the name of a method from the above examples, and the value should be a tuple if it's a parameter that requires multiple values.

To inspect and retreive results from the API, the following methods are available:

# inspect the number of results the query will return without downloading the results
>>> print(api.hits())

# retrieve 100 granules
>>> granules = api.get(100)

# retrieve 25,000 granules
>>> granules = api.get(25000)

# retrieve all the granules possible for the query
>>> granules = api.get_all()  # this is a shortcut for api.get(api.hits())

By default the responses will return as json and be accessible as a list of python dictionaries. Other formats can be specified before making the request:

>>> granules = api.format("echo10").get(100)

The following formats are supported for both granule and collection queries:

  • json (default)
  • xml
  • echo10
  • iso
  • iso19115
  • csv
  • atom
  • kml
  • native

Collection queries also support the following formats:

  • dif
  • dif10
  • opendata
  • umm_json
  • umm_json_vX_Y (ex: umm_json_v1_9)
Comments
  • Variablesquery

    Variablesquery

    • Added in VariableQuery class to query umm-v
    • Added in tests for VariableQuery
    • Changed url in readme for github url
    • Concept_id function return self so we can chain functions
    opened by sliu008 1
  • Release/0.7.0

    Release/0.7.0

    [0.7.0]

    Added

    • New workflow that runs lint and test
    • New function Query.token to add an auth token to the request sent to CMR

    Changed

    opened by frankinspace 0
  • Release/0.6.0

    Release/0.6.0

    [0.6.0]

    Added

    • New support for querying variables (UMM-V)

    Changed

    • Can now import ToolQuery ServiceQuery VariableQuery straight from cmr module. (e.g. from cmr import ToolQuery)
    opened by frankinspace 0
  • Release/0.5.0

    Release/0.5.0

    [0.5.0]

    Added

    • New support for querying tools (UMM-T) and services (UMM-S)
    • CodeQL Analysis on pushes and pull requests

    Changed

    • Moved to github.com/nasa/python_cmr
    opened by frankinspace 0
  • New searching criterion: circle

    New searching criterion: circle

    Similar to the point criterion but includes a buffer around the point. One application is searching for granules with data within a certain distance of a waypoint such as a mooring or a meteorological station.

    opened by castelao 0
  • Bump certifi from 2021.10.8 to 2022.12.7

    Bump certifi from 2021.10.8 to 2022.12.7

    Bumps certifi from 2021.10.8 to 2022.12.7.

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
Releases(v0.7.0)
  • v0.7.0(Nov 23, 2021)

    [0.7.0]

    Added

    • New workflow that runs lint and test
    • New function Query.token to add an authentication token to the request sent to CMR

    Changed

    What's Changed

    • Create python-app.yml by @frankinspace in https://github.com/nasa/python_cmr/pull/7
    • Feature/token by @sliu008 in https://github.com/nasa/python_cmr/pull/8
    • Release/0.7.0 by @frankinspace in https://github.com/nasa/python_cmr/pull/9

    Full Changelog: https://github.com/nasa/python_cmr/compare/v0.6.0...v0.7.0

    Source code(tar.gz)
    Source code(zip)
  • v0.6.0(Oct 28, 2021)

    [0.6.0]

    Added

    • New support for querying variables (UMM-V)

    Changed

    • Can now import ToolQuery ServiceQuery VariableQuery straight from cmr module. (e.g. from cmr import ToolQuery)
    Source code(tar.gz)
    Source code(zip)
  • v0.5.0(Oct 15, 2021)

    [0.5.0]

    Added

    • New support for querying tools (UMM-T) and services (UMM-S)
    • CodeQL Analysis on pushes and pull requests

    Changed

    • Moved to github.com/nasa/python_cmr
    Source code(tar.gz)
    Source code(zip)
Owner
NASA
Read about NASA's Open Data initiative here: https://www.nasa.gov/open/ & Members Find Instructions here: http://nasa.github.io/
NASA
A Simple Telegram Bot That Can Generate Strong Password With Many Features Written In Python Using Pyrogram

Password-Generator-Bot A Simple Telegram Bot That Can Generate Strong Password With Many Features Written In Python Using Pyrogram Features Random Pas

Muhammed Fazin 17 Dec 23, 2022
A cracking tool of Xiaomi Dr AI (Archytas / Archimedes)

Archytas Tool 我们强烈抵制闲鱼平台上未经授权的刷机服务! 我对本人之前在程序中为防止违规刷机服务添加未生效的格机代码感到抱歉,在此声明此过激行为与 Crack Mi Dr AI Team 无关,并将程序开源。 A cracking tool of Xiaomi Dr AI (Archy

rponeawa 5 Oct 25, 2022
💻 A fully functional local AWS cloud stack. Develop and test your cloud & Serverless apps offline!

LocalStack - A fully functional local AWS cloud stack LocalStack provides an easy-to-use test/mocking framework for developing Cloud applications. Cur

LocalStack 45.3k Jan 02, 2023
Name says it all/Instructions are in README file.

Discord-Webhook-Spammer Name says it all/Instructions are in README file. Setup 1. pip install discord-webhook ( In console, terminal or whatever you

Catto 1 Mar 21, 2022
Automation application was made by me using Google, Sheet and Slack APIs with Python.

README This application is used to transfer the data in the xlsx document we have to the Google Drive environment and calculate the "total budget" wit

3 Apr 12, 2022
VideoMergeDcBot1 - Video Merge Dc Bot for telegram

VIDEO MERGE BOT An Telegram Bot Demo 👉 @VideoMergeDcBot To Merge multiple Video

Selfie SD 2 Feb 04, 2022
Python wrapper for the GitLab API

Python GitLab python-gitlab is a Python package providing access to the GitLab server API. It supports the v4 API of GitLab, and provides a CLI tool (

1.9k Dec 31, 2022
An interactive and multi-function Telegram bot, made especially for Telegram groups.

PyKorone An interaction and fun bot for Telegram groups, having some useful and other useless commands. Created as an experiment and learning bot but

Amano Team 17 Nov 12, 2022
Subtitle Translater

Subtitle Translater

OshadhaVimukthi 2 Nov 29, 2021
discord.js nuker (50 bans a sec)

js-nuker discord.js nuker (50 bans a sec) I was to lazy to make the scraper in js, but this works too. DISCLAIMER This is tool was made for educationa

4 Sep 11, 2021
Innocent-Bot - A Discord client self-bot for destroying, nuking and causing mischief in servers

Innocent-bot A Discord client self-bot for destroying, nuking and causing mischi

†† 5 Jan 26, 2022
THE BEST INSTAGRAM AUTO LIKER GET MORE FOLLOWERS WITH THIS AUTOMATION

Hi 👋 , I'm Anandhu Ashok Developer making awesome things for awesome people 🚀 Connect with me: THE BEST INSTAGRAM AUTO LIKER GET MORE FOLLOWERS WITH

Anandhu Ashok 3 Jul 26, 2022
Asynchronous Python Wrapper for the Ufile API

Ufile.io Asynchronous Python Wrapper for the Ufile API (Unofficial).

Gautam Kumar 16 Aug 31, 2022
🐙 Share your Github stats for 2020 on Twitter

Year on Github 🐙 Share your Github stats for 2020 on Twitter. This project contains a small web app that let's you share stats about your Github acti

Johannes Rieke 129 Dec 25, 2022
A lightweight Python wrapper for the IG Markets API

trading_ig A lightweight Python wrapper for the IG Markets API. Simplifies access to the IG REST and Streaming APIs with a live or demo account. What

IG Python 247 Dec 08, 2022
Simple Craigslist wrapper

python-craigslist A simple Craigslist wrapper. License: MIT-Zero. Disclaimer I don't work for or have any affiliation with Craigslist. This module was

Julio M. Alegria 370 Dec 22, 2022
A Script to automate fowarding all new messages from one/many channel(s) to another channel(s), without the forwarded tag.

Channel Auto Message Post A script to automate fowarding all new messages from one/many channel(s) to another channel(s), without the forwarded tag. C

16 Oct 21, 2022
Nowadays we don't have time to listen to each and every song that we come across in a playlist.

Nowadays we don't have time to listen to each and every song that we come across in a playlist. so, this project helps you. we used Spotify API for collecting the dataset information and able to do E

3 Apr 26, 2022
A Webhook spammer For Python

Webhooker Optimizations Asynchronous Fast & Efficient Multi Tasked Usage Put high threads/tasks for maximum impact Webhook must be valid Proof of conc

andria 1 Dec 20, 2021
Black-hat with python

black-hat_python Advantages - More advance tool Easy to use allows updating tool update - run bash update.sh Here -: Command to install tool main- clo

Hackers Tech 2 Feb 10, 2022