Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Minor changes in docs "extending" and landsat connector - support of login-token #104

Open
wants to merge 3 commits into
base: b-1.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion CHANGES.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
..
This file is part of BDC-Collectors.
Copyright (C) 2023 INPE.
Copyright (C) 2025 INPE.

BDC-Collectors is a free software; you can redistribute it and/or modify it
under the terms of the MIT License; see LICENSE file for more details.
Expand All @@ -10,6 +10,14 @@
Changes
=======

Version 1.0.3 (2025-02-21)
--------------------------

- Update USGS Connector API to support login-token (#103)
- Remove warnings from docs buiding
- Review Dockerfile version


Version 1.0.2 (2024-12-30)
--------------------------

Expand Down
39 changes: 39 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#
# This file is part of Brazil Data Cube BDC-Collectors.
# Copyright (C) 2023 INPE.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/gpl-3.0.html>.
#
ARG GIT_COMMIT
ARG BASE_IMAGE=python:3.11-bullseye
FROM ${BASE_IMAGE}

ARG GIT_COMMIT

LABEL "org.repo.maintainer"="Brazil Data Cube <[email protected]>"
LABEL "org.repo.title"="Docker image for BDC Collectors"
LABEL "org.repo.description"="Docker image to collect data from multiple providers."
LABEL "org.repo.git_commit"="${GIT_COMMIT}"

# Build arguments
ARG APP_INSTALL_PATH="/opt/bdc-collectors"

ADD . ${APP_INSTALL_PATH}

WORKDIR ${APP_INSTALL_PATH}

RUN python3 -m pip install pip --upgrade setuptools wheel --no-cache && \
python3 -m pip install --no-cache -e .[docs,tests,raster]

CMD ["bdc-collector"]
77 changes: 77 additions & 0 deletions USAGE.rst
Original file line number Diff line number Diff line change
Expand Up @@ -291,3 +291,80 @@ The following code is an example of an ``entry_points`` in ``setup.py`` file:
'mycatalog = my_app.mycatalog'
]
}


Creating a new provider based on existent provider
++++++++++++++++++++++++++++++++++++++++++++++++++

This example shows how to create your own provider based on :class:`bdc_collectors.dataspace.DataspaceProvider`.
You can also use this if you would like to implement a different provider from scratch.


This example assume you have a minimal package named ``my-app`` with the following structure::

my-app/
├── setup.py
└── my_app/
├── __init__.py
└── api.py


Create a file named ``my_app/api.py`` and use the following snippet for a minimal set up for inheriting from :class:`bdc_collectors.dataspace.DataspaceProvider`::

from typing import Type

from ..base import BaseCollection
from ..dataspace import DataspaceProvider

def init_provider():
return dict(MyProvider=MyProviderAPI)


class MyProviderAPI(DataspaceProvider):
def __init__(self, *args, **kwargs):
kwargs.setdefault("api_url", "https://my-url-provider-hub")
super(MyProviderAPI, self).__init__(*args, **kwargs)
def get_collector(self, collection: str) -> Type[BaseCollection]:
# ... logic for custom data collection
return super().get_collector(collection) # optional
def search(self, *args, **kwargs):
# ... logic for search collection
return super().search(*args, **kwargs) # optional
def download(self, *args, **kwargs):
# ... logic for search collection
return super().download(*args, **kwargs) # optional


The file ``my_app/__init__.py`` should export the ``MyProviderAPI`` as following::

from .api import MyProviderAPI, init_provider

__all__ = (
"MyProviderAPI",
"init_provider"
)


Edit ``setup.py`` and register your module with the following statement::


entry_points={
'bdc_collectors.providers': [
'myprovider = my_app'
]
}

After that, you can install the module and it will be loaded whenever you call the extension like as following::

from bdc_collectors.ext import CollectorExtension
from flask import Flask

app = Flask(__name__)
ext = CollectorExtension(app) # flask_app
catalog = ext.get_provider("MyProvider")(parameter1="x", parameter2="b", ...)
catalog.search(...)

# Or use directly
# from my_app import MyProviderAPI
# catalog = MyProviderAPI(parameter1="x", parameter2="b", ...)
# catalog.search(...)
11 changes: 5 additions & 6 deletions bdc_collectors/usgs/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,10 @@ def __init__(self, **kwargs):

self.kwargs = kwargs

if lazy:
self.api = None
else:
self.api = LandsatApi(self.kwargs['username'], self.kwargs['password'])
self.ee = EarthExplorer(self.kwargs['username'], self.kwargs['password'])
self.api = None

if not lazy:
self._api()

def _set_default_collections(self, datasets, data_type):
for dataset in datasets:
Expand All @@ -97,7 +96,7 @@ def _set_default_collections(self, datasets, data_type):
def _api(self):
"""Lazy API instance."""
if self.api is None:
self.api = LandsatApi(self.kwargs['username'], self.kwargs['password'])
self.api = LandsatApi(self.kwargs['username'], self.kwargs['token'])
self.ee = EarthExplorer(self.kwargs['username'], self.kwargs['password'])

def get_collector(self, collection: str) -> Type[BaseCollection]:
Expand Down
10 changes: 7 additions & 3 deletions bdc_collectors/usgs/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ class LandsatApi:
This interface follows the `JSON API 1.5 <https://m2m.cr.usgs.gov/api/docs/json/>`_ stable spec.

Use this API directly only if you really need. Otherwise use `bdc_collectors.usgs.USGS` instead.

Note:
This interface is already according to M2M Login Tokens.
Consider ``password`` as ``token``.
"""

api_url: str = 'https://m2m.cr.usgs.gov/api/api/json/{version}'
Expand All @@ -46,15 +50,15 @@ class LandsatApi:

_filters: Dict[str, Any]

def __init__(self, username: str, password: str, version: str = 'stable',
def __init__(self, username: str, token: str, version: str = 'stable',
lazy: bool = False, progress: bool = False, **kwargs):
"""Build a API instance."""
self.api_url = self.api_url.format(version=version)
self.session = requests.Session()
self.session.headers.update(**{'Content-Type': 'application/json'})
self._credentials = dict(
username=username,
password=password,
token=token,
**kwargs
)
self.progress = progress
Expand All @@ -71,7 +75,7 @@ def login(self):
Raises:
RuntimeError for any error occurred.
"""
response = self.session.post(f'{self.api_url}/login', json=self._credentials,
response = self.session.post(f'{self.api_url}/login-token', json=self._credentials,
headers={'Content-Type': 'application/json'})

# TODO: validate content type
Expand Down
2 changes: 1 addition & 1 deletion bdc_collectors/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@

"""Version information for BDC-Collectors."""

__version__ = '1.0.2'
__version__ = '1.0.3'