-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #280 from datosgobar/277-indicadores-status-downlo…
…adURL 277 indicadores status download url
- Loading branch information
Showing
10 changed files
with
397 additions
and
74 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,4 @@ | ||
REQUESTS_TIMEOUT = 30 | ||
DEFAULT_TIMEZONE = "America/Buenos_Aires" | ||
|
||
VALID_STATUS_CODES = [200, 203, 302] |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
from pydatajson.helpers import is_working_url | ||
from pydatajson.readers import read_catalog | ||
from pydatajson.reporting import generate_datasets_summary | ||
|
||
|
||
class StatusIndicatorsGenerator(object): | ||
|
||
def __init__(self, catalog, validator=None): | ||
self.download_url_ok = None | ||
self.catalog = read_catalog(catalog) | ||
self.summary = generate_datasets_summary(self.catalog, | ||
validator=validator) | ||
|
||
def datasets_cant(self): | ||
return len(self.summary) | ||
|
||
def distribuciones_cant(self): | ||
return sum(ds['cant_distribuciones'] for ds in self.summary) | ||
|
||
def datasets_meta_ok_cant(self): | ||
return sum(ds['estado_metadatos'] == 'OK' for ds in self.summary) | ||
|
||
def datasets_meta_error_cant(self): | ||
return sum(ds['estado_metadatos'] == 'ERROR' for ds in self.summary) | ||
|
||
def datasets_meta_ok_pct(self): | ||
return self._get_dataset_percentage(self.datasets_meta_ok_cant) | ||
|
||
def datasets_con_datos_cant(self): | ||
return sum(ds['tiene_datos'] == 'SI' for ds in self.summary) | ||
|
||
def datasets_sin_datos_cant(self): | ||
return sum(ds['tiene_datos'] == 'NO' for ds in self.summary) | ||
|
||
def datasets_con_datos_pct(self): | ||
return self._get_dataset_percentage(self.datasets_con_datos_cant) | ||
|
||
def distribuciones_download_url_ok_cant(self): | ||
return self.download_url_ok or self._validate_download_urls() | ||
|
||
def distribuciones_download_url_error_cant(self): | ||
return self.distribuciones_cant() - \ | ||
self.distribuciones_download_url_ok_cant() | ||
|
||
def distribuciones_download_url_ok_pct(self): | ||
total = self.distribuciones_cant() | ||
if not total: | ||
return None | ||
return \ | ||
round(float(self.distribuciones_download_url_ok_cant()) / total, 4) | ||
|
||
def _validate_download_urls(self): | ||
result = 0 | ||
for dataset in self.catalog.get('dataset', []): | ||
for distribution in dataset.get('distribution', []): | ||
valid = is_working_url(distribution.get('downloadURL', '')) | ||
result += valid | ||
# Guardo el resultado una vez calculado | ||
self.download_url_ok = result | ||
return result | ||
|
||
def _get_dataset_percentage(self, indicator): | ||
total = self.datasets_cant() | ||
if not total: | ||
return None | ||
return round(float(indicator()) / total, 4) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,3 +15,4 @@ pycallgraph | |
setuptools>=38.6 | ||
wheel>=0.31 | ||
vcrpy | ||
requests_mock |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
import os.path | ||
import unittest | ||
import re | ||
|
||
import requests_mock | ||
|
||
from pydatajson.status_indicators_generator import StatusIndicatorsGenerator | ||
|
||
try: | ||
import mock | ||
except ImportError: | ||
from unittest import mock | ||
|
||
|
||
class TestStatusIndicatorsGeneratorTestCase(unittest.TestCase): | ||
SAMPLES_DIR = os.path.join("tests", "samples") | ||
|
||
@classmethod | ||
def get_sample(cls, sample_filename): | ||
return os.path.join(cls.SAMPLES_DIR, sample_filename) | ||
|
||
@classmethod | ||
def setUpClass(cls): | ||
cls.gen_justicia = StatusIndicatorsGenerator( | ||
cls.get_sample('catalogo_justicia.json')) | ||
cls.gen_full_data = StatusIndicatorsGenerator( | ||
cls.get_sample('full_data.json')) | ||
cls.gen_empty = StatusIndicatorsGenerator( | ||
cls.get_sample('invalid_catalog_empty.json')) | ||
|
||
def test_just_datasets_cant(self): | ||
self.assertEqual(16, self.gen_justicia.datasets_cant()) | ||
|
||
def test_full_datasets_cant(self): | ||
self.assertEqual(2, self.gen_full_data.datasets_cant()) | ||
|
||
def test_empty_datasets_cant(self): | ||
self.assertEqual(0, self.gen_empty.datasets_cant()) | ||
|
||
def test_just_distribuciones_cant(self): | ||
self.assertEqual(56, self.gen_justicia.distribuciones_cant()) | ||
|
||
def test_full_distribuciones_cant(self): | ||
self.assertEqual(2, self.gen_full_data.distribuciones_cant()) | ||
|
||
def test_empty_distribuciones_cant(self): | ||
self.assertEqual(0, self.gen_empty.distribuciones_cant()) | ||
|
||
def test_just_datasets_meta_ok_cant(self): | ||
self.assertEqual(15, self.gen_justicia.datasets_meta_ok_cant()) | ||
|
||
def test_full_datasets_meta_ok_cant(self): | ||
self.assertEqual(2, self.gen_full_data.datasets_meta_ok_cant()) | ||
|
||
def test_empty_datasets_meta_ok_cant(self): | ||
self.assertEqual(0, self.gen_empty.datasets_meta_ok_cant()) | ||
|
||
def test_just_datasets_meta_error_cant(self): | ||
self.assertEqual(1, self.gen_justicia.datasets_meta_error_cant()) | ||
|
||
def test_full_datasets_meta_error_cant(self): | ||
self.assertEqual(0, self.gen_full_data.datasets_meta_error_cant()) | ||
|
||
def test_empty_datasets_meta_error_cant(self): | ||
self.assertEqual(0, self.gen_empty.datasets_meta_error_cant()) | ||
|
||
def test_just_datasets_meta_ok_pct(self): | ||
self.assertEqual(0.9375, self.gen_justicia.datasets_meta_ok_pct()) | ||
|
||
def test_full_datasets_meta_ok_pct(self): | ||
self.assertEqual(1.0, self.gen_full_data.datasets_meta_ok_pct()) | ||
|
||
def test_empty_datasets_meta_ok_pct(self): | ||
self.assertEqual(None, self.gen_empty.datasets_meta_ok_pct()) | ||
|
||
def test_just_datasets_con_datos_cant(self): | ||
self.assertEqual(16, self.gen_justicia.datasets_con_datos_cant()) | ||
|
||
def test_full_datasets_con_datos_cant(self): | ||
self.assertEqual(1, self.gen_full_data.datasets_con_datos_cant()) | ||
|
||
def test_empty_datasets_con_datos_cant(self): | ||
self.assertEqual(0, self.gen_empty.datasets_con_datos_cant()) | ||
|
||
def test_just_datasets_sin_datos_cant(self): | ||
self.assertEqual(0, self.gen_justicia.datasets_sin_datos_cant()) | ||
|
||
def test_full_datasets_sin_datos_cant(self): | ||
self.assertEqual(1, self.gen_full_data.datasets_sin_datos_cant()) | ||
|
||
def test_empty_datasets_sin_datos_cant(self): | ||
self.assertEqual(0, self.gen_empty.datasets_sin_datos_cant()) | ||
|
||
def test_just_datasets_con_datos_pct(self): | ||
self.assertEqual(1, self.gen_justicia.datasets_con_datos_pct()) | ||
|
||
def test_full_datasets_con_datos_pct(self): | ||
self.assertEqual(0.5, self.gen_full_data.datasets_con_datos_pct()) | ||
|
||
def test_empty_datasets_con_datos_pct(self): | ||
self.assertEqual(None, self.gen_empty.datasets_con_datos_pct()) | ||
|
||
@requests_mock.Mocker() | ||
def test_just_distribuciones_download_url_ok_cant(self, req_mock): | ||
req_mock.head(requests_mock.ANY, text='resp') | ||
self.assertEqual( | ||
56, self.gen_justicia.distribuciones_download_url_ok_cant()) | ||
|
||
@requests_mock.Mocker() | ||
def test_full_distribuciones_download_url_ok_cant(self, req_mock): | ||
req_mock.head(re.compile('/convocatorias-abiertas-anio-2015.pdf'), | ||
status_code=404) | ||
req_mock.head(re.compile('/convocatorias-abiertas-anio-2015.csv'), | ||
status_code=200) | ||
self.assertEqual( | ||
1, self.gen_full_data.distribuciones_download_url_ok_cant()) | ||
|
||
def test_empty_distribuciones_download_url_ok_cant(self): | ||
self.assertEqual( | ||
0, self.gen_empty.distribuciones_download_url_ok_cant()) | ||
|
||
@requests_mock.Mocker() | ||
def test_just_distribuciones_download_url_error_cant(self, req_mock): | ||
req_mock.head(requests_mock.ANY, text='resp') | ||
self.assertEqual( | ||
0, self.gen_justicia.distribuciones_download_url_error_cant()) | ||
|
||
@requests_mock.Mocker() | ||
def test_full_distribuciones_download_url_error_cant(self, req_mock): | ||
req_mock.head(re.compile('/convocatorias-abiertas-anio-2015.pdf'), | ||
status_code=404) | ||
req_mock.head(re.compile('/convocatorias-abiertas-anio-2015.csv'), | ||
status_code=200) | ||
self.assertEqual( | ||
1, self.gen_full_data.distribuciones_download_url_error_cant()) | ||
|
||
def test_empty_distribuciones_download_url_error_cant(self): | ||
self.assertEqual( | ||
0, self.gen_empty.distribuciones_download_url_error_cant()) | ||
|
||
@requests_mock.Mocker() | ||
def test_just_distribuciones_download_url_ok_pct(self, req_mock): | ||
req_mock.head(requests_mock.ANY, text='resp') | ||
self.assertEqual( | ||
1, self.gen_justicia.distribuciones_download_url_ok_pct()) | ||
|
||
@requests_mock.Mocker() | ||
def test_full_distribuciones_download_url_ok_pct(self, req_mock): | ||
req_mock.head(re.compile('/convocatorias-abiertas-anio-2015.pdf'), | ||
status_code=404) | ||
req_mock.head(re.compile('/convocatorias-abiertas-anio-2015.csv'), | ||
status_code=200) | ||
self.assertEqual( | ||
0.5, self.gen_full_data.distribuciones_download_url_ok_pct()) | ||
|
||
def test_empty_distribuciones_download_url_ok_pct(self): | ||
self.assertEqual( | ||
None, self.gen_empty.distribuciones_download_url_ok_pct()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.