Skip to content

Commit

Permalink
Make Web API optional
Browse files Browse the repository at this point in the history
  • Loading branch information
fpagnoux authored Aug 15, 2018
2 parents 27fc8bd + b8c3a4d commit b296504
Show file tree
Hide file tree
Showing 21 changed files with 120 additions and 60 deletions.
4 changes: 2 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
name: Install dependencies
command: |
pip install --upgrade pip twine wheel
pip install --editable .[test] --upgrade
pip install --editable .[dev] --upgrade
# pip install --editable git+https://github.com/openfisca/country-template.git@BRANCH_NAME#egg=OpenFisca-Country-Template # use a specific branch of OpenFisca-Country-Template
- save_cache:
Expand Down Expand Up @@ -88,7 +88,7 @@ jobs:
name: Install dependencies
command: |
pip install --upgrade pip twine wheel
pip install --editable .[test] --upgrade
pip install --editable .[dev] --upgrade
# pip install --editable git+https://github.com/openfisca/country-template.git@BRANCH_NAME#egg=OpenFisca-Country-Template # use a specific branch of OpenFisca-Country-Template
- save_cache:
Expand Down
34 changes: 34 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,38 @@
# Changelog

# 24.0.0 [#703](https://github.com/openfisca/openfisca-core/pull/703)

#### Breaking changes

##### Only install the Web API dependencies as an opt-in:

- `pip install OpenFisca-Core` will _not_ install the Web API anymore.
- `pip install OpenFisca-Core[web-api]` will.

Country package maintainers who still want to provide the Web API by default with their package (**recommended**) should update their `setup.py`:
- In the `install_requires` section, replace `'OpenFisca-Core >= 23.3, < 24.0'` by `'OpenFisca-Core[api] >= 24.0, < 25.0'`
- See [example](https://github.com/openfisca/country-template/commit/b75eea97d8d22091a3f13a580118ce45b16f4294)

##### Change default Web API port to 5000:

- `openfisca serve` will now serve by default on the `5000` port instead of `6000` (blocked by Chrome).

##### Rename OpenFisca Web Api package to `openfisca_web_api`:

- Transparent for users of the `openfisca serve` command.
- Users who used to manually import `openfisca_web_api_preview` must know import `openfisca_web_api`.

##### Rename development dependencies from `test` to `dev`:

- Developpers should now run `pip install --editable .[dev]` instead of `pip install --editable .[test]` to install them.

#### New features

- In the `/spec` route:
- Indicate the served country package version as API version (instead of `0.1.0`).
- Infer the host URL from the requests, instead of relying on the undocumented `SERVER_NAME` environnement variable.
- The use of the `SERVER_NAME` environnement variable is therefore deprecated and without effect.

### 23.5.2 [#710](https://github.com/openfisca/openfisca-core/pull/710)

- Revert the undesired side effects of `23.4.0` on the `parameters/` overview route of the Web API
Expand Down Expand Up @@ -116,6 +149,7 @@ For instance, `/parameter/benefits/basic_income` contains:

Note that this route doesn't _recursively_ explore the node, and only exposes its direct children name and description.


### 23.3.2 [#702](https://github.com/openfisca/openfisca-core/pull/702)

Minor Change without any impact for country package developers and users:
Expand Down
2 changes: 1 addition & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
recursive-include openfisca_core/scripts *
include openfisca_web_api_preview/openAPI.yml
include openfisca_web_api/openAPI.yml
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ This package contains the core features of OpenFisca, which are meant to be used

## Environment

OpenFisca runs on Python 3.6, or more recent versions.
OpenFisca runs on Python 3.6. More recent versions should work, but are not tested.

Backward compatibility with Python 2.7 is maintained for now, but will be dropped from January 1st, 2019.

Expand All @@ -19,7 +19,7 @@ If you want to contribute to OpenFisca-Core itself, welcome! To install it local
```bash
git clone https://github.com/openfisca/openfisca-core.git
cd openfisca-core
pip install --editable ".[test]"
pip install --editable .[dev]
```

## Testing
Expand All @@ -44,12 +44,12 @@ nosetests core/test_parameters.py:test_parameter_for_period

## Serving the API

OpenFisca-Core provides a Web-API. It is served on the `6000` port.
OpenFisca-Core provides a Web-API. It is by default served on the `5000` port.

To run it with the mock country package `openfisca_country_template` and another port value as `5000`, run:
To run it with the mock country package `openfisca_country_template` and another port value such as `2000`, run:

```sh
openfisca serve --country-package openfisca_country_template --port 5000
openfisca serve --country-package openfisca_country_template --port 2000
```

To read more about the `openfisca serve` command, check out its [documentation](https://openfisca.readthedocs.io/en/latest/openfisca_serve.html).
Expand All @@ -59,7 +59,7 @@ By default, the Web API uses 3 workers to avoid [this issue](http://stackoverflo
You can test that the API is running by executing the command:

```sh
curl http://localhost:5000/parameters
curl http://localhost:2000/parameters
```
For more information about endpoints and input formatting, see the [official documentation](http://openfisca.org/doc/openfisca-web-api).

Expand Down
2 changes: 1 addition & 1 deletion openfisca_core/scripts/openfisca_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import argparse
import sys

from openfisca_web_api_preview.scripts.serve import define_command_line_options, main as serve
from openfisca_web_api.scripts.serve import define_command_line_options, main as serve


"""
Expand Down
File renamed without changes.
23 changes: 13 additions & 10 deletions openfisca_web_api_preview/app.py → openfisca_web_api/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,24 @@

from __future__ import unicode_literals, print_function, division, absolute_import
from copy import deepcopy
import logging
import os
from os import linesep
from flask import Flask, jsonify, abort, request, make_response
from werkzeug.contrib.fixers import ProxyFix
from flask_cors import CORS
import traceback

import dpath

from openfisca_core.simulations import Simulation, SituationParsingError
from openfisca_core.commons import to_unicode
from openfisca_core.indexed_enums import Enum
from openfisca_web_api_preview.loader import build_data
import traceback
import logging
from openfisca_web_api.loader import build_data
from openfisca_web_api.errors import handle_import_error

try:
from flask import Flask, jsonify, abort, request, make_response
from flask_cors import CORS
from werkzeug.contrib.fixers import ProxyFix
except ImportError as error:
handle_import_error(error)

log = logging.getLogger('gunicorn.error')

Expand All @@ -25,14 +29,14 @@ def init_tracker(url, idsite, tracker_token):
from openfisca_tracker.piwik import PiwikTracker
tracker = PiwikTracker(url, idsite, tracker_token)

info = linesep.join(['You chose to activate the `tracker` module. ',
info = os.linesep.join(['You chose to activate the `tracker` module. ',
'Tracking data will be sent to: ' + url,
'For more information, see <https://github.com/openfisca/openfisca-core#tracker-configuration>.'])
log.info(info)
return tracker

except ImportError:
message = linesep.join([traceback.format_exc(),
message = os.linesep.join([traceback.format_exc(),
'You chose to activate the `tracker` module, but it is not installed.',
'For more information, see <https://github.com/openfisca/openfisca-core#tracker-installation>.'])
log.warn(message)
Expand Down Expand Up @@ -95,7 +99,6 @@ def get_variable(id):

@app.route('/spec')
def get_spec():

# Ugly Python2-compatible way
response = {}
response.update(data['openAPI_spec'])
Expand Down
10 changes: 10 additions & 0 deletions openfisca_web_api/errors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-

from __future__ import unicode_literals
import logging

log = logging.getLogger('gunicorn.error')


def handle_import_error(error):
raise ImportError("OpenFisca is missing some dependencies to run the Web API: '{}'. To install them, run `pip install openfisca_core[web-api]`.".format(error))
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# -*- coding: utf-8 -*-

from __future__ import unicode_literals, print_function, division, absolute_import
from openfisca_web_api_preview.loader.parameters import build_parameters, build_parameters_overview
from openfisca_web_api_preview.loader.variables import build_variables
from openfisca_web_api_preview.loader.spec import build_openAPI_specification

from openfisca_web_api.loader.parameters import build_parameters, build_parameters_overview
from openfisca_web_api.loader.variables import build_variables
from openfisca_web_api.loader.spec import build_openAPI_specification


def extract_description(items):
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ def build_openAPI_specification(tax_benefit_system, country_package_metadata):
country_package_name = country_package_metadata['name'].title()
spec['info']['title'] = spec['info']['title'].replace("{COUNTRY_PACKAGE_NAME}", country_package_name)
spec['info']['description'] = spec['info']['description'].replace("{COUNTRY_PACKAGE_NAME}", country_package_name)
spec['info']['version'] = country_package_metadata['version']

for entity in tax_benefit_system.entities:
name = entity.key.title()
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ swagger: "2.0"
info:
title: "{COUNTRY_PACKAGE_NAME} Web API"
description: "The OpenFisca Web API lets you get up-to-date information and formulas included in the {COUNTRY_PACKAGE_NAME} legislation."
version: "0.1.0"
termsOfService: "http://openfisca.org/doc/publishing.html"
version: null
termsOfService: "https://openfisca.org/doc/publishing"
contact:
email: "contact@openfisca.fr"
license:
name: "AGPL"
url: "https://www.gnu.org/licenses/agpl-3.0.html"
url: "https://www.gnu.org/licenses/agpl-3.0"
host: null
schemes:
- "https"
Expand All @@ -17,12 +17,12 @@ tags:
description: "A parameter is a numeric property of the legislation that can evolve over time."
externalDocs:
description: "Parameter official documentation"
url: "http://openfisca.org/doc/parameters.html"
url: "https://openfisca.org/doc/parameters"
- name: "Variables"
description: "A variable depends on a person, or an entity (e.g. zip code, salary, income tax)."
externalDocs:
description: "Variable official documentation"
url: "http://openfisca.org/doc/variables.html"
url: "https://openfisca.org/doc/variables"
- name: "Calculations"
- name: "Documentation"
paths:
Expand All @@ -39,7 +39,7 @@ paths:
parameters:
- in: "body"
name: "Situation"
description: 'Describe the situation (persons and entities). Add the variable you wish to calculate in the proper entity, with null as the value. Learn more in our official documentation: http://openfisca.org/doc/openfisca-web-api/input-output-data.html'
description: 'Describe the situation (persons and entities). Add the variable you wish to calculate in the proper entity, with null as the value. Learn more in our official documentation: https://openfisca.org/doc/openfisca-web-api/input-output-data'
required: true
schema:
$ref: '#/definitions/SituationInput'
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,23 @@
import logging
import argparse

from gunicorn.app.base import BaseApplication
from gunicorn.six import iteritems
from gunicorn import config

from openfisca_core.scripts import add_tax_benefit_system_arguments, build_tax_benefit_system
from openfisca_web_api_preview.app import create_app
from openfisca_web_api.app import create_app
from openfisca_web_api.errors import handle_import_error

try:
from gunicorn.app.base import BaseApplication
from gunicorn.six import iteritems
from gunicorn import config
except ImportError as error:
handle_import_error(error)


"""
Define the `openfisca serve` command line interface.
"""

DEFAULT_PORT = '6000'
DEFAULT_PORT = '5000'
HOST = '127.0.0.1'
DEFAULT_WORKERS_NUMBER = '3'

Expand Down
49 changes: 28 additions & 21 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,33 @@
from __future__ import unicode_literals, print_function, division, absolute_import
from setuptools import setup, find_packages

general_requirements = [
'Biryani[datetimeconv] >= 0.10.8',
'dpath == 1.4.0',
'enum34 >= 1.1.6',
'future',
'numpy >= 1.11, < 1.15',
'psutil == 5.4.6',
'PyYAML >= 3.10',
'sortedcontainers == 1.5.9',
]

api_requirements = [
'flask == 1.0.2',
'flask-cors == 3.0.2',
'gunicorn >= 19.7.1',
]

dev_requirements = [
'nose',
'flake8 >= 3.4.0, < 3.5.0',
'openfisca-country-template >= 3.2.3, < 4.0.0',
'openfisca-extension-template >= 1.1.3, < 2.0.0',
] + api_requirements

setup(
name = 'OpenFisca-Core',
version = '23.5.2',
version = '24.0.0',
author = 'OpenFisca Team',
author_email = 'contact@openfisca.org',
classifiers = [
Expand All @@ -30,30 +53,14 @@
'console_scripts': ['openfisca=openfisca_core.scripts.openfisca_command:main', 'openfisca-run-test=openfisca_core.scripts.run_test:main'],
},
extras_require = {
'test': [
'nose',
'flake8 >= 3.4.0, < 3.5.0',
'openfisca-country-template >= 3.2.3, < 4.0.0',
'openfisca-extension-template >= 1.1.3, < 2.0.0',
],
'web-api': api_requirements,
'dev': dev_requirements,
'tracker': [
'openfisca-tracker == 0.4.0',
]
],
},
include_package_data = True, # Will read MANIFEST.in
install_requires = [
'Biryani[datetimeconv] >= 0.10.8',
'dpath == 1.4.0',
'enum34 >= 1.1.6',
'future',
'flask == 1.0.2',
'flask-cors == 3.0.2',
'gunicorn >= 19.7.1',
'numpy >= 1.11, < 1.15',
'psutil == 5.4.6',
'PyYAML >= 3.10',
'sortedcontainers == 1.5.9',
],
install_requires = general_requirements,
message_extractors = {
'openfisca_core': [
('**.py', 'python', None),
Expand Down
2 changes: 1 addition & 1 deletion tests/web_api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from __future__ import unicode_literals, print_function, division, absolute_import
import pkg_resources
from openfisca_web_api_preview.app import create_app
from openfisca_web_api.app import create_app
from openfisca_core.scripts import build_tax_benefit_system

TEST_COUNTRY_PACKAGE_NAME = 'openfisca_country_template'
Expand Down
2 changes: 1 addition & 1 deletion tests/web_api/basic_case/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals, print_function, division, absolute_import
import pkg_resources
from openfisca_web_api_preview.app import create_app
from openfisca_web_api.app import create_app
from openfisca_core.scripts import build_tax_benefit_system

TEST_COUNTRY_PACKAGE_NAME = 'openfisca_country_template'
Expand Down
2 changes: 1 addition & 1 deletion tests/web_api/case_with_extension/test_extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from http.client import OK
from nose.tools import assert_equal
from openfisca_core.scripts import build_tax_benefit_system
from openfisca_web_api_preview.app import create_app
from openfisca_web_api.app import create_app


TEST_COUNTRY_PACKAGE_NAME = 'openfisca_country_template'
Expand Down
2 changes: 1 addition & 1 deletion tests/web_api/test_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from nose.tools import assert_equal

from openfisca_core.parameters import load_parameter_file
from openfisca_web_api_preview.loader.parameters import build_api_values_history, get_value
from openfisca_web_api.loader.parameters import build_api_values_history, get_value


dir_path = os.path.join(os.path.dirname(__file__), 'assets')
Expand Down

0 comments on commit b296504

Please sign in to comment.