Esempio n. 1
0
def get_data():
    """Get Data resource collection.

    .. :quickref: Data; Access de-identified survey data.

    Args:
        Non-REST, Python API for function has no arguments.

    Query Args:
        None

    Returns:
        json: Collection for resource.

    Details:
        Query de-identified PMA2020 survey data.

    Example:
        .. code-block:: json
           :caption: GET http://api.pma2020.org/v1/data
           :name: example-of-collection-data

            {"Documentation example not available."}
    """
    all_data = data_refined_query(request.args)
    data = [d.full_json() for d in all_data]
    return QuerySetApiResult(data, 'json')
Esempio n. 2
0
def get_country(code):
    """Country resource entity GET method.

    .. :quickref: Countries; Access a specific country by its code.

    Args:
        code (str): Identification for resource entity.

    Query Args:
        None

    Returns:
        json: Entity of resource.

    Details:
        Access a specific PMA2020 country with publicly available data, by its
        code.

    Example:
        .. code-block:: json
           :caption: GET http://api.pma2020.org/v1/countries/CODE
           :name: example-of-instance-country

            {"Documentation example not available."}
    """
    lang = request.args.get('_lang')
    country = Country.query.filter_by(country_code=code).first()
    json_obj = country.to_json(lang=lang)
    return QuerySetApiResult(json_obj, 'json')
Esempio n. 3
0
def get_datum(code):
    """Get data resource entity.

    .. :quickref: Data; Access a specific datum by its code.

    Args:
        code (str): Identification for resource entity.

    Query Args:
        None

    Returns:
        json: Entity of resource.

    Details:
        Access a specific data record, by its code.

    Example:
        .. code-block:: json
           :caption: GET http://api.pma2020.org/v1/data/CODE
           :name: example-of-instance-datum

            {"Documentation example not available."}
    """
    data = Data.query.filter_by(code=code).first()
    json_obj = data.full_json()
    return QuerySetApiResult(json_obj, 'json')
Esempio n. 4
0
def get_surveys():
    """Survey resource collection GET method.

    .. :quickref: Survey rounds; Get collection of survey rounds.

    Args:
        Non-REST, Python API for function has no arguments.

    Query Args:
        None

    Returns:
        json: Collection for resource.

    Details:
        Gets a list of all PMA2020 country survey rounds with publicly
        available data.

    Example:
        .. code-block:: json
           :caption: GET http://api.pma2020.org/v1/surveys
           :name: example-of-collection-surveys

            {
              "metadata": {
                "..."
              },
              "resultSize": 48,
              "results": [
                {
                  "country.id": "GH",
                  "country.label": "Ghana",
                  "country.order": 4,
                  "country.region": "Africa",
                  "country.subregion": "Western Africa",
                  "end_date": "2013-10-01",
                  "id": "PMA2013_GHR1",
                  "order": 101,
                  "pma_code": "GHR1",
                  "round": 1,
                  "start_date": "2013-09-01",
                  "type": "PMA2020",
                  "year": 2013
                },
                "..."
              ]
            }
    """
    # Query by year, country, round
    # print(request.args)
    surveys = Survey.query.all()
    data = [s.full_json() for s in surveys]
    return QuerySetApiResult(data, 'json')
Esempio n. 5
0
def get_indicators():
    """Get Indicator resource collection.

    .. :quickref: Indicators; Get collection of available indicators.

    Args:
        Non-REST, Python API for function has no arguments.

    Query Args:
        None

    Returns:
        json: Collection for resource.

    Details:
        Gets a list of all PMA2020 indicators with publicly available data.

    Example:
        .. code-block:: json
           :caption: GET http://api.pma2020.org/v1/indicators
           :name: example-of-collection-indicators

            {
              "metadata": {
                "..."
              },
              "resultSize": 112,
              "results": [
                {
                  "definition": "Percent of women ages 15\u201349 who are using (or whose partners are using) any contraceptive method at the time of the survey",
                  "denominator": "All women, ages 15-49",
                  "domain": "Women's reproductive health",
                  "favoriteOrder": 1,
                  "id": "cp_all",
                  "isFavorite": true,
                  "label": "Current use of any contraceptive method (all women)",
                  "level1": "Family planning utilization",
                  "level2": "Contraceptive use",
                  "measurementType": "percent",
                  "order": 11,
                  "type": "indicator",
                  "url": "http://api.pma2020.org/v1/indicators/cp_all"
                },
                "..."
              ]
            }
    """
    indicators = Indicator.query.all()
    data = [i.full_json(endpoint='api.get_indicator') for i in indicators]
    return QuerySetApiResult(data, 'json')
Esempio n. 6
0
def get_survey(code):
    """Survey resource entity GET method.

    .. :quickref: Survey rounds; Access a specific survey round by its code

    Args:
        code (str): Identification for resource entity.

    Query Args:
        None

    Returns:
        json: Entity of resource.

    Details:
        Access a specific PMA2020 country survey round with publicly
        available data, by its code.

    Example:
        .. code-block:: json
           :caption: GET http://api.pma2020.org/v1/surveys/PMA2013_GHR1
           :name: example-of-instance-survey

            {
              "metadata": {
                "..."
              },
              "resultSize": 13,
              "results": {
                "country.id": "GH",
                "country.label": "Ghana",
                "country.order": 4,
                "country.region": "Africa",
                "country.subregion": "Western Africa",
                "end_date": "2013-10-01",
                "id": "PMA2013_GHR1",
                "order": 101,
                "pma_code": "GHR1",
                "round": 1,
                "start_date": "2013-09-01",
                "type": "PMA2020",
                "year": 2013
              }
            }
    """
    survey = Survey.query.filter_by(code=code).first()
    json_obj = survey.full_json()
    return QuerySetApiResult(json_obj, 'json')
Esempio n. 7
0
def get_indicator(code):
    """Get Indicator resource entity.

    .. :quickref: Indicators; Access a specific indicator by its code

    Args:
        code (str): Identification for resource entity.

    Query Args:
        None

    Returns:
        json: Entity of resource.

    Details:
        Access a specific PMA2020 indicator with publicly available data, by
        its code.

    Example:
        .. code-block:: json
           :caption: GET http://api.pma2020.org/v1/indicators/CODE
           :name: example-of-instance-indicator

            {
              "metadata": {
                "..."
              },
              "resultSize": 12,
              "results": {
                "definition": "Percent of women ages 15\u201349 who are using (or whose partners are using) any contraceptive method at the time of the survey",
                "denominator": "All women, ages 15-49",
                "domain": "Women's reproductive health",
                "favoriteOrder": 1,
                "id": "cp_all",
                "isFavorite": true,
                "label": "Current use of any contraceptive method (all women)",
                "level1": "Family planning utilization",
                "level2": "Contraceptive use",
                "measurementType": "percent",
                "order": 11,
                "type": "indicator"
              }
            }
    """
    indicator = Indicator.query.filter_by(code=code).first()
    json_obj = indicator.full_json()
    return QuerySetApiResult(json_obj, 'json')
Esempio n. 8
0
def get_countries():
    """Country resource collection GET method.

    .. :quickref: Countries; Get collection of countries.

    Args:
        Non-REST, Python API for function has no arguments.

    Query Args:
        None

    Returns:
        json: Collection for resource.

    Details:
        Gets a list of all PMA2020 countries with publicly available data.

    Example:
        .. code-block:: json
           :caption: GET http://api.pma2020.org/v1/countries
           :name: example-of-collection-countries

            {
              "metadata": {
                "..."
              },
              "resultSize": 10,
              "results": [
                {
                  "id": "BF",
                  "label": "Burkina Faso",
                  "order": 1,
                  "region": "Africa",
                  "subregion": "Western Africa"
                },
                "..."
              ]
            }
    """
    countries = Country.query.all()
    data = [c.full_json() for c in countries]
    return QuerySetApiResult(data, 'json')
Esempio n. 9
0
def show_version():
    """Show API version data.

    .. :quickref: Version; API versioning data.

    Args:
        n/a

    Returns:
        String: Version number.

    Details:
        Displays API's 2-part semantic version number. ALso displays versioning
        for datasets used.

    Example:
        .. code-block:: json
           :caption: GET /v1/version
           :name: example-of-endpoint-version

            {
              "datasetMetadata": [
                {
                  "createdOn": "Fri, 13 Jul 2018 20:25:42 GMT",
                  "hash": "339ce036bdee399d449f95a1d4b3bb8f",
                  "name": "api_data-2018.03.19-v29-SAS",
                  "type": "api"
                },
                {
                  "createdOn": "Fri, 13 Jul 2018 20:25:43 GMT",
                  "hash": "469542a93241da0af80269b6d7352600",
                  "name": "ui_data-2017.10.02-v4-jef",
                  "type": "ui"
                }
              ],
              "version": "0.1.9"
            }
    """
    return jsonify(QuerySetApiResult.metadata())
Esempio n. 10
0
def get_text(code):
    """Get Text resource entity.

    .. :quickref: Text; Access a specific piece of text by its code

    Args:
        code (str): Identification for resource entity.

    Query Args:
        None

    Returns:
        json: Entity of resource.

    Details:
        Access a specific piece of text related to surveys and metadata, by its
        code.

    Example:
        .. code-block:: json
           :caption: GET http://api.pma2020.org/v1/texts/6EA0At85
           :name: example-of-instance-text

            {
              "metadata": {
                "..."
              },
              "resultSize": 3,
              "results": {
                "id": "6EA0At85",
                "langCode": "en",
                "text": "Kinshasa Province"
              }
            }
    """
    text = EnglishString.query.filter_by(code=code).first()
    json_obj = text.to_json()
    return QuerySetApiResult(json_obj, 'json')
Esempio n. 11
0
def get_resources():
    """Return API resource routes.

    .. :quickref: Resources list; Lists all of the available API resources and
     their URLs.

    Args:
        Non-REST, Python API for function has no arguments.

    Query Args:
        None

    Returns:
        json: List of resources.

    Details:
        The resources object returned is split up into two main parts--results,
        and metadata. The metadata object contains information about the
        datasets used, including the client-specific "ui" dataset. The results
        object is the main object, which returns a list of resources,
        consisting of the resource name and its URL. The resource can then be
        accessed by using the literal URL string shown.

    Example:
        .. code-block:: json
           :caption: GET http://api.pma2020.org/v1/resources
           :name: example-of-collection-resources

            {
              "metadata": {
                "datasetMetadata": [
                  {
                    "createdOn": "Fri, 13 Jul 2018 20:25:42 GMT",
                    "hash": "339ce036bdee399d449f95a1d4b3bb8f",
                    "name": "api_data-2018.03.19-v29-SAS",
                    "type": "api"
                  },
                  {
                    "createdOn": "Fri, 13 Jul 2018 20:25:43 GMT",
                    "hash": "469542a93241da0af80269b6d7352600",
                    "name": "ui_data-2017.10.02-v4-jef",
                    "type": "ui"
                  }
                ],
                "version": "0.1.9"
              },
              "resultSize": 1,
              "results": {
                "resources": [
                  {
                    "name": "countries",
                    "resource": "http://api.pma2020.org/v1/countries"
                  },
                  {
                    "name": "surveys",
                    "resource": "http://api.pma2020.org/v1/surveys"
                  },
                  {
                    "name": "texts",
                    "resource": "http://api.pma2020.org/v1/texts"
                  },
                  {
                    "name": "indicators",
                    "resource": "http://api.pma2020.org/v1/indicators"
                  },
                  {
                    "name": "data",
                    "resource": "http://api.pma2020.org/v1/data"
                  },
                  {
                    "name": "characteristicGroups",
                    "resource": "http://api.pma2020.org/v1/characteristicGroups"
                  }
                ]
              }
            }
    """
    resource_endpoints = (('countries', 'api.get_countries'),
                          ('surveys', 'api.get_surveys'), ('texts',
                                                           'api.get_texts'),
                          ('indicators',
                           'api.get_indicators'), ('data', 'api.get_data'),
                          ('characteristicGroups',
                           'api.get_characteristic_groups'))
    json_obj = {
        'resources': [{
            'name': name,
            'resource': url_for(route, _external=True)
        } for name, route in resource_endpoints]
    }
    return QuerySetApiResult(json_obj, 'json')
Esempio n. 12
0
def get_texts():
    """Get Text resource collection.

    .. :quickref: Text; Get collection of various text related to surveys and
     metadata.

    Args:
        Non-REST, Python API for function has no arguments.

    Query Args:
        None

    Returns:
        json: Collection for resource.

    Details:
        Get a list of various texts related to surveys and metadata. Default
        language displayed is English (en).

    Example:
        .. code-block:: json
           :caption: GET http://api.pma2020.org/v1/texts
           :name: example-of-collection-texts

            {
              "metadata": {
                "..."
              },
              "resultSize": 515,
              "results": [
                {
                  "id": "6EA0At85",
                  "langCode": "en",
                  "text": "Kinshasa Province"
                },
                {
                  "id": "K9pC3w90",
                  "langCode": "en",
                  "text": "2013 Round 1"
                },
                {
                  "id": "0G2e7W61",
                  "langCode": "en",
                  "text": "Household / female questionnaire"
                },
                {
                  "id": "noFfI-js",
                  "langCode": "en",
                  "text": "Marital status"
                },
                {
                  "id": "qWyhZCgY",
                  "langCode": "en",
                  "text": "Married vs unmarried"
                },
                "..."
              ]
            }
    """
    english_strings = EnglishString.query.all()
    data = [d.to_json() for d in english_strings]
    return QuerySetApiResult(data, 'json')
Esempio n. 13
0
def dynamic_route(resource: str) -> Union[QuerySetApiResult, str]:
    """Dynamically resource-based routing

    For any model resources that do not have explicit static routes created,
    this route will attempt to return a standardized list of results for that
    model.

    Args:
        resource(str): Resource requested in url of request

    Returns:
        QuerySetApiResult: Records queried for resource
        str: Standard 404

    # TODO 1: Allow for public/non-public access settings. Psuedo code:
    # access_ok = hasattr(model, 'access') and model['access']['api'] \
    #             and model['access']['api']['public']
    # public_attrs = [x for x in model['access']['api']['attributes']
    #                 if x['public']]
    # # filter out key value pairs that are not public
    # # return json

    # TODO 5: Ideally I'd like to use a different approach, i.e. dynamically
    # generate and register a list of routes at server start.
    """

    model = resource_model_map[resource] \
        if resource in resource_model_map else None

    if model is None:
        # TODO 2: There's probably a better way to handle 404's in this case
        msg_404 = 'Error 404: Page not found' + '<br/>'
        resource_h1 = 'The resources available are limited to the following ' \
                      + '<ul>'
        resources: str = '<li>' + \
                         '</li><li>'.join(resource_model_map.keys()) + '</ul>'
        msg = '<br/>'.join([msg_404, resource_h1, resources])
        return msg

    objects: List[Model] = model.query.all()

    if not request.args:
        dict_objs: [{}] = models_to_dicts(objects)
        QuerySetApiResult(record_list=dict_objs, return_format='json')

    query_dir = os.path.join(PROJECT_ROOT_PATH, 'pma_api')
    query_template_path = os.path.join(query_dir, 'python_query_template.py')
    query_tempfile_path = os.path.join(query_dir, 'python_query_tempfile.py')

    # TODO: review https://nedbatchelder.com/blog/201206/
    #  eval_really_is_dangerous.html
    arg_str = ''
    for k, v in request.args.items():
        # TODO 3: Lots of other conversions. Consider as well using the literal
        #  url string rather than request.args
        v = 'True' if v == 'true' else 'False' if v == 'false' else v
        arg_str += '_.{} == {}'.format(k, v)

    with open(query_template_path, 'r') as file:
        txt = file.read()

    # TODO 4: Use actual temp files with random names for concurrency
    with open(query_tempfile_path, 'w') as file:
        txt = txt.replace("'$'", arg_str)
        file.write(txt)
    # noinspection PyUnresolvedReferences
    from pma_api.python_query_tempfile import interpolated_query
    filtered_objs: List[Model] = interpolated_query(objects)
    os.remove(query_tempfile_path)

    dict_objs: [{}] = models_to_dicts(filtered_objs)
    response = QuerySetApiResult(record_list=dict_objs, return_format='json')

    return response