Skip to content
This repository has been archived by the owner on Jan 22, 2021. It is now read-only.

Replace flask_restplus by flask_restx #61

Merged
merged 4 commits into from
Oct 20, 2020
Merged
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
46 changes: 21 additions & 25 deletions jitenshea/webapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,18 @@
"""Flask API for Jitenshea (Bicycle-sharing data)
"""

import daiquiri

from datetime import date, datetime
from dateutil.parser import parse

from werkzeug.routing import BaseConverter

import daiquiri
from flask import jsonify
from flask.json import JSONEncoder
from flask_restplus import inputs
from flask_restplus import Resource, Api
from flask_restx import Api, Resource, inputs
from dateutil.parser import parse
from werkzeug.routing import BaseConverter

from jitenshea import controller
from jitenshea.webapp import app


ISO_DATE = '%Y-%m-%d'
ISO_DATETIME = '%Y-%m-%dT%H:%M:%S'
CITIES = ('lyon', 'bordeaux')
Expand Down Expand Up @@ -53,7 +49,7 @@ def to_python(self, value):
return value.split(',')

def to_url(self, values):
return ','.join(BaseConverter.to_url(value)
return ','.join(super(ListConverter, self).to_url(value=value)
for value in values)

app.url_map.converters['list'] = ListConverter
Expand Down Expand Up @@ -220,8 +216,8 @@ def get(self, city, ids):

@api.route("/<string:city>/daily/station")
class CityDailyStationList(Resource):
@api.doc(parser=daily_list_parser,
description="Daily transactions for all stations")
@api.expect(parser=daily_list_parser)
@api.doc(description="Daily transactions for all stations")
def get(self, city):
check_city(city)
args = daily_list_parser.parse_args()
Expand All @@ -237,8 +233,8 @@ def get(self, city):

@api.route("/<string:city>/timeseries/station/<list:ids>")
class CityTimeseriesStation(Resource):
@api.doc(parser=timeseries_parser,
description="Bicycle station(s) timeseries")
@api.expect(parser=timeseries_parser)
@api.doc(description="Bicycle station(s) timeseries")
def get(self, city, ids):
check_city(city)
args = timeseries_parser.parse_args()
Expand All @@ -252,8 +248,8 @@ def get(self, city, ids):

@api.route("/<string:city>/predict/station/<list:ids>")
class PredictStation(Resource):
@api.doc(parser=predict_parser,
description="Bicycle station(s) prediction")
@api.expect(parser=predict_parser)
@api.doc(description="Bicycle station(s) prediction")
def get(self, city, ids):
check_city(city)
args = predict_parser.parse_args()
Expand All @@ -270,8 +266,8 @@ def get(self, city, ids):

@api.route("/<string:city>/predict/station")
class PredictStationList(Resource):
@api.doc(parser=station_list_parser,
description="Bicycle stations prediction")
@api.expect(parser=station_list_parser)
@api.doc(description="Bicycle stations prediction")
def get(self, city):
check_city(city)
args = station_list_parser.parse_args()
Expand All @@ -283,8 +279,8 @@ def get(self, city):

@api.route("/<string:city>/profile/hourly/station/<list:ids>")
class CityHourlyStation(Resource):
@api.doc(parser=hourly_profile_parser,
description="Bicycle station(s) hourly profile")
@api.expect(parser=station_list_parser)
@api.doc(description="Bicycle station(s) hourly profile")
def get(self, city, ids):
check_city(city)
args = hourly_profile_parser.parse_args()
Expand All @@ -298,8 +294,8 @@ def get(self, city, ids):

@api.route("/<string:city>/profile/daily/station/<list:ids>")
class CityDailyStation(Resource):
@api.doc(parser=daily_profile_parser,
description="Bicycle station(s) daily profile")
@api.expect(parser=station_list_parser)
@api.doc(description="Bicycle station(s) daily profile")
def get(self, city, ids):
check_city(city)
args = daily_profile_parser.parse_args()
Expand All @@ -313,8 +309,8 @@ def get(self, city, ids):

@api.route("/<string:city>/clustering/stations")
class CityClusteredStation(Resource):
@api.doc(parser=clustering_parser,
description="Clustered stations according to K-means algorithm")
@api.expect(parser=station_list_parser)
@api.doc(description="Clustered stations according to K-means algorithm")
def get(self, city):
check_city(city)
args = clustering_parser.parse_args()
Expand All @@ -337,8 +333,8 @@ def get(self, city):

@api.route("/<string:city>/clustering/centroids")
class CityClusterCentroids(Resource):
@api.doc(parser=clustering_parser,
description="Centroids of clusters computed with a K-means algorithm")
@api.expect(parser=station_list_parser)
@api.doc(description="Centroids of clusters computed with a K-means algorithm")
def get(self, city):
check_city(city)
args = clustering_parser.parse_args()
Expand Down
7 changes: 3 additions & 4 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@
LONG_DESCRIPTION = fobj.read()

INSTALL_REQUIRES = ["luigi", "numpy", "pandas", "requests", "psycopg2-binary",
'sqlalchemy', 'lxml', 'xgboost', 'daiquiri', 'Flask==1.0.2',
'flask-restplus==0.12.1', 'sh', 'seaborn', 'scikit-learn',
'tables']
'sqlalchemy', 'lxml', 'xgboost', 'daiquiri',
'flask-restx', 'sh', 'seaborn', 'scikit-learn', 'tables']


setuptools.setup(
Expand All @@ -20,7 +19,7 @@
packages=setuptools.find_packages(),
include_package_data=True,
install_requires=INSTALL_REQUIRES,
extras_require={'dev': ['pytest', 'pytest-sugar', 'ipython', 'ipdb']},
extras_require={'dev': ['pytest', 'pytest-sugar', 'ipython', 'ipdb', 'flake8', 'isort']},

author="Damien Garaud",
author_email='[email protected]',
Expand Down
8 changes: 3 additions & 5 deletions tests/test_webapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@
from datetime import date, datetime, timedelta

import pytest

from jitenshea.webapi import ISO_DATE, ISO_DATETIME, api
from jitenshea.webapp import app
from jitenshea.webapi import api, ISO_DATE, ISO_DATETIME


app.config['TESTING'] = True
api.init_app(app)
Expand Down Expand Up @@ -156,7 +154,7 @@ def test_api_prediction(client):
assert resp.status_code == 200
data = resp.get_json()
# 3 values by default
assert len(data) == 3
assert len(data) == 5
assert 'nb_bikes' in data[0]
assert data[0]['at'] == '1H'

Expand All @@ -183,7 +181,7 @@ def test_api_latest_prediction(client):
assert resp.status_code == 200
data = resp.get_json()['data']
date = resp.get_json()['date']
assert len(data) == 100
assert len(data) >= 100
# in GeoJSON
resp = client.get('/api/bordeaux/predict/station',
query_string={'limit': 5, 'geojson': True})
Expand Down