Skip to content

Commit

Permalink
Merge pull request brazil-data-cube#37 from fabianazioti/b-0.6
Browse files Browse the repository at this point in the history
fixing create mapping and style ref brazil-data-cube#35
  • Loading branch information
raphaelrpl authored Mar 12, 2021
2 parents 4a9f65a + da6921a commit bd71109
Show file tree
Hide file tree
Showing 25 changed files with 416 additions and 658 deletions.
13 changes: 10 additions & 3 deletions .drone.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,8 @@ steps:
commands:
- pip install --upgrade pip
- pip install --upgrade setuptools
- pip install -e .[tests,docs]
- pip install -e .[all]
- ./run-tests.sh
environment:
LCCS_SERVER_URL: http://brazildatacube.dpi.inpe.br/dev/lccs

- name: coverage
image: plugins/codecov
Expand All @@ -24,3 +22,12 @@ steps:
event:
- push

- name: discord-notify
image: brazildatacube/bdc-drone-discord
settings:
webhook:
from_secret: discord_webhook
when:
status:
- failure
- success
2 changes: 1 addition & 1 deletion docs/sphinx/examples.rst
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ Mappings

This example shows the list of available mappings in service of a specific classification system:

.. literalinclude:: ../../examples/mappings.py
.. literalinclude:: ../../examples/available_mappings.py
:language: python
:lines: 10-

Expand Down
4 changes: 2 additions & 2 deletions examples/mappings.py → examples/available_mappings.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
from lccs import LCCS

# Change to the LCCS-WS URL you want to use.
service = LCCS("http://brazildatacube.dpi.inpe.br/dev/lccs/")
service = LCCS("https://brazildatacube.dpi.inpe.br/lccs/")

# Return the list of available clasification system for mapping
available_mappings = service.available_mappings(system_id_source='TerraClass_AMZ')
available_mappings = service.available_mappings('PRODES-1.0')

print(available_mappings)
4 changes: 2 additions & 2 deletions examples/class_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@

# Get a specific classification system
# Make sure the classification system is available in service
classification_system = service.classification_system(system_id='TerraClass_AMZ')
classification_system = service.classification_system('PRODES-1.0')

# Return the metadata of a specific class
class_metadata = classification_system.classes(class_id='Desflorestamento')
class_metadata = classification_system.get_class('Desflorestamento')
print(class_metadata)

# You can access specific attributes
Expand Down
7 changes: 4 additions & 3 deletions examples/classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@
from lccs import LCCS

# Change to the LCCS-WS URL you want to use.
service = LCCS("http://brazildatacube.dpi.inpe.br/dev/lccs/")
service = LCCS("https://brazildatacube.dpi.inpe.br/lccs/")

# Get a specific classification system
# Make sure the classification system is available in service
classification_system = service.classification_system(system_id='TerraClass_AMZ')
classification_system = service.classification_system('PRODES-1.0')

# Returns all classes belonging to a specific classification system.
classes = classification_system.classes()
classes = classification_system.classes
print(classes)

4 changes: 2 additions & 2 deletions examples/classification_system_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@
from lccs import LCCS

# Change to the LCCS-WS URL you want to use.
service = LCCS("http://brazildatacube.dpi.inpe.br/dev/lccs/")
service = LCCS("https://brazildatacube.dpi.inpe.br/lccs/")

# Return the metadata of a specific classification system
# Make sure the classification system is available in service
classification_system = service.classification_system(system_id='TerraClass_AMZ')
classification_system = service.classification_system('PRODES-1.0')
print(classification_system)

# You can access specific attributes
Expand Down
2 changes: 1 addition & 1 deletion examples/classification_systems.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from lccs import LCCS

# Change to the LCCS-WS URL you want to use.
service = LCCS("http://brazildatacube.dpi.inpe.br/dev/lccs/")
service = LCCS("https://brazildatacube.dpi.inpe.br/lccs/")

# Returns the list of classification system available on the service
print(service.classification_systems)
11 changes: 5 additions & 6 deletions examples/ex-01.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@

print(lccs.__version__)

url = os.environ.get('LCCS_SERVER_URL', 'https://brazildatacube.dpi.inpe.br/dev/lccs/')
server_url = os.environ.get('LCCS_SERVER_URL', 'https://brazildatacube.dpi.inpe.br/lccs/')

service = lccs.LCCS('http://127.0.0.1:5000/')
service = lccs.LCCS(server_url)

print("Return all classificaton systems available in service")
print("Return all classification systems available in service")
print(service.classification_systems)

# The examples presented in this code vary depending on the database used. Check the parameters informed.
Expand All @@ -42,10 +42,9 @@
# Get mapping
mapping = service.mappings(system_name_source='PRODES-1.0', system_name_target='TerraClass_AMZ-1.0')

print(f"\nMapping PRODES-1.0 to TerraClass_AMZ-1.0: \n")
print(f"\nMapping PRODES-1.0 to TerraClass_AMZ-1.0:")

for mp in mapping:
print(mp)
print(mapping)

# Get all styles available for a specific classification system
style_formats = service.style_formats(system_source_name='PRODES-1.0')
Expand Down
9 changes: 3 additions & 6 deletions examples/mapping.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,10 @@
from lccs import LCCS

# Change to the LCCS-WS URL you want to use.
service = LCCS("http://brazildatacube.dpi.inpe.br/dev/lccs/")
service = LCCS("https://brazildatacube.dpi.inpe.br/lccs/")

# Returns the mapping between two classification systems.
# Make sure the classification system is available in service
mappings = service.mappings(system_id_source='TerraClass_AMZ', system_id_target='PRODES')

for mp in mappings.mapping:
print("Source Class: {} ID: {} | Target Class: {} ID: {}".format(mp.source_class, mp.source_class_id,
mp.target_class, mp.target_class_id))
mapping = service.mappings(system_name_source='PRODES-1.0', system_name_target='TerraClass_AMZ-1.0')

print(mapping)
6 changes: 3 additions & 3 deletions examples/style.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@
from lccs import LCCS

# Change to the LCCS-WS URL you want to use.
service = LCCS("http://brazildatacube.dpi.inpe.br/dev/lccs/")
service = LCCS("https://brazildatacube.dpi.inpe.br/dev/lccs/")

# Save Style File
service.get_styles(system_id='MapBiomas5', format_id='QGIS')
service.get_style(system_name='PRODES-1.0', format_name='QGIS')

# Save Style File passing the path directory
service.get_styles(system_id='MapBiomas5', format_id='QGIS', path='/home/user/Downloads/')
service.get_style(system_name='PRODES-1.0', format_name='QGIS', path='/home/user/Downloads/')
4 changes: 2 additions & 2 deletions examples/styles.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
from lccs import LCCS

# Change to the LCCS-WS URL you want to use.
service = LCCS("http://brazildatacube.dpi.inpe.br/dev/lccs/")
service = LCCS("https://brazildatacube.dpi.inpe.br/lccs/")

# Get all styles available for a specific classification system
styles = service.styles(system_id='MapBiomas5')
styles = service.style_formats('PRODES-1.0')

print(styles)
7 changes: 4 additions & 3 deletions lccs/class_system.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,10 @@ def _get_classes(self, filter=None):
for link in self['links']:
if link['rel'] == 'classes':
data = Utils._get(link['href'], params=filter)
[classes.append(ClassificationSystemClass(Utils._get(i['href'], self._validate), self._validate)) for i in data if i['rel'] == 'child']
self['classes'] = classes
return ClassificationSystemClass({})
for i in data:
if 'rel' in i and i['rel'] == 'child':
classes.append(ClassificationSystemClass(Utils._get(i['href'], self._validate), self._validate))
self['classes'] = classes

def _repr_html_(self):
"""HTML repr."""
Expand Down
29 changes: 14 additions & 15 deletions lccs/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,46 +174,45 @@ def mappings(config: Config, system_name_source, system_name_target, verbose):


@cli.command()
@click.option('--system_id_source', type=click.STRING, required=True, help='The classification system source.')
@click.option('--system_id_target', type=click.STRING, required=True, default=None,
@click.option('--system_name_source', type=click.STRING, required=True, help='The classification system source.')
@click.option('--system_name_target', type=click.STRING, required=True, default=None,
help='The classification system target.')
@click.option('--mappings_path', type=click.Path(exists=True), required=True, help='File path with the mapping')
@click.option('-v', '--verbose', is_flag=True, default=False)
@pass_config
def add_mapping(config: Config, system_id_source, system_id_target, mappings_path, verbose):
def add_mapping(config: Config, system_name_source, system_name_target, mappings_path, verbose):
"""Add a mapping between classification systems."""
if verbose:
click.secho(f'Server: {config.url}', bold=True, fg='black')
click.secho('\tAdding new mapping ... ', bold=False, fg='black')

retval = config.service.add_mapping(system_id_source=system_id_source, system_id_target=system_id_target,
mappings_path=mappings_path)
config.service.add_mapping(system_name_source=system_name_source,
system_name_target=system_name_target,
mappings=mappings_path)

click.secho(f'Added Mapping between {retval["source_classification_system"]} and '
f'{retval["target_classification_system"]}', bold=True, fg='green')
click.secho(f'Added Mapping between {system_name_source} and '
f'{system_name_target}', bold=True, fg='green')

if verbose:
click.secho('\tFinished!', bold=False, fg='black')


@cli.command()
@click.option('--system_id', type=click.STRING, required=True, help='The classification system source.')
@click.option('--style_format', type=click.STRING, required=True, default=None,
@click.option('--system_name', type=click.STRING, required=True, help='The classification system source.')
@click.option('--style_format_name', type=click.STRING, required=True, default=None,
help='The style file format.')
@click.option('--style_path', type=click.Path(exists=True), required=True, help='The style file path.')
@click.option('--extension', type=click.STRING, required=True, help='The style extension type.')
@click.option('-v', '--verbose', is_flag=True, default=False)
@pass_config
def add_style(config: Config, system_id, style_format, style_path, extension, verbose):
def add_style(config: Config, system_name, style_format_name, style_path, verbose):
"""Add a classification system style."""
if verbose:
click.secho(f'Server: {config.url}', bold=True, fg='black')
click.secho('\tAdding new classification system style ... ', bold=False, fg='black')

retval = config.service.add_style(system_id=system_id, style_format=style_format, style_path=style_path,
extension=extension)

click.secho(f'{retval}', bold=True, fg='green')
config.service.add_style(system_name=system_name,
format_name=style_format_name,
style_path=style_path)

if verbose:
click.secho('\tFinished!', bold=False, fg='black')
Expand Down
70 changes: 40 additions & 30 deletions lccs/lccs.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from .mappings import MappingGroup, Mapping
from .style_formats import StyleFormats
from .utils import Utils
import json


class LCCS:
Expand Down Expand Up @@ -83,7 +84,6 @@ def classification_system(self, system_name: str) -> ClassificationSystem:
:returns: A ClassificationSystem.
:rtype: dict
"""

if system_name in self._classification_systems.keys() and self._classification_systems[system_name] is not None:
return self._classification_systems[system_name]

Expand Down Expand Up @@ -121,7 +121,7 @@ def available_mappings(self, system_source_name: str) -> list:

return result

def mappings(self, system_name_source: str, system_name_target: str) -> list:
def mappings(self, system_name_source: str, system_name_target: str) -> MappingGroup:
"""Return the given classification_system.
:param system_name_source: A classification system name.
Expand All @@ -134,18 +134,17 @@ def mappings(self, system_name_source: str, system_name_target: str) -> list:
"""
_system_source_id = self._id(system_name_source)
_system_target_id = self._id(system_name_target)

result = list()


try:
data = Utils._get(f'{self._url}/mappings/{_system_source_id.id}/{_system_target_id.id}')
except Exception:
raise KeyError('Could not retrieve mappings for {} and {}'.format(system_name_source, system_name_target))

[result.append(Mapping(mapping, self._validate)) for mapping in data]

return result

data_result = dict()
data_result['mappings'] = data

return MappingGroup(data_result, self._validate)

def style_formats(self, system_source_name) -> list:
"""Fetch styles of the a giving classification system.
Expand Down Expand Up @@ -216,45 +215,56 @@ def add_classification_system(self, name: str, authority_name: str, description:

return retval

def add_style(self, system_id: str, style_format: str, style_path: str, extension: str):
def add_style(self, system_name: str, format_name: str, style_path: str):
"""Add a new style format system."""
url = f'{self._url}/classification_system/{system_id}/styles{self._access_token}'
_format_id = self._get_format_identifier(format_name)

_system_source_id = self._id(system_name)

url = f'{self._url}/classification_systems/{_system_source_id.id}/styles{self._access_token}'

try:
style = {'style': (f'style_{system_id}_{style_format}.{extension}', open(style_path, 'rb'),
'application/octet-stream')}
style = {'style': open(style_path, 'rb')}
except RuntimeError:
raise ValueError(f'Could not open style file {style_path}.')

data = dict()
data["style_format"] = style_format
data["style_format_id"] = _format_id['id']

try:
retval = Utils._post(url, data=data, files=style)
except RuntimeError:
raise ValueError('Could not insert style!')

return retval['message']
return retval

def add_mapping(self, system_id_source: str, system_id_target: str, mappings_path: str):
def add_mapping(self, system_name_source: str, system_name_target: str, mappings):
"""Add new classification system mapping."""
url = f'{self._url}/mappings/{system_id_source}/{system_id_target}{self._access_token}'

try:
mapping = {'mappings': ('mappings.json', open(mappings_path, 'rb'), 'application/json')}
except RuntimeError:
raise ValueError(f'Could not open mapping file {mappings_path}. It is a json file ?')
def get_id_by_name(name, classes):
"""Get id of class."""
return list(filter(lambda x: x.name == name, classes))[0]['id']

_system_source_id = self._id(system_name_source)
_system_target_id = self._id(system_name_target)

url = f'{self._url}/mappings/{_system_source_id.id}/{_system_target_id.id}{self._access_token}'

if type(mappings) == str:
with open(mappings) as file:
mappings = json.load(file)

for i in mappings:
if type(i['source_class_id']) != str:
break
i['source_class_id'] = get_id_by_name(i['source_class_id'], _system_source_id.classes)
i['target_class_id'] = get_id_by_name(i['target_class_id'], _system_target_id.classes)

try:
retval = Utils._post(url, json=mapping)
retval = Utils._post(url, json=mappings)
except RuntimeError:
raise ValueError('Could not insert mappings!')

retval['source_classification_system'] = system_id_source

retval['target_classification_system'] = system_id_target

return MappingGroup(retval, self._validate)

return retval

@property
def url(self):
Expand Down
14 changes: 14 additions & 0 deletions lccs/mappings.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,20 @@ def _repr_html_(self):
"""HTML repr."""
return Utils.render_html('mapping.html', mappings=self)

def __repr__(self):
"""Return the string representation of a mapping group object."""
text = ''
for i in self.mapping:
text += f'\n\t{i}'
return text

def __str__(self):
"""Return the string representation of a mapping group object."""
text = ''
for i in self.mapping:
text += f'\n\t{i}'
return text


class Mapping(dict):
"""Mapping."""
Expand Down
Loading

0 comments on commit bd71109

Please sign in to comment.