karec / cookiecutter-flask-restful Goto Github PK
View Code? Open in Web Editor NEWFlask cookiecutter template for builing APIs with flask-restful, including JWT auth, cli, tests, swagger, docker and more
License: MIT License
Flask cookiecutter template for builing APIs with flask-restful, including JWT auth, cli, tests, swagger, docker and more
License: MIT License
I am running python 3.7.4 on windows 10 with celery 4.4.7, and I am using rabbitmq 3.8.5 for broker and result backend.
I deploy example project by cookiecutter and install all requirements and cli, but when I tried to use tox to do unittest, all tests except celery's one passed. So am I doing wrong here? any help will be appreciated.
E:\Project\testrestful\restful_api>tox
GLOB sdist-make: E:\Project\testrestful\restful_api\setup.py
py38 create: E:\Project\testrestful\restful_api\.tox\py38
ERROR: InterpreterNotFound: python3.8
py37 inst-nodeps: E:\Project\testrestful\restful_api\.tox\.tmp\package\3\myapi-0.1.zip
py37 installed: alembic==1.4.2,amqp==2.6.1,aniso8601==8.0.0,apispec==3.3.1,apispec-webframeworks==0.5.2,appdirs==1.4.4,atomicwrites==1.4.0,attrs==19.3.0,billiard==3.6.3.0,black==19.10b0,celery==4.4.7,click==7.1.2,colorama==0.4.3,distlib==0.3.1,factory-boy==2.12.0,Faker==4.1.1,filelock==3.0.12,flake8==3.8.3,Flask==1.1.2,Flask-JWT-Extended==3.24.1,flask-marshmallow==0.13.0,Flask-Migrate==2.5.3,Flask-RESTful==0.3.8,Flask-SQLAlchemy==2.4.4,gunicorn==20.0.4,importlib-metadata==1.7.0,inflection==0.5.0,iniconfig==1.0.1,itsdangerous==1.1.0,Jinja2==2.11.2,kombu==4.6.11,Mako==1.1.3,MarkupSafe==1.1.1,marshmallow==3.7.1,marshmallow-sqlalchemy==0.23.1,mccabe==0.6.1,more-itertools==8.4.0,myapi @ file:///E:/Project/testrestful/restful_api/.tox/.tmp/package/3/myapi-0.1.zip,packaging==20.4,passlib==1.7.2,pathspec==0.8.0,pluggy==0.13.1,py==1.9.0,pycodestyle==2.6.0,pyflakes==2.2.0,PyJWT==1.7.1,pyparsing==2.4.7,pytest==6.0.1,pytest-factoryboy==2.0.3,pytest-flask==1.0.0,pytest-runner==5.2,python-dateutil==2.8.1,python-dotenv==0.14.0,python-editor==1.0.4,pytz==2020.1,PyYAML==5.3.1,redis==3.5.3,regex==2020.7.14,six==1.15.0,SQLAlchemy==1.3.18,text-unidecode==1.3,toml==0.10.1,tox==3.18.1,typed-ast==1.4.1,vine==1.3.0,virtualenv==20.0.30,Werkzeug==1.0.1,zipp==3.1.0
py37 run-test-pre: PYTHONHASHSEED='862'
py37 run-test: commands[0] | flake8 myapi
py37 run-test: commands[1] | black myapi --check
All done! β¨ π° β¨
24 files would be left unchanged.
py37 run-test: commands[2] | pytest tests
================================================= test session starts =================================================
platform win32 -- Python 3.7.4, pytest-6.0.1, py-1.9.0, pluggy-0.13.1
cachedir: .tox\py37\.pytest_cache
rootdir: E:\Project\testrestful\restful_api
plugins: celery-4.4.7, Faker-4.1.1, factoryboy-2.0.3, flask-1.0.0
collected 8 items
tests\test_auth.py .. [ 25%]
tests\test_celery.py Message: 'Task handler raised error: %r'
Arguments: (Task of kind 'celery.ping' never registered, please make sure it's imported.,)
E [ 37%]
tests\test_user.py ..... [100%]
======================================================= ERRORS ========================================================
___________________________________________ ERROR at setup of test_example ____________________________________________
request = <SubRequest 'celery_worker' for <Function test_example>>, celery_app = <Celery celery.tests at 0x1e4291ade08>
celery_includes = (), celery_worker_pool = 'prefork', celery_worker_parameters = {}
@pytest.fixture()
def celery_worker(request,
celery_app,
celery_includes,
celery_worker_pool,
celery_worker_parameters):
# type: (Any, Celery, Sequence[str], str, Any) -> WorkController
"""Fixture: Start worker in a thread, stop it when the test returns."""
if not NO_WORKER:
for module in celery_includes:
celery_app.loader.import_task_module(module)
with worker.start_worker(celery_app,
pool=celery_worker_pool,
> **celery_worker_parameters) as w:
.tox\py37\lib\site-packages\celery\contrib\pytest.py:198:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
f:\anaconda\lib\contextlib.py:112: in __enter__
return next(self.gen)
.tox\py37\lib\site-packages\celery\contrib\testing\worker.py:84: in start_worker
assert ping.delay().get(timeout=ping_task_timeout) == 'pong'
.tox\py37\lib\site-packages\celery\result.py:237: in get
on_message=on_message,
.tox\py37\lib\site-packages\celery\backends\base.py:668: in wait_for_pending
return result.maybe_throw(propagate=propagate, callback=callback)
.tox\py37\lib\site-packages\celery\result.py:342: in maybe_throw
self.throw(value, self._to_remote_traceback(tb))
.tox\py37\lib\site-packages\celery\result.py:335: in throw
self.on_ready.throw(*args, **kwargs)
.tox\py37\lib\site-packages\vine\promises.py:244: in throw
reraise(type(exc), exc, tb)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
tp = <class 'celery.exceptions.NotRegistered'>
value = Task of kind 'celery.ping' never registered, please make sure it's imported., tb = None
def reraise(tp, value, tb=None):
"""Reraise exception."""
if value.__traceback__ is not tb:
raise value.with_traceback(tb)
> raise value
E celery.exceptions.NotRegistered: 'celery.ping'
.tox\py37\lib\site-packages\vine\five.py:195: NotRegistered
------------------------------------------------ Captured stderr setup ------------------------------------------------
--- Logging error ---
Traceback (most recent call last):
File "f:\anaconda\lib\logging\__init__.py", line 1028, in emit
stream.write(msg + self.terminator)
OSError: [WinError 6] ε₯ζζ ζγ
Call stack:
================================================== warnings summary ===================================================
tests/test_celery.py::test_example
e:\project\testrestful\restful_api\.tox\py37\lib\site-packages\celery\backends\amqp.py:67: CPendingDeprecationWarning:
The AMQP result backend is scheduled for deprecation in version 4.0 and removal in version v5.0. Please use RPC backend or a persistent backend.
alternative='Please use RPC backend or a persistent backend.')
-- Docs: https://docs.pytest.org/en/stable/warnings.html
=============================================== short test summary info ===============================================
ERROR tests/test_celery.py::test_example - celery.exceptions.NotRegistered: 'celery.ping'
======================================== 7 passed, 1 warning, 1 error in 1.98s ========================================
Installs latest Celery and then...
celery_1 | You are using -A
as an option of the worker sub-command:
celery_1 | celery worker -A celeryapp <...>
celery_1 |
celery_1 | The support for this usage was removed in Celery 5.0. Instead you should use -A
as a global option:
celery_1 | celery -A celeryapp worker <...>
celery_1 | Usage: celery worker [OPTIONS]
celery_1 | Try 'celery worker --help' for help.
celery_1 |
Hi @karec !
It seems that the latest changes (regarding cli from flask) gives an error after the pip install -e .
, I just run flask --help
to check and I get this (I tried with python 3.8 and 3.9, same issue):
Traceback (most recent call last):
File "/Users/johndoe/Software/python-virtualenvs/TestRestful/lib/python3.9/site-packages/pkg_resources/__init__.py", line 2455, in resolve
return functools.reduce(getattr, self.attrs, module)
AttributeError: module 'myapi.manage' has no attribute 'cli'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/Users/johndoe/Software/python-virtualenvs/TestRestful/bin/flask", line 8, in <module>
sys.exit(main())
File "/Users/johndoe/Software/python-virtualenvs/TestRestful/lib/python3.9/site-packages/flask/cli.py", line 994, in main
cli.main(args=sys.argv[1:])
File "/Users/johndoe/Software/python-virtualenvs/TestRestful/lib/python3.9/site-packages/flask/cli.py", line 600, in main
return super().main(*args, **kwargs)
File "/Users/johndoe/Software/python-virtualenvs/TestRestful/lib/python3.9/site-packages/click/core.py", line 1052, in main
with self.make_context(prog_name, args, **extra) as ctx:
File "/Users/johndoe/Software/python-virtualenvs/TestRestful/lib/python3.9/site-packages/click/core.py", line 914, in make_context
self.parse_args(ctx, args)
File "/Users/johndoe/Software/python-virtualenvs/TestRestful/lib/python3.9/site-packages/click/core.py", line 1615, in parse_args
rest = super().parse_args(ctx, args)
File "/Users/johndoe/Software/python-virtualenvs/TestRestful/lib/python3.9/site-packages/click/core.py", line 1370, in parse_args
value, args = param.handle_parse_result(ctx, opts, args)
File "/Users/johndoe/Software/python-virtualenvs/TestRestful/lib/python3.9/site-packages/click/core.py", line 2347, in handle_parse_result
value = self.process_value(ctx, value)
File "/Users/johndoe/Software/python-virtualenvs/TestRestful/lib/python3.9/site-packages/click/core.py", line 2309, in process_value
value = self.callback(ctx, self, value)
File "/Users/johndoe/Software/python-virtualenvs/TestRestful/lib/python3.9/site-packages/click/core.py", line 1270, in show_help
echo(ctx.get_help(), color=ctx.color)
File "/Users/johndoe/Software/python-virtualenvs/TestRestful/lib/python3.9/site-packages/click/core.py", line 693, in get_help
return self.command.get_help(self)
File "/Users/johndoe/Software/python-virtualenvs/TestRestful/lib/python3.9/site-packages/click/core.py", line 1295, in get_help
self.format_help(ctx, formatter)
File "/Users/johndoe/Software/python-virtualenvs/TestRestful/lib/python3.9/site-packages/click/core.py", line 1326, in format_help
self.format_options(ctx, formatter)
File "/Users/johndoe/Software/python-virtualenvs/TestRestful/lib/python3.9/site-packages/click/core.py", line 1524, in format_options
self.format_commands(ctx, formatter)
File "/Users/johndoe/Software/python-virtualenvs/TestRestful/lib/python3.9/site-packages/click/core.py", line 1587, in format_commands
for subcommand in self.list_commands(ctx):
File "/Users/johndoe/Software/python-virtualenvs/TestRestful/lib/python3.9/site-packages/flask/cli.py", line 561, in list_commands
self._load_plugin_commands()
File "/Users/johndoe/Software/python-virtualenvs/TestRestful/lib/python3.9/site-packages/flask/cli.py", line 539, in _load_plugin_commands
self.add_command(ep.load(), ep.name)
File "/Users/johndoe/Software/python-virtualenvs/TestRestful/lib/python3.9/site-packages/pkg_resources/__init__.py", line 2447, in load
return self.resolve()
File "/Users/johndoe/Software/python-virtualenvs/TestRestful/lib/python3.9/site-packages/pkg_resources/__init__.py", line 2457, in resolve
raise ImportError(str(exc)) from exc
ImportError: module 'myapi.manage' has no attribute 'cli'
Any idea?
Thanks a lot!
Best regards,
Sylvain
Hi Karec,
I'm currently trying to adapt your template for my uses, but I encounter an error when I want to run test.
Error on test_revoke_access_token(client, admin_headers)
This is using fixture admin_headers, and admin_headers is also using fixtures admin_user(...) (ok) and client(...) (ko)
where does client come from ? it seems it's not initialized yet when running test, and I cannot find occurence to it.
ty
first, just wanna say thank you for making this project.
i noticed that method_decorator
is assigned [jwt_required]
but it isn't used? not sure if i'm reading it correctly, but maybe it belongs above the put
and delete
requests as @method_decorator
by default? or is it up to the user to decide...
Hi - wondered if you thought it would be useful to include socket endpoints?
Interesting project, I think it would be nice when also implement the asgi & async.
For example when user select asgi & async, then the project will be use its.
I ran into this problem when I created a demo for testing using this project.Maybe it's a bug, so submit this issues.Thanks for checking out.
The password inserted into the database when adding a user is a hash value, but it is plaintext when updating a user.
post -> /api/v1/users Add new user.The password inserted into the database when adding a user is a hash value.
PUT -> /api/v1/users/2 Update user info.The password for inserting the database is in plaintext
I analyzed it for perhaps the following reasons.
The encryption process is done here, and the __init__
method is executed when adding a user, but not called when updating. Maybe that's the reason.
Related CodesοΌ
Using 'next' URL on our tests we are getting the following error:
self = <flask_sqlalchemy.BaseQuery object at 0x7f192cf46d00>, page = '1', per_page = 50, error_out = True, max_per_page = None
def paginate(self, page=None, per_page=None, error_out=True, max_per_page=None):
# ... about 40 lines ....
> if page < 1:
E TypeError: '<' not supported between instances of 'str' and 'int'
venv/lib/python3.8/site-packages/flask_sqlalchemy/__init__.py:484: TypeError
SQLAlchemy related libraries installed are these:
Flask-SQLAlchemy==2.4.4
PyMySQL==0.9.3
SQLAlchemy==1.3.23
SQLAlchemy-Utils==0.36.8
I humble propose PR #49 as solution
Can we get a Dockerfile and possibly a docker compose file as well as part of this template?
It would be useful to add the cli commands (manage.cli) to the flask terminal command. This is a change of just a few lines, and would provide easy access to cli actions. e.g.
flask app init
where app is declared as the top level group for commands related to the.... app.
Doing it this way also makes it easy to access current_app inside commands.
I imagine a blueprint that contains the app click.group which can be imported to all other modules with cli commands and used as the top level namespace for commands specific to the app.
I have a working general example at https://github.com/DonalChilde/flask_cli -> manual_cli branch
I would be happy to try to submit a pull request if you are interested in the idea, but I've never done that before so it would take some time to figure it out.
I just want to put this here!
I don't know if I will have time to do it but let me just put it here,
Hi, I've been using your great template (slightly tweaked to meet my needs) in one of my flask apps and noticed odd problem.
After changing SQLALCHEMY_DATABASE_URI to sqlite:///myapi.db
and initializing sqlite database using flask
cli commands: init
-> migrate
-> upgrade
. I get an error when querying User
table in python shell:
$ flask shell
>>> from myapi.models.user import User
>>> User.query.all()
Traceback (most recent call last):
File "/home/linux-hp/git-clones/restful_api/.venv/lib/python3.5/site-packages/sqlalchemy/engine/base.py", line 1193, in _execute_context
context)
File "/home/linux-hp/git-clones/restful_api/.venv/lib/python3.5/site-packages/sqlalchemy/engine/default.py", line 509, in do_execute
cursor.execute(statement, parameters)
sqlite3.OperationalError: no such table: user
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/home/linux-hp/git-clones/restful_api/.venv/lib/python3.5/site-packages/sqlalchemy/orm/query.py", line 2843, in all
return list(self)
File "/home/linux-hp/git-clones/restful_api/.venv/lib/python3.5/site-packages/sqlalchemy/orm/query.py", line 2995, in __iter__
return self._execute_and_instances(context)
File "/home/linux-hp/git-clones/restful_api/.venv/lib/python3.5/site-packages/sqlalchemy/orm/query.py", line 3018, in _execute_and_instances
result = conn.execute(querycontext.statement, self._params)
File "/home/linux-hp/git-clones/restful_api/.venv/lib/python3.5/site-packages/sqlalchemy/engine/base.py", line 948, in execute
return meth(self, multiparams, params)
File "/home/linux-hp/git-clones/restful_api/.venv/lib/python3.5/site-packages/sqlalchemy/sql/elements.py", line 269, in _execute_on_connection
return connection._execute_clauseelement(self, multiparams, params)
File "/home/linux-hp/git-clones/restful_api/.venv/lib/python3.5/site-packages/sqlalchemy/engine/base.py", line 1060, in _execute_clauseelement
compiled_sql, distilled_params
File "/home/linux-hp/git-clones/restful_api/.venv/lib/python3.5/site-packages/sqlalchemy/engine/base.py", line 1200, in _execute_context
context)
File "/home/linux-hp/git-clones/restful_api/.venv/lib/python3.5/site-packages/sqlalchemy/engine/base.py", line 1413, in _handle_dbapi_exception
exc_info
File "/home/linux-hp/git-clones/restful_api/.venv/lib/python3.5/site-packages/sqlalchemy/util/compat.py", line 265, in raise_from_cause
reraise(type(exception), exception, tb=exc_tb, cause=cause)
File "/home/linux-hp/git-clones/restful_api/.venv/lib/python3.5/site-packages/sqlalchemy/util/compat.py", line 248, in reraise
raise value.with_traceback(tb)
File "/home/linux-hp/git-clones/restful_api/.venv/lib/python3.5/site-packages/sqlalchemy/engine/base.py", line 1193, in _execute_context
context)
File "/home/linux-hp/git-clones/restful_api/.venv/lib/python3.5/site-packages/sqlalchemy/engine/default.py", line 509, in do_execute
cursor.execute(statement, parameters)
sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such table: user [SQL: 'SELECT user.id AS user_id, user.username AS user_username, user.email AS user_email, user.password AS user_password, user.active AS user_active \nFROM user'] (Background on this error at: http://sqlalche.me/e/e3q8)
As far as I understood from googling that this somewhat related to Python import system, but I can't currently come up with any solution except of workaround with storing sqlite database in /tmp/
directory. How this problem can be solved?
TODOS: to be updated
Ubuntu 20.04
Python 3.8
Running pytest after creating project gives:
____________________________________________________________________________ ERROR at setup of test_revoke_access_token _____________________________________________________________________________
app = <Flask 'flaskapi'>
@pytest.fixture
def db(app):
_db.app = app
with app.app_context():
> _db.create_all()
tests/conftest.py:24:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
venv/lib/python3.8/site-packages/flask_sqlalchemy/__init__.py:1039: in create_all
self._execute_for_all_tables(app, bind, 'create_all')
venv/lib/python3.8/site-packages/flask_sqlalchemy/__init__.py:1031: in _execute_for_all_tables
op(bind=self.get_engine(app, bind), **extra)
venv/lib/python3.8/site-packages/flask_sqlalchemy/__init__.py:962: in get_engine
return connector.get_engine()
venv/lib/python3.8/site-packages/flask_sqlalchemy/__init__.py:555: in get_engine
options = self.get_options(sa_url, echo)
venv/lib/python3.8/site-packages/flask_sqlalchemy/__init__.py:570: in get_options
self._sa.apply_driver_hacks(self._app, sa_url, options)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <[AttributeError("'NoneType' object has no attribute 'drivername'") raised in repr()] SQLAlchemy object at 0x7facf606deb0>, app = <Flask 'flaskapi'>, sa_url = None, options = {}
def apply_driver_hacks(self, app, sa_url, options):
"""This method is called before engine creation and used to inject
driver specific hacks into the options. The `options` parameter is
a dictionary of keyword arguments that will then be used to call
the :func:`sqlalchemy.create_engine` function.
The default implementation provides some saner defaults for things
like pool sizes for MySQL and sqlite. Also it injects the setting of
`SQLALCHEMY_NATIVE_UNICODE`.
"""
> if sa_url.drivername.startswith('mysql'):
E AttributeError: 'NoneType' object has no attribute 'drivername'
venv/lib/python3.8/site-packages/flask_sqlalchemy/__init__.py:883: AttributeError
____________________________________________________________________________ ERROR at setup of test_revoke_refresh_token ____________________________________________________________________________
app = <Flask 'flaskapi'>
@pytest.fixture
def db(app):
_db.app = app
with app.app_context():
> _db.create_all()
tests/conftest.py:24:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
venv/lib/python3.8/site-packages/flask_sqlalchemy/__init__.py:1039: in create_all
self._execute_for_all_tables(app, bind, 'create_all')
venv/lib/python3.8/site-packages/flask_sqlalchemy/__init__.py:1031: in _execute_for_all_tables
op(bind=self.get_engine(app, bind), **extra)
venv/lib/python3.8/site-packages/flask_sqlalchemy/__init__.py:962: in get_engine
return connector.get_engine()
venv/lib/python3.8/site-packages/flask_sqlalchemy/__init__.py:555: in get_engine
options = self.get_options(sa_url, echo)
venv/lib/python3.8/site-packages/flask_sqlalchemy/__init__.py:570: in get_options
self._sa.apply_driver_hacks(self._app, sa_url, options)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <[AttributeError("'NoneType' object has no attribute 'drivername'") raised in repr()] SQLAlchemy object at 0x7facf606deb0>, app = <Flask 'flaskapi'>, sa_url = None, options = {}
def apply_driver_hacks(self, app, sa_url, options):
"""This method is called before engine creation and used to inject
driver specific hacks into the options. The `options` parameter is
a dictionary of keyword arguments that will then be used to call
the :func:`sqlalchemy.create_engine` function.
The default implementation provides some saner defaults for things
like pool sizes for MySQL and sqlite. Also it injects the setting of
`SQLALCHEMY_NATIVE_UNICODE`.
"""
> if sa_url.drivername.startswith('mysql'):
E AttributeError: 'NoneType' object has no attribute 'drivername'
venv/lib/python3.8/site-packages/flask_sqlalchemy/__init__.py:883: AttributeError
Having this error as soon as I cloned the project and tried installation steps, can someone help me set this up?
here's my pip freeze :
alembic==1.5.4 aniso8601==8.1.1 apispec==4.3.0 apispec-webframeworks==0.5.2 appdirs==1.4.4 arrow==0.17.0 binaryornot==0.4.4 certifi==2020.12.5 chardet==4.0.0 click==7.1.2 cookiecutter==1.7.2 distlib==0.3.1 filelock==3.0.12 Flask==1.1.2 Flask-JWT-Extended==4.0.2 flask-marshmallow==0.14.0 Flask-Migrate==2.6.0 Flask-RESTful==0.3.8 Flask-SQLAlchemy==2.4.4 gunicorn==20.0.4 idna==2.10 itsdangerous==1.1.0 Jinja2==2.11.3 jinja2-time==0.2.0 Mako==1.1.4 MarkupSafe==1.1.1 marshmallow==3.10.0 marshmallow-sqlalchemy==0.24.2 packaging==20.9 passlib==1.7.4 pluggy==0.13.1 poyo==0.5.0 py==1.10.0 PyJWT==2.0.1 pyparsing==2.4.7 python-dateutil==2.8.1 python-dotenv==0.15.0 python-editor==1.0.4 python-slugify==4.0.1 pytz==2021.1 PyYAML==5.4.1 requests==2.25.1 six==1.15.0 SQLAlchemy==1.3.23 text-unidecode==1.3 toml==0.10.2 tox==3.22.0 urllib3==1.26.3 virtualenv==20.4.2 Werkzeug==1.0.1
I tried to download the code but there seems to be no script to run the bootstrap. Do i need to get from https://github.com/sloria/cookiecutter-flask tasks.py
?
I have been working with this for a long time I think it should be okay to have the config as a different class one for development, another for production, and another one for testing...!
For more info check here
I had to downgrade to Flask 1.1.2 and all seems good with the world again. Perhaps a change to the requirements.txt until a fix can be made?
Celery tests not passing with tox or pytest. Probably because no broker/result backend running.
Needs a) update in readme and b) some sort of w/a. Either run tests eager, or spin up an instance to test end to end.
Seems to be failing when installing and using all the defaults and then using the make init
command
Error
Recreating restful_api_web_1 ... error
ERROR: for restful_api_web_1 Cannot start service web: OCI runtime create failed: container_linux.go:370: starting container process caused: exec: "myapi": executable file not found in $PATH: unknown
ERROR: for web Cannot start service web: OCI runtime create failed: container_linux.go:370: starting container process caused: exec: "myapi": executable file not found in $PATH: unknown
Full setup and init output below:
Setup
bbolt@bbolt playground % cookiecutter https://github.com/karec/cookiecutter-flask-restful
project_name [restful_api]:
app_name [myapi]:
Select python_version:
1 - 3.8
2 - 3.7
3 - 3.6
Choose from 1, 2, 3 [1]:
tox_python_env [py38]:
Select use_celery:
1 - no
2 - yes
Choose from 1, 2 [1]:
admin_user_username [admin]:
admin_user_email [[email protected]]:
admin_user_password [admin]:
Select wsgi_server:
1 - none
2 - uwsgi
3 - gunicorn
Choose from 1, 2, 3 [1]:
Init
bbolt@bbolt playground % cd restful_api
bbolt@bbolt restful_api % make init
docker-compose build
Building web
Step 1/10 : FROM python:3.8
---> b0358f6298cd
Step 2/10 : RUN mkdir /code
---> Using cache
---> 87c9c870b25e
Step 3/10 : WORKDIR /code
---> Using cache
---> f21a622260a4
Step 4/10 : COPY requirements.txt setup.py tox.ini ./
---> 1706cabbf3ef
Step 5/10 : RUN pip install -U pip
---> Running in abc8ae00d385
Requirement already satisfied: pip in /usr/local/lib/python3.8/site-packages (20.3.3)
Removing intermediate container abc8ae00d385
---> 6d7debcf7641
Step 6/10 : RUN pip install -r requirements.txt
---> Running in 45e00103d363
Collecting marshmallow>=3
Downloading marshmallow-3.10.0-py2.py3-none-any.whl (46 kB)
Collecting apispec-webframeworks
Downloading apispec_webframeworks-0.5.2-py2.py3-none-any.whl (12 kB)
Collecting apispec[yaml]
Downloading apispec-4.0.0-py2.py3-none-any.whl (26 kB)
Collecting PyYAML>=3.10
Downloading PyYAML-5.3.1.tar.gz (269 kB)
Collecting flask
Downloading Flask-1.1.2-py2.py3-none-any.whl (94 kB)
Collecting click>=5.1
Downloading click-7.1.2-py2.py3-none-any.whl (82 kB)
Collecting itsdangerous>=0.24
Downloading itsdangerous-1.1.0-py2.py3-none-any.whl (16 kB)
Collecting Jinja2>=2.10.1
Downloading Jinja2-2.11.2-py2.py3-none-any.whl (125 kB)
Collecting MarkupSafe>=0.23
Downloading MarkupSafe-1.1.1-cp38-cp38-manylinux1_x86_64.whl (32 kB)
Collecting Werkzeug>=0.15
Downloading Werkzeug-1.0.1-py2.py3-none-any.whl (298 kB)
Collecting flask-jwt-extended
Downloading Flask-JWT-Extended-3.25.0.tar.gz (31 kB)
Collecting PyJWT<2.0,>=1.6.4
Downloading PyJWT-1.7.1-py2.py3-none-any.whl (18 kB)
Collecting flask-marshmallow
Downloading flask_marshmallow-0.14.0-py2.py3-none-any.whl (10 kB)
Collecting six
Downloading six-1.15.0-py2.py3-none-any.whl (10 kB)
Collecting flask-migrate
Downloading Flask_Migrate-2.5.3-py2.py3-none-any.whl (13 kB)
Collecting flask-sqlalchemy
Downloading Flask_SQLAlchemy-2.4.4-py2.py3-none-any.whl (17 kB)
Collecting alembic>=0.7
Downloading alembic-1.4.3-py2.py3-none-any.whl (159 kB)
Collecting python-editor>=0.3
Downloading python_editor-1.0.4-py3-none-any.whl (4.9 kB)
Collecting SQLAlchemy>=0.8.0
Downloading SQLAlchemy-1.3.22-cp38-cp38-manylinux2010_x86_64.whl (1.3 MB)
Collecting flask-restful
Downloading Flask_RESTful-0.3.8-py2.py3-none-any.whl (25 kB)
Collecting aniso8601>=0.82
Downloading aniso8601-8.1.0-py2.py3-none-any.whl (44 kB)
Collecting marshmallow-sqlalchemy
Downloading marshmallow_sqlalchemy-0.24.1-py2.py3-none-any.whl (18 kB)
Collecting passlib
Downloading passlib-1.7.4-py2.py3-none-any.whl (525 kB)
Collecting python-dotenv
Downloading python_dotenv-0.15.0-py2.py3-none-any.whl (18 kB)
Collecting tox
Downloading tox-3.21.0-py2.py3-none-any.whl (84 kB)
Collecting filelock>=3.0.0
Downloading filelock-3.0.12-py3-none-any.whl (7.6 kB)
Collecting packaging>=14
Downloading packaging-20.8-py2.py3-none-any.whl (39 kB)
Collecting pluggy>=0.12.0
Downloading pluggy-0.13.1-py2.py3-none-any.whl (18 kB)
Collecting py>=1.4.17
Downloading py-1.10.0-py2.py3-none-any.whl (97 kB)
Collecting pyparsing>=2.0.2
Downloading pyparsing-2.4.7-py2.py3-none-any.whl (67 kB)
Collecting toml>=0.9.4
Downloading toml-0.10.2-py2.py3-none-any.whl (16 kB)
Collecting virtualenv!=20.0.0,!=20.0.1,!=20.0.2,!=20.0.3,!=20.0.4,!=20.0.5,!=20.0.6,!=20.0.7,>=16.0.0
Downloading virtualenv-20.3.0-py2.py3-none-any.whl (5.7 MB)
Collecting appdirs<2,>=1.4.3
Downloading appdirs-1.4.4-py2.py3-none-any.whl (9.6 kB)
Collecting distlib<1,>=0.3.1
Downloading distlib-0.3.1-py2.py3-none-any.whl (335 kB)
Collecting Mako
Downloading Mako-1.1.3-py2.py3-none-any.whl (75 kB)
Collecting python-dateutil
Downloading python_dateutil-2.8.1-py2.py3-none-any.whl (227 kB)
Collecting pytz
Downloading pytz-2020.5-py2.py3-none-any.whl (510 kB)
Building wheels for collected packages: PyYAML, flask-jwt-extended
Building wheel for PyYAML (setup.py): started
Building wheel for PyYAML (setup.py): finished with status 'done'
Created wheel for PyYAML: filename=PyYAML-5.3.1-cp38-cp38-linux_x86_64.whl size=572488 sha256=5757dd393e674951a1bc399b335ae17843b17d8745797072a231b2452a416863
Stored in directory: /root/.cache/pip/wheels/13/90/db/290ab3a34f2ef0b5a0f89235dc2d40fea83e77de84ed2dc05c
Building wheel for flask-jwt-extended (setup.py): started
Building wheel for flask-jwt-extended (setup.py): finished with status 'done'
Created wheel for flask-jwt-extended: filename=Flask_JWT_Extended-3.25.0-py2.py3-none-any.whl size=21569 sha256=27dd3a35f6c4e6767fa4a06541c8499490d1a8489c77746d85ab54bf2a2cc89e
Stored in directory: /root/.cache/pip/wheels/f0/53/54/ec3db050e12900460634d2f7badb842fa29af7508a5b84557d
Successfully built PyYAML flask-jwt-extended
Installing collected packages: MarkupSafe, Werkzeug, six, Jinja2, itsdangerous, click, SQLAlchemy, PyYAML, python-editor, python-dateutil, pyparsing, Mako, flask, filelock, distlib, appdirs, apispec, virtualenv, toml, pytz, PyJWT, py, pluggy, packaging, marshmallow, flask-sqlalchemy, aniso8601, alembic, tox, python-dotenv, passlib, marshmallow-sqlalchemy, flask-restful, flask-migrate, flask-marshmallow, flask-jwt-extended, apispec-webframeworks
Successfully installed Jinja2-2.11.2 Mako-1.1.3 MarkupSafe-1.1.1 PyJWT-1.7.1 PyYAML-5.3.1 SQLAlchemy-1.3.22 Werkzeug-1.0.1 alembic-1.4.3 aniso8601-8.1.0 apispec-4.0.0 apispec-webframeworks-0.5.2 appdirs-1.4.4 click-7.1.2 distlib-0.3.1 filelock-3.0.12 flask-1.1.2 flask-jwt-extended-3.25.0 flask-marshmallow-0.14.0 flask-migrate-2.5.3 flask-restful-0.3.8 flask-sqlalchemy-2.4.4 itsdangerous-1.1.0 marshmallow-3.10.0 marshmallow-sqlalchemy-0.24.1 packaging-20.8 passlib-1.7.4 pluggy-0.13.1 py-1.10.0 pyparsing-2.4.7 python-dateutil-2.8.1 python-dotenv-0.15.0 python-editor-1.0.4 pytz-2020.5 six-1.15.0 toml-0.10.2 tox-3.21.0 virtualenv-20.3.0
Removing intermediate container 45e00103d363
---> 30025f46750e
Step 7/10 : RUN pip install -e .
---> Running in f0ab77a80cb4
Obtaining file:///code
Requirement already satisfied: flask in /usr/local/lib/python3.8/site-packages (from myapi==0.1) (1.1.2)
Requirement already satisfied: flask-sqlalchemy in /usr/local/lib/python3.8/site-packages (from myapi==0.1) (2.4.4)
Requirement already satisfied: flask-restful in /usr/local/lib/python3.8/site-packages (from myapi==0.1) (0.3.8)
Requirement already satisfied: flask-migrate in /usr/local/lib/python3.8/site-packages (from myapi==0.1) (2.5.3)
Requirement already satisfied: flask-jwt-extended in /usr/local/lib/python3.8/site-packages (from myapi==0.1) (3.25.0)
Requirement already satisfied: flask-marshmallow in /usr/local/lib/python3.8/site-packages (from myapi==0.1) (0.14.0)
Requirement already satisfied: marshmallow-sqlalchemy in /usr/local/lib/python3.8/site-packages (from myapi==0.1) (0.24.1)
Requirement already satisfied: python-dotenv in /usr/local/lib/python3.8/site-packages (from myapi==0.1) (0.15.0)
Requirement already satisfied: passlib in /usr/local/lib/python3.8/site-packages (from myapi==0.1) (1.7.4)
Requirement already satisfied: apispec[yaml] in /usr/local/lib/python3.8/site-packages (from myapi==0.1) (4.0.0)
Requirement already satisfied: apispec-webframeworks in /usr/local/lib/python3.8/site-packages (from myapi==0.1) (0.5.2)
Requirement already satisfied: PyYAML>=3.10 in /usr/local/lib/python3.8/site-packages (from apispec[yaml]->myapi==0.1) (5.3.1)
Requirement already satisfied: click>=5.1 in /usr/local/lib/python3.8/site-packages (from flask->myapi==0.1) (7.1.2)
Requirement already satisfied: itsdangerous>=0.24 in /usr/local/lib/python3.8/site-packages (from flask->myapi==0.1) (1.1.0)
Requirement already satisfied: Jinja2>=2.10.1 in /usr/local/lib/python3.8/site-packages (from flask->myapi==0.1) (2.11.2)
Requirement already satisfied: Werkzeug>=0.15 in /usr/local/lib/python3.8/site-packages (from flask->myapi==0.1) (1.0.1)
Requirement already satisfied: MarkupSafe>=0.23 in /usr/local/lib/python3.8/site-packages (from Jinja2>=2.10.1->flask->myapi==0.1) (1.1.1)
Requirement already satisfied: PyJWT<2.0,>=1.6.4 in /usr/local/lib/python3.8/site-packages (from flask-jwt-extended->myapi==0.1) (1.7.1)
Requirement already satisfied: six in /usr/local/lib/python3.8/site-packages (from flask-jwt-extended->myapi==0.1) (1.15.0)
Requirement already satisfied: marshmallow>=2.0.0 in /usr/local/lib/python3.8/site-packages (from flask-marshmallow->myapi==0.1) (3.10.0)
Requirement already satisfied: alembic>=0.7 in /usr/local/lib/python3.8/site-packages (from flask-migrate->myapi==0.1) (1.4.3)
Requirement already satisfied: python-dateutil in /usr/local/lib/python3.8/site-packages (from alembic>=0.7->flask-migrate->myapi==0.1) (2.8.1)
Requirement already satisfied: SQLAlchemy>=1.1.0 in /usr/local/lib/python3.8/site-packages (from alembic>=0.7->flask-migrate->myapi==0.1) (1.3.22)
Requirement already satisfied: python-editor>=0.3 in /usr/local/lib/python3.8/site-packages (from alembic>=0.7->flask-migrate->myapi==0.1) (1.0.4)
Requirement already satisfied: Mako in /usr/local/lib/python3.8/site-packages (from alembic>=0.7->flask-migrate->myapi==0.1) (1.1.3)
Requirement already satisfied: aniso8601>=0.82 in /usr/local/lib/python3.8/site-packages (from flask-restful->myapi==0.1) (8.1.0)
Requirement already satisfied: pytz in /usr/local/lib/python3.8/site-packages (from flask-restful->myapi==0.1) (2020.5)
Installing collected packages: myapi
Running setup.py develop for myapi
Successfully installed myapi
Removing intermediate container f0ab77a80cb4
---> 7e90d7594f1f
Step 8/10 : COPY myapi myapi/
---> 60bef73528f1
Step 9/10 : COPY migrations migrations/
---> 2e2dbb23e90d
Step 10/10 : EXPOSE 5000
---> Running in e557f96dd4e0
Removing intermediate container e557f96dd4e0
---> 2fbe405e8216
Successfully built 2fbe405e8216
Successfully tagged myapi:latest
docker-compose up -d
Recreating restful_api_web_1 ... error
ERROR: for restful_api_web_1 Cannot start service web: OCI runtime create failed: container_linux.go:370: starting container process caused: exec: "myapi": executable file not found in $PATH: unknown
ERROR: for web Cannot start service web: OCI runtime create failed: container_linux.go:370: starting container process caused: exec: "myapi": executable file not found in $PATH: unknown
ERROR: Encountered errors while bringing up the project.
make: *** [run] Error 1
helloοΌI'm a new python coderγ
The methods I found through search are to click the debug button directly when there is an app.run() call. But the project generated by your command is run through the flask run command. Presumably, the flask command called the create_app method to obtain the instance and run it. What should we do now?
Bonjour @karec !
What do you think about separating resources and schemas and have them in 2 different packages?
Why I have an impression that having this in one module violates the Single responsibility principle or separation of concern? But I am not sure, maybe you can give some light on this.
Plus it may increase readability for the cookiecutter.
What are your thoughts?
I can work on this if you agree.
cd myproject
virtualenv --no-site-packages --pyhton=python3.6 venv
source venv/bin/activate
pip install -r requirements.txt
pip install -e .
myapi init
tox
tox
GLOB sdist-make: /mnt/f/workspace/git/FlaskProjectTemplate/ig-restful-api/setup.py
python create: /mnt/f/workspace/git/FlaskProjectTemplate/ig-restful-api/.tox/python
python installdeps: flake8, pytest, pytest-flask, pytest-runner, pytest-factoryboy, factory_boy, -rrequirements.txt
python inst: /mnt/f/workspace/git/FlaskProjectTemplate/ig-restful-api/.tox/.tmp/package/1/igapi-0.1.zip
python installed: alembic==1.0.11,aniso8601==7.0.0,atomicwrites==1.3.0,attrs==19.1.0,Click==7.0,entrypoints==0.3,factory-boy==2.12.0,Faker==2.0.0,filelock==3.0.12,flake8==3.7.8,Flask==1.1.1,Flask-JWT-Extended==3.21.0,flask-marshmallow==0.10.1,Flask-Migrate==2.5.2,Flask-RESTful==0.3.7,Flask-SQLAlchemy==2.4.0,igapi==0.1,importlib-metadata==0.19,inflection==0.3.1,itsdangerous==1.1.0,Jinja2==2.10.1,Mako==1.1.0,MarkupSafe==1.1.1,marshmallow==3.0.0,marshmallow-sqlalchemy==0.17.0,mccabe==0.6.1,more-itertools==7.2.0,packaging==19.1,passlib==1.7.1,pathlib2==2.3.4,pluggy==0.12.0,py==1.8.0,pycodestyle==2.5.0,pyflakes==2.1.1,PyJWT==1.7.1,pyparsing==2.4.2,pytest==5.1.0,pytest-factoryboy==2.0.3,pytest-flask==0.15.0,pytest-runner==5.1,python-dateutil==2.8.0,python-dotenv==0.10.3,python-editor==1.0.4,pytz==2019.2,six==1.12.0,SQLAlchemy==1.3.7,text-unidecode==1.2,toml==0.10.0,tox==3.13.2,virtualenv==16.7.3,wcwidth==0.1.7,Werkzeug==0.15.5,zipp==0.5.2
python run-test-pre: PYTHONHASHSEED='4188641553'
python run-test: commands[0] | flake8 igapi
python run-test: commands[1] | pytest tests
=============================================================================== test session starts ================================================================================
platform linux -- Python 3.5.2, pytest-5.1.0, py-1.8.0, pluggy-0.12.0
cachedir: .tox/python/.pytest_cache
rootdir: /mnt/f/workspace/git/FlaskProjectTemplate/ig-restful-api
plugins: factoryboy-2.0.3, flask-0.15.0
collected 7 items
tests/test_auth.py .. [ 28%]
tests/test_user.py FF.FF [100%]
===================================================================================== FAILURES =====================================================================================
__________________________________________________________________________________ test_get_user ___________________________________________________________________________________
client = <FlaskClient <Flask 'igapi'>>, db = <SQLAlchemy engine=sqlite:///:memory:>, user = <User user1>
admin_headers = {'authorization': 'Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZGVudGl0eSI6MSwiZXhwIjoxNTY2MTg0OTI0LCJpYXQiOjE1NjY...oxNTY2MTg0MDI0LCJ0eXBlIjoiYWNjZXNzIn0.qYzgV4glilctyzHvsBJSb6OnicTPJRskbOb3hJhRMds', 'content-type': 'application/json'}
> ???
tests/test_user.py:283:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
.tox/python/lib/python3.5/site-packages/werkzeug/test.py:1029: in get
return self.open(*args, **kw)
.tox/python/lib/python3.5/site-packages/flask/testing.py:227: in open
follow_redirects=follow_redirects,
.tox/python/lib/python3.5/site-packages/werkzeug/test.py:993: in open
response = self.run_wsgi_app(environ.copy(), buffered=buffered)
.tox/python/lib/python3.5/site-packages/werkzeug/test.py:884: in run_wsgi_app
rv = run_wsgi_app(self.application, environ, buffered=buffered)
.tox/python/lib/python3.5/site-packages/werkzeug/test.py:1119: in run_wsgi_app
app_rv = app(environ, start_response)
.tox/python/lib/python3.5/site-packages/flask/app.py:2463: in __call__
return self.wsgi_app(environ, start_response)
.tox/python/lib/python3.5/site-packages/flask/app.py:2449: in wsgi_app
response = self.handle_exception(e)
.tox/python/lib/python3.5/site-packages/flask_restful/__init__.py:269: in error_router
return original_handler(e)
.tox/python/lib/python3.5/site-packages/flask/app.py:1866: in handle_exception
reraise(exc_type, exc_value, tb)
.tox/python/lib/python3.5/site-packages/flask/_compat.py:38: in reraise
raise value.with_traceback(tb)
.tox/python/lib/python3.5/site-packages/flask/app.py:2446: in wsgi_app
response = self.full_dispatch_request()
.tox/python/lib/python3.5/site-packages/flask/app.py:1951: in full_dispatch_request
rv = self.handle_user_exception(e)
.tox/python/lib/python3.5/site-packages/flask_restful/__init__.py:269: in error_router
return original_handler(e)
.tox/python/lib/python3.5/site-packages/flask/app.py:1820: in handle_user_exception
reraise(exc_type, exc_value, tb)
.tox/python/lib/python3.5/site-packages/flask/_compat.py:38: in reraise
raise value.with_traceback(tb)
.tox/python/lib/python3.5/site-packages/flask/app.py:1949: in full_dispatch_request
rv = self.dispatch_request()
.tox/python/lib/python3.5/site-packages/flask/app.py:1935: in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
.tox/python/lib/python3.5/site-packages/flask_restful/__init__.py:458: in wrapper
resp = resource(*args, **kwargs)
.tox/python/lib/python3.5/site-packages/flask/views.py:89: in view
return self.dispatch_request(*args, **kwargs)
.tox/python/lib/python3.5/site-packages/flask_restful/__init__.py:573: in dispatch_request
resp = meth(*args, **kwargs)
.tox/python/lib/python3.5/site-packages/flask_jwt_extended/view_decorators.py:103: in wrapper
return fn(*args, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <igapi.api.resources.user.UserResource object at 0x7f87a3d18438>, user_id = 2
def get(self, user_id):
schema = UserSchema()
user = User.query.get_or_404(user_id)
> return {"user": schema.dump(user).data}
E AttributeError: 'dict' object has no attribute 'data'
igapi/api/resources/user.py:27: AttributeError
__________________________________________________________________________________ test_put_user ___________________________________________________________________________________
client = <FlaskClient <Flask 'igapi'>>, db = <SQLAlchemy engine=sqlite:///:memory:>, user = <User updated>
admin_headers = {'authorization': 'Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZGVudGl0eSI6MSwiZXhwIjoxNTY2MTg0OTI0LCJpYXQiOjE1NjY...oxNTY2MTg0MDI0LCJ0eXBlIjoiYWNjZXNzIn0.mjjdw9SzzuvAvouJyuQi96GoQurv4WWKdOy8GMU93Uo', 'content-type': 'application/json'}
def test_put_user(client, db, user, admin_headers):
# test 404
rep = client.put("/api/v1/users/100000", headers=admin_headers)
assert rep.status_code == 404
db.session.add(user)
db.session.commit()
data = {'username': 'updated'}
# test update user
rep = client.put(
'/api/v1/users/%d' % user.id,
json=data,
> headers=admin_headers
)
tests/test_user.py:50:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
.tox/python/lib/python3.5/site-packages/werkzeug/test.py:1049: in put
return self.open(*args, **kw)
.tox/python/lib/python3.5/site-packages/flask/testing.py:227: in open
follow_redirects=follow_redirects,
.tox/python/lib/python3.5/site-packages/werkzeug/test.py:993: in open
response = self.run_wsgi_app(environ.copy(), buffered=buffered)
.tox/python/lib/python3.5/site-packages/werkzeug/test.py:884: in run_wsgi_app
rv = run_wsgi_app(self.application, environ, buffered=buffered)
.tox/python/lib/python3.5/site-packages/werkzeug/test.py:1119: in run_wsgi_app
app_rv = app(environ, start_response)
.tox/python/lib/python3.5/site-packages/flask/app.py:2463: in __call__
return self.wsgi_app(environ, start_response)
.tox/python/lib/python3.5/site-packages/flask/app.py:2449: in wsgi_app
response = self.handle_exception(e)
.tox/python/lib/python3.5/site-packages/flask_restful/__init__.py:269: in error_router
return original_handler(e)
.tox/python/lib/python3.5/site-packages/flask/app.py:1866: in handle_exception
reraise(exc_type, exc_value, tb)
.tox/python/lib/python3.5/site-packages/flask/_compat.py:38: in reraise
raise value.with_traceback(tb)
.tox/python/lib/python3.5/site-packages/flask/app.py:2446: in wsgi_app
response = self.full_dispatch_request()
.tox/python/lib/python3.5/site-packages/flask/app.py:1951: in full_dispatch_request
rv = self.handle_user_exception(e)
.tox/python/lib/python3.5/site-packages/flask_restful/__init__.py:269: in error_router
return original_handler(e)
.tox/python/lib/python3.5/site-packages/flask/app.py:1820: in handle_user_exception
reraise(exc_type, exc_value, tb)
.tox/python/lib/python3.5/site-packages/flask/_compat.py:38: in reraise
raise value.with_traceback(tb)
.tox/python/lib/python3.5/site-packages/flask/app.py:1949: in full_dispatch_request
rv = self.dispatch_request()
.tox/python/lib/python3.5/site-packages/flask/app.py:1935: in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
.tox/python/lib/python3.5/site-packages/flask_restful/__init__.py:458: in wrapper
resp = resource(*args, **kwargs)
.tox/python/lib/python3.5/site-packages/flask/views.py:89: in view
return self.dispatch_request(*args, **kwargs)
.tox/python/lib/python3.5/site-packages/flask_restful/__init__.py:573: in dispatch_request
resp = meth(*args, **kwargs)
.tox/python/lib/python3.5/site-packages/flask_jwt_extended/view_decorators.py:103: in wrapper
return fn(*args, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <igapi.api.resources.user.UserResource object at 0x7f87a3c7da20>, user_id = 2
def put(self, user_id):
schema = UserSchema(partial=True)
user = User.query.get_or_404(user_id)
> user, errors = schema.load(request.json, instance=user)
E TypeError: 'User' object is not iterable
igapi/api/resources/user.py:32: TypeError
_________________________________________________________________________________ test_create_user _________________________________________________________________________________
client = <FlaskClient <Flask 'igapi'>>, db = <SQLAlchemy engine=sqlite:///:memory:>
admin_headers = {'authorization': 'Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZGVudGl0eSI6MSwiZXhwIjoxNTY2MTg0OTI0LCJpYXQiOjE1NjY...oxNTY2MTg0MDI0LCJ0eXBlIjoiYWNjZXNzIn0.0QCtn7uKt6eTjby9DA6ZvdjFn1Sach2uA-s5z8lUoy0', 'content-type': 'application/json'}
def test_create_user(client, db, admin_headers):
# test bad data
data = {
'username': 'created'
}
rep = client.post(
'/api/v1/users',
json=data,
> headers=admin_headers
)
tests/test_user.py:86:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
.tox/python/lib/python3.5/site-packages/werkzeug/test.py:1039: in post
return self.open(*args, **kw)
.tox/python/lib/python3.5/site-packages/flask/testing.py:227: in open
follow_redirects=follow_redirects,
.tox/python/lib/python3.5/site-packages/werkzeug/test.py:993: in open
response = self.run_wsgi_app(environ.copy(), buffered=buffered)
.tox/python/lib/python3.5/site-packages/werkzeug/test.py:884: in run_wsgi_app
rv = run_wsgi_app(self.application, environ, buffered=buffered)
.tox/python/lib/python3.5/site-packages/werkzeug/test.py:1119: in run_wsgi_app
app_rv = app(environ, start_response)
.tox/python/lib/python3.5/site-packages/flask/app.py:2463: in __call__
return self.wsgi_app(environ, start_response)
.tox/python/lib/python3.5/site-packages/flask/app.py:2449: in wsgi_app
response = self.handle_exception(e)
.tox/python/lib/python3.5/site-packages/flask_restful/__init__.py:269: in error_router
return original_handler(e)
.tox/python/lib/python3.5/site-packages/flask/app.py:1866: in handle_exception
reraise(exc_type, exc_value, tb)
.tox/python/lib/python3.5/site-packages/flask/_compat.py:38: in reraise
raise value.with_traceback(tb)
.tox/python/lib/python3.5/site-packages/flask/app.py:2446: in wsgi_app
response = self.full_dispatch_request()
.tox/python/lib/python3.5/site-packages/flask/app.py:1951: in full_dispatch_request
rv = self.handle_user_exception(e)
.tox/python/lib/python3.5/site-packages/flask_restful/__init__.py:269: in error_router
return original_handler(e)
.tox/python/lib/python3.5/site-packages/flask/app.py:1820: in handle_user_exception
reraise(exc_type, exc_value, tb)
.tox/python/lib/python3.5/site-packages/flask/_compat.py:38: in reraise
raise value.with_traceback(tb)
.tox/python/lib/python3.5/site-packages/flask/app.py:1949: in full_dispatch_request
rv = self.dispatch_request()
.tox/python/lib/python3.5/site-packages/flask/app.py:1935: in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
.tox/python/lib/python3.5/site-packages/flask_restful/__init__.py:458: in wrapper
resp = resource(*args, **kwargs)
.tox/python/lib/python3.5/site-packages/flask/views.py:89: in view
return self.dispatch_request(*args, **kwargs)
.tox/python/lib/python3.5/site-packages/flask_restful/__init__.py:573: in dispatch_request
resp = meth(*args, **kwargs)
.tox/python/lib/python3.5/site-packages/flask_jwt_extended/view_decorators.py:103: in wrapper
return fn(*args, **kwargs)
igapi/api/resources/user.py:60: in post
user, errors = schema.load(request.json)
.tox/python/lib/python3.5/site-packages/marshmallow_sqlalchemy/schema.py:216: in load
return super(ModelSchema, self).load(data, *args, **kwargs)
.tox/python/lib/python3.5/site-packages/marshmallow/schema.py:684: in load
data, many=many, partial=partial, unknown=unknown, postprocess=True
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <UserSchema(many=False)>, data = {'username': 'created'}
def _do_load(
self, data, *, many=None, partial=None, unknown=None, postprocess=True
):
"""Deserialize `data`, returning the deserialized result.
:param data: The data to deserialize.
:param bool many: Whether to deserialize `data` as a collection. If `None`, the
value for `self.many` is used.
:param bool|tuple partial: Whether to validate required fields. If its
value is an iterable, only fields listed in that iterable will be
ignored will be allowed missing. If `True`, all fields will be allowed missing.
If `None`, the value for `self.partial` is used.
:param unknown: Whether to exclude, include, or raise an error for unknown
fields in the data. Use `EXCLUDE`, `INCLUDE` or `RAISE`.
If `None`, the value for `self.unknown` is used.
:param bool postprocess: Whether to run post_load methods..
:return: A dict of deserialized data
:rtype: dict
"""
error_store = ErrorStore()
errors = {}
many = self.many if many is None else bool(many)
unknown = unknown or self.unknown
if partial is None:
partial = self.partial
# Run preprocessors
if self._has_processors(PRE_LOAD):
try:
processed_data = self._invoke_load_processors(
PRE_LOAD, data, many=many, original_data=data, partial=partial
)
except ValidationError as err:
errors = err.normalized_messages()
result = None
else:
processed_data = data
if not errors:
# Deserialize data
result = self._deserialize(
processed_data,
error_store=error_store,
many=many,
partial=partial,
unknown=unknown,
)
# Run field-level validation
self._invoke_field_validators(
error_store=error_store, data=result, many=many
)
# Run schema-level validation
if self._has_processors(VALIDATES_SCHEMA):
field_errors = bool(error_store.errors)
self._invoke_schema_validators(
error_store=error_store,
pass_many=True,
data=result,
original_data=data,
many=many,
partial=partial,
field_errors=field_errors,
)
self._invoke_schema_validators(
error_store=error_store,
pass_many=False,
data=result,
original_data=data,
many=many,
partial=partial,
field_errors=field_errors,
)
errors = error_store.errors
# Run post processors
if not errors and postprocess and self._has_processors(POST_LOAD):
try:
result = self._invoke_load_processors(
POST_LOAD,
result,
many=many,
original_data=data,
partial=partial,
)
except ValidationError as err:
errors = err.normalized_messages()
if errors:
exc = ValidationError(errors, data=data, valid_data=result)
self.handle_error(exc, data, many=many, partial=partial)
> raise exc
E marshmallow.exceptions.ValidationError: {'password': ['Missing data for required field.'], 'email': ['Missing data for required field.']}
.tox/python/lib/python3.5/site-packages/marshmallow/schema.py:842: ValidationError
________________________________________________________________________________ test_get_all_user _________________________________________________________________________________
client = <FlaskClient <Flask 'igapi'>>, db = <SQLAlchemy engine=sqlite:///:memory:>, user_factory = <class 'tests.test_user.UserFactory'>
admin_headers = {'authorization': 'Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZGVudGl0eSI6MSwiZXhwIjoxNTY2MTg0OTI0LCJpYXQiOjE1NjY...oxNTY2MTg0MDI0LCJ0eXBlIjoiYWNjZXNzIn0.F9D-sbfjg_jSmWcW0kkIfHBBgyfqHFXk9K1t347wWZs', 'content-type': 'application/json'}
def test_get_all_user(client, db, user_factory, admin_headers):
users = user_factory.create_batch(30)
db.session.add_all(users)
db.session.commit()
> rep = client.get('/api/v1/users', headers=admin_headers)
tests/test_user.py:113:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
.tox/python/lib/python3.5/site-packages/werkzeug/test.py:1029: in get
return self.open(*args, **kw)
.tox/python/lib/python3.5/site-packages/flask/testing.py:227: in open
follow_redirects=follow_redirects,
.tox/python/lib/python3.5/site-packages/werkzeug/test.py:993: in open
response = self.run_wsgi_app(environ.copy(), buffered=buffered)
.tox/python/lib/python3.5/site-packages/werkzeug/test.py:884: in run_wsgi_app
rv = run_wsgi_app(self.application, environ, buffered=buffered)
.tox/python/lib/python3.5/site-packages/werkzeug/test.py:1119: in run_wsgi_app
app_rv = app(environ, start_response)
.tox/python/lib/python3.5/site-packages/flask/app.py:2463: in __call__
return self.wsgi_app(environ, start_response)
.tox/python/lib/python3.5/site-packages/flask/app.py:2449: in wsgi_app
response = self.handle_exception(e)
.tox/python/lib/python3.5/site-packages/flask_restful/__init__.py:269: in error_router
return original_handler(e)
.tox/python/lib/python3.5/site-packages/flask/app.py:1866: in handle_exception
reraise(exc_type, exc_value, tb)
.tox/python/lib/python3.5/site-packages/flask/_compat.py:38: in reraise
raise value.with_traceback(tb)
.tox/python/lib/python3.5/site-packages/flask/app.py:2446: in wsgi_app
response = self.full_dispatch_request()
.tox/python/lib/python3.5/site-packages/flask/app.py:1951: in full_dispatch_request
rv = self.handle_user_exception(e)
.tox/python/lib/python3.5/site-packages/flask_restful/__init__.py:269: in error_router
return original_handler(e)
.tox/python/lib/python3.5/site-packages/flask/app.py:1820: in handle_user_exception
reraise(exc_type, exc_value, tb)
.tox/python/lib/python3.5/site-packages/flask/_compat.py:38: in reraise
raise value.with_traceback(tb)
.tox/python/lib/python3.5/site-packages/flask/app.py:1949: in full_dispatch_request
rv = self.dispatch_request()
.tox/python/lib/python3.5/site-packages/flask/app.py:1935: in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
.tox/python/lib/python3.5/site-packages/flask_restful/__init__.py:458: in wrapper
resp = resource(*args, **kwargs)
.tox/python/lib/python3.5/site-packages/flask/views.py:89: in view
return self.dispatch_request(*args, **kwargs)
.tox/python/lib/python3.5/site-packages/flask_restful/__init__.py:573: in dispatch_request
resp = meth(*args, **kwargs)
.tox/python/lib/python3.5/site-packages/flask_jwt_extended/view_decorators.py:103: in wrapper
return fn(*args, **kwargs)
igapi/api/resources/user.py:56: in get
return paginate(query, schema)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
query = <flask_sqlalchemy.BaseQuery object at 0x7f87a3addba8>, schema = <UserSchema(many=True)>
def paginate(query, schema):
page = request.args.get('page', DEFAULT_PAGE_NUMBER)
per_page = request.args.get('page_size', DEFAULT_PAGE_SIZE)
page_obj = query.paginate(page=page, per_page=per_page)
next = url_for(
request.endpoint,
page=page_obj.next_num if page_obj.has_next else page_obj.page,
per_page=per_page,
**request.view_args
)
prev = url_for(
request.endpoint,
page=page_obj.prev_num if page_obj.has_prev else page_obj.page,
per_page=per_page,
**request.view_args
)
return {
'total': page_obj.total,
'pages': page_obj.pages,
'next': next,
'prev': prev,
> 'results': schema.dump(page_obj.items).data
}
E AttributeError: 'list' object has no attribute 'data'
igapi/commons/pagination.py:31: AttributeError
=========================================================================== 4 failed, 3 passed in 2.88s ============================================================================
ERROR: InvocationError for command /mnt/f/workspace/git/FlaskProjectTemplate/ig-restful-api/.tox/python/bin/pytest tests (exited with code 1)
_____________________________________________________________________________________ summary ______________________________________________________________________________________
ERROR: python: commands failed
alembic==1.0.11
aniso8601==7.0.0
attrs==19.1.0
Click==7.0
filelock==3.0.12
Flask==1.1.1
Flask-JWT-Extended==3.21.0
flask-marshmallow==0.10.1
Flask-Migrate==2.5.2
Flask-RESTful==0.3.7
Flask-SQLAlchemy==2.4.0
# Editable install with no version control (igapi==0.1)
-e /mnt/f/workspace/git/FlaskProjectTemplate/ig-restful-api
importlib-metadata==0.19
itsdangerous==1.1.0
Jinja2==2.10.1
Mako==1.1.0
MarkupSafe==1.1.1
marshmallow==3.0.0
marshmallow-sqlalchemy==0.17.0
packaging==19.1
passlib==1.7.1
pluggy==0.12.0
py==1.8.0
PyJWT==1.7.1
pyparsing==2.4.2
python-dateutil==2.8.0
python-dotenv==0.10.3
python-editor==1.0.4
pytz==2019.2
six==1.12.0
SQLAlchemy==1.3.7
toml==0.10.0
tox==3.13.2
virtualenv==16.7.3
Werkzeug==0.15.
Version 3.0.0 of marshmallow will introduce many backwards-incompatible changes. It could be nice to upgrade this cookiecutter to make it compatible with this new version.
http://marshmallow.readthedocs.io/en/latest/changelog.html#changelog
Is there a reason this example doesn't have a user logout function that invalidates the jwt?
I found that we have a login
endpoint but not a register
endpoint.
Is a register endpoint within the scope of this cookie cutter?
Shouldn't this be client.delete instead of client.put
Feature request - celery implementation.
Really cool project, thank you very much for all your efforts! β€οΈ
Modern Python project uses the pyproject.toml
file to configure a project. However, this can't be selected by these cookiecutter templates.
If it's feasible, could we offer an option to select between setup.py
and pyproject.toml
? We could use setup.py
as default, but offer the new option if people want to go this way.
Thanks!
Add support for swagger using https://github.com/marshmallow-code/apispec
Is use_factory function deprecated by UserFactory class? I want to confirm this. Tests are passed if I delete this file.
Hello Is there a API method generation option instead of handcoding. like
myapi -add methodname -params
The framework is great but would like to know if there is any example for the same to add APIs
Thanks
Bhushan
flask db upgrade
Traceback (most recent call last):
File "/Users/tirghose/Work/src/py/.venv_upann/bin/flask", line 8, in
sys.exit(main())
File "/Users/tirghose/Work/src/py/.venv_upann/lib/python3.9/site-packages/flask/cli.py", line 994, in main
cli.main(args=sys.argv[1:])
File "/Users/tirghose/Work/src/py/.venv_upann/lib/python3.9/site-packages/flask/cli.py", line 600, in main
return super().main(*args, **kwargs)
File "/Users/tirghose/Work/src/py/.venv_upann/lib/python3.9/site-packages/click/core.py", line 782, in main
rv = self.invoke(ctx)
File "/Users/tirghose/Work/src/py/.venv_upann/lib/python3.9/site-packages/click/core.py", line 1259, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/Users/tirghose/Work/src/py/.venv_upann/lib/python3.9/site-packages/click/core.py", line 1259, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/Users/tirghose/Work/src/py/.venv_upann/lib/python3.9/site-packages/click/core.py", line 1066, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/Users/tirghose/Work/src/py/.venv_upann/lib/python3.9/site-packages/click/core.py", line 610, in invoke
return callback(*args, **kwargs)
File "/Users/tirghose/Work/src/py/.venv_upann/lib/python3.9/site-packages/click/decorators.py", line 21, in new_func
return f(get_current_context(), *args, **kwargs)
File "/Users/tirghose/Work/src/py/.venv_upann/lib/python3.9/site-packages/flask/cli.py", line 443, in decorator
with __ctx.ensure_object(ScriptInfo).load_app().app_context():
File "/Users/tirghose/Work/src/py/.venv_upann/lib/python3.9/site-packages/flask/cli.py", line 406, in load_app
app = locate_app(self, import_name, name)
File "/Users/tirghose/Work/src/py/.venv_upann/lib/python3.9/site-packages/flask/cli.py", line 278, in locate_app
return find_app_by_string(script_info, module, app_name)
File "/Users/tirghose/Work/src/py/.venv_upann/lib/python3.9/site-packages/flask/cli.py", line 205, in find_app_by_string
app = call_factory(script_info, attr, args, kwargs)
File "/Users/tirghose/Work/src/py/.venv_upann/lib/python3.9/site-packages/flask/cli.py", line 123, in call_factory
return app_factory(*args, **kwargs)
File "/Users/tirghose/Work/src/py/upann_api/upann/app.py", line 14, in create_app
app.config.from_object("upann.config")
File "/Users/tirghose/Work/src/py/.venv_upann/lib/python3.9/site-packages/flask/config.py", line 162, in from_object
obj = import_string(obj)
File "/Users/tirghose/Work/src/py/.venv_upann/lib/python3.9/site-packages/werkzeug/utils.py", line 887, in import_string
raise ImportStringError(import_name, e).with_traceback(
File "/Users/tirghose/Work/src/py/.venv_upann/lib/python3.9/site-packages/werkzeug/utils.py", line 883, in import_string
raise ImportError(e) from None
werkzeug.utils.ImportStringError: import_string() failed for 'upann.config'. Possible reasons are:
Debugged import:
Original exception:
ImportError: module 'upann' has no attribute 'config'
The generated project contains a setup.py
. Although this file is small and doesn't have much in it, it doesn't follow a more declarative way.
Although it's not mandatory of course, we should follow a more declarative approach. For example, we could add all the meta data into setup.cfg
and have a very minimal setup.py
. See the link below for a more exhaustive description.
I think there are some benefits for this approach. We encourage developers to add meta data into setup.cfg
, keeping setup.py
small. It's probably a bit easier to move to pyproject.toml
if someone wants to go that way. It's also more in sync with the modern way to package Python project.
https://setuptools.rtfd.io/en/latest/userguide/declarative_config.html
On a new cookiecutter from this repo, there is a missing client
pytest fixture:
$ cookiecutter https://github.com/karec/cookiecutter-flask-restful
You've downloaded /Users/gburek/.cookiecutters/cookiecutter-flask-restful before. Is it okay to delete and re-download it? [yes]:
project_name [restful_api]:
app_name [myapi]:
$ cd restful_api
$ pipenv install
Creating a virtualenv for this project...
Pipfile: /Users/gburek/code/restful_api/Pipfile
Using /Users/gburek/.pyenv/versions/3.6.5/bin/python3.6 (3.6.5) to create virtualenv...
β Already using interpreter /Users/gburek/.pyenv/versions/3.6.5/bin/python3.6
Using base prefix '/Users/gburek/.pyenv/versions/3.6.5'
New python executable in /Users/gburek/.local/share/virtualenvs/restful_api-w6vN7KAs/bin/python3.6
Also creating executable in /Users/gburek/.local/share/virtualenvs/restful_api-w6vN7KAs/bin/python
Installing setuptools, pip, wheel...done.
Setting project for restful_api-w6vN7KAs to /Users/gburek/code/restful_api
Virtualenv location: /Users/gburek/.local/share/virtualenvs/restful_api-w6vN7KAs
requirements.txt found, instead of Pipfile! Converting...
Warning: Your Pipfile now contains pinned versions, if your requirements.txt did.
We recommend updating your Pipfile to specify the "*" version, instead.
Pipfile.lock not found, creating...
Locking [dev-packages] dependencies...
Locking [packages] dependencies...
Updated Pipfile.lock (7950d7)!
Installing dependencies from Pipfile.lock (7950d7)...
π ββββββββββββββββββββββββββββββββ 29/29 β 00:00:08
To activate this project's virtualenv, run pipenv shell.
Alternatively, run a command inside the virtualenv with pipenv run.
$ pipenv install --dev pytest pytest_factoryboy
Installing pytest...
Collecting pytest
Using cached https://files.pythonhosted.org/packages/0c/9a/592314ceda78f3307afb6cf56d7fdbb92c5a5960a88a6d2fd25c11312ead/pytest-3.8.1-py2.py3-none-any.whl
Requirement already satisfied: setuptools in /Users/gburek/.local/share/virtualenvs/restful_api-w6vN7KAs/lib/python3.6/site-packages (from pytest) (40.4.3)
Requirement already satisfied: six>=1.10.0 in /Users/gburek/.local/share/virtualenvs/restful_api-w6vN7KAs/lib/python3.6/site-packages (from pytest) (1.11.0)
Collecting attrs>=17.4.0 (from pytest)
Using cached https://files.pythonhosted.org/packages/3a/e1/5f9023cc983f1a628a8c2fd051ad19e76ff7b142a0faf329336f9a62a514/attrs-18.2.0-py2.py3-none-any.whl
Collecting atomicwrites>=1.0 (from pytest)
Using cached https://files.pythonhosted.org/packages/3a/9a/9d878f8d885706e2530402de6417141129a943802c084238914fa6798d97/atomicwrites-1.2.1-py2.py3-none-any.whl
Requirement already satisfied: pluggy>=0.7 in /Users/gburek/.local/share/virtualenvs/restful_api-w6vN7KAs/lib/python3.6/site-packages (from pytest) (0.7.1)
Requirement already satisfied: py>=1.5.0 in /Users/gburek/.local/share/virtualenvs/restful_api-w6vN7KAs/lib/python3.6/site-packages (from pytest) (1.6.0)
Collecting more-itertools>=4.0.0 (from pytest)
Using cached https://files.pythonhosted.org/packages/79/b1/eace304ef66bd7d3d8b2f78cc374b73ca03bc53664d78151e9df3b3996cc/more_itertools-4.3.0-py3-none-any.whl
Installing collected packages: attrs, atomicwrites, more-itertools, pytest
Successfully installed atomicwrites-1.2.1 attrs-18.2.0 more-itertools-4.3.0 pytest-3.8.1
Adding pytest to Pipfile's [dev-packages]...
Installing pytest_factoryboy...
Collecting pytest_factoryboy
Collecting inflection (from pytest_factoryboy)
Requirement already satisfied: pytest>=3.3.2 in /Users/gburek/.local/share/virtualenvs/restful_api-w6vN7KAs/lib/python3.6/site-packages (from pytest_factoryboy) (3.8.1)
Collecting factory-boy>=2.10.0 (from pytest_factoryboy)
Using cached https://files.pythonhosted.org/packages/19/6c/b2ac85b3f0b48ac968af3741c4f020bf272ab9dabbd1643e9c719441099a/factory_boy-2.11.1-py2.py3-none-any.whl
Requirement already satisfied: more-itertools>=4.0.0 in /Users/gburek/.local/share/virtualenvs/restful_api-w6vN7KAs/lib/python3.6/site-packages (from pytest>=3.3.2->pytest_factoryboy) (4.3.0)
Requirement already satisfied: pluggy>=0.7 in /Users/gburek/.local/share/virtualenvs/restful_api-w6vN7KAs/lib/python3.6/site-packages (from pytest>=3.3.2->pytest_factoryboy) (0.7.1)
Requirement already satisfied: py>=1.5.0 in /Users/gburek/.local/share/virtualenvs/restful_api-w6vN7KAs/lib/python3.6/site-packages (from pytest>=3.3.2->pytest_factoryboy) (1.6.0)
Requirement already satisfied: atomicwrites>=1.0 in /Users/gburek/.local/share/virtualenvs/restful_api-w6vN7KAs/lib/python3.6/site-packages (from pytest>=3.3.2->pytest_factoryboy) (1.2.1)
Requirement already satisfied: six>=1.10.0 in /Users/gburek/.local/share/virtualenvs/restful_api-w6vN7KAs/lib/python3.6/site-packages (from pytest>=3.3.2->pytest_factoryboy) (1.11.0)
Requirement already satisfied: setuptools in /Users/gburek/.local/share/virtualenvs/restful_api-w6vN7KAs/lib/python3.6/site-packages (from pytest>=3.3.2->pytest_factoryboy) (40.4.3)
Requirement already satisfied: attrs>=17.4.0 in /Users/gburek/.local/share/virtualenvs/restful_api-w6vN7KAs/lib/python3.6/site-packages (from pytest>=3.3.2->pytest_factoryboy) (18.2.0)
Collecting Faker>=0.7.0 (from factory-boy>=2.10.0->pytest_factoryboy)
Using cached https://files.pythonhosted.org/packages/6e/e6/78a4bcf0e59c31b0ed9f4b81ef62cf6b7f4978755b5a88e566dc0fec8e06/Faker-0.9.1-py2.py3-none-any.whl
Requirement already satisfied: python-dateutil>=2.4 in /Users/gburek/.local/share/virtualenvs/restful_api-w6vN7KAs/lib/python3.6/site-packages (from Faker>=0.7.0->factory-boy>=2.10.0->pytest_factoryboy) (2.7.3)
Collecting text-unidecode==1.2 (from Faker>=0.7.0->factory-boy>=2.10.0->pytest_factoryboy)
Using cached https://files.pythonhosted.org/packages/79/42/d717cc2b4520fb09e45b344b1b0b4e81aa672001dd128c180fabc655c341/text_unidecode-1.2-py2.py3-none-any.whl
Installing collected packages: inflection, text-unidecode, Faker, factory-boy, pytest-factoryboy
Successfully installed Faker-0.9.1 factory-boy-2.11.1 inflection-0.3.1 pytest-factoryboy-2.0.1 text-unidecode-1.2
Adding pytest_factoryboy to Pipfile's [dev-packages]...
Pipfile.lock (7950d7) out of date, updating to (4b7861)...
Locking [dev-packages] dependencies...
Locking [packages] dependencies...
Updated Pipfile.lock (4b7861)!
Installing dependencies from Pipfile.lock (4b7861)...
π ββββββββββββββββββββββββββββββββ 42/42 β 00:00:08
To activate this project's virtualenv, run pipenv shell.
Alternatively, run a command inside the virtualenv with pipenv run.
$ pipenv run py.test
============================================================================================================================== test session starts ==============================================================================================================================
platform darwin -- Python 3.6.5, pytest-3.8.1, py-1.6.0, pluggy-0.7.1
rootdir: /Users/gburek/code/restful_api, inifile:
plugins: factoryboy-2.0.1
collected 7 items
tests/test_auth.py EE [ 28%]
tests/test_user.py EEEEE [100%]
==================================================================================================================================== ERRORS =====================================================================================================================================
__________________________________________________________________________________________________________________ ERROR at setup of test_revoke_access_token ___________________________________________________________________________________________________________________
file /Users/gburek/code/restful_api/tests/test_auth.py, line 1
def test_revoke_access_token(client, admin_headers):
E fixture 'client' not found
> available fixtures: admin_headers, admin_refresh_headers, admin_user, app, cache, capfd, capfdbinary, caplog, capsys, capsysbinary, db, doctest_namespace, factoryboy_request, monkeypatch, pytestconfig, record_property, record_xml_attribute, record_xml_property, recwarn, tmpdir, tmpdir_factory
> use 'pytest --fixtures [testpath]' for help on them.
/Users/gburek/code/restful_api/tests/test_auth.py:1
__________________________________________________________________________________________________________________ ERROR at setup of test_revoke_refresh_token __________________________________________________________________________________________________________________
file /Users/gburek/code/restful_api/tests/test_auth.py, line 9
def test_revoke_refresh_token(client, admin_refresh_headers):
E fixture 'client' not found
> available fixtures: admin_headers, admin_refresh_headers, admin_user, app, cache, capfd, capfdbinary, caplog, capsys, capsysbinary, db, doctest_namespace, factoryboy_request, monkeypatch, pytestconfig, record_property, record_xml_attribute, record_xml_property, recwarn, tmpdir, tmpdir_factory
> use 'pytest --fixtures [testpath]' for help on them.
/Users/gburek/code/restful_api/tests/test_auth.py:9
________________________________________________________________________________________________________________________ ERROR at setup of test_get_user ________________________________________________________________________________________________________________________
file /Users/gburek/code/restful_api/tests/test_user.py, line 18
def test_get_user(client, db, user, admin_headers):
E fixture 'client' not found
> available fixtures: admin_headers, admin_refresh_headers, admin_user, app, cache, capfd, capfdbinary, caplog, capsys, capsysbinary, db, doctest_namespace, factoryboy_request, monkeypatch, pytestconfig, record_property, record_xml_attribute, record_xml_property, recwarn, tmpdir, tmpdir_factory, user, user__email, user__password, user__username, user_factory
> use 'pytest --fixtures [testpath]' for help on them.
/Users/gburek/code/restful_api/tests/test_user.py:18
________________________________________________________________________________________________________________________ ERROR at setup of test_put_user ________________________________________________________________________________________________________________________
file /Users/gburek/code/restful_api/tests/test_user.py, line 36
def test_put_user(client, db, user, admin_headers):
E fixture 'client' not found
> available fixtures: admin_headers, admin_refresh_headers, admin_user, app, cache, capfd, capfdbinary, caplog, capsys, capsysbinary, db, doctest_namespace, factoryboy_request, monkeypatch, pytestconfig, record_property, record_xml_attribute, record_xml_property, recwarn, tmpdir, tmpdir_factory, user, user__email, user__password, user__username, user_factory
> use 'pytest --fixtures [testpath]' for help on them.
/Users/gburek/code/restful_api/tests/test_user.py:36
______________________________________________________________________________________________________________________ ERROR at setup of test_delete_user _______________________________________________________________________________________________________________________
file /Users/gburek/code/restful_api/tests/test_user.py, line 60
def test_delete_user(client, db, user, admin_headers):
E fixture 'client' not found
> available fixtures: admin_headers, admin_refresh_headers, admin_user, app, cache, capfd, capfdbinary, caplog, capsys, capsysbinary, db, doctest_namespace, factoryboy_request, monkeypatch, pytestconfig, record_property, record_xml_attribute, record_xml_property, recwarn, tmpdir, tmpdir_factory, user, user__email, user__password, user__username, user_factory
> use 'pytest --fixtures [testpath]' for help on them.
/Users/gburek/code/restful_api/tests/test_user.py:60
______________________________________________________________________________________________________________________ ERROR at setup of test_create_user _______________________________________________________________________________________________________________________
file /Users/gburek/code/restful_api/tests/test_user.py, line 78
def test_create_user(client, db, admin_headers):
E fixture 'client' not found
> available fixtures: admin_headers, admin_refresh_headers, admin_user, app, cache, capfd, capfdbinary, caplog, capsys, capsysbinary, db, doctest_namespace, factoryboy_request, monkeypatch, pytestconfig, record_property, record_xml_attribute, record_xml_property, recwarn, tmpdir, tmpdir_factory, user, user__email, user__password, user__username, user_factory
> use 'pytest --fixtures [testpath]' for help on them.
/Users/gburek/code/restful_api/tests/test_user.py:78
______________________________________________________________________________________________________________________ ERROR at setup of test_get_all_user ______________________________________________________________________________________________________________________
file /Users/gburek/code/restful_api/tests/test_user.py, line 107
def test_get_all_user(client, db, user_factory, admin_headers):
E fixture 'client' not found
> available fixtures: admin_headers, admin_refresh_headers, admin_user, app, cache, capfd, capfdbinary, caplog, capsys, capsysbinary, db, doctest_namespace, factoryboy_request, monkeypatch, pytestconfig, record_property, record_xml_attribute, record_xml_property, recwarn, tmpdir, tmpdir_factory, user, user__email, user__password, user__username, user_factory
> use 'pytest --fixtures [testpath]' for help on them.
/Users/gburek/code/restful_api/tests/test_user.py:107
============================================================================================================================ 7 error in 0.26 seconds ============================================================================================================================
It appears to be wanting something like http://flask.pocoo.org/docs/1.0/testing/#the-testing-skeleton
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.