GithubHelp home page GithubHelp logo

briancappello / flask-unchained Goto Github PK

View Code? Open in Web Editor NEW
79.0 79.0 8.0 1.99 MB

The quickest and easiest way to build large web apps and APIs with Flask

Home Page: https://flask-unchained.readthedocs.io

License: MIT License

Python 96.22% Makefile 0.02% HTML 2.78% CSS 0.07% Mako 0.14% JavaScript 0.76% Jinja 0.01%
framework python3 web

flask-unchained's People

Contributors

briancappello avatar chriamue avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

flask-unchained's Issues

Create a new release?

Looks like BundleConfig was introduced on 16 October 2018, but release 0.6.6 was cut on 9 October 2018, which means the latest release doesn't have this class defined.

The missing class definition means that flask-unchained-react-spa doesn't work out of the box.

Cutting a new release would presumably fix: briancappello/flask-unchained-react-spa#3

wrong redirect uri for oauth using docker

When running backend in a docker container using backend as its dns,
a frontend proxying to the backend hosting at example.com,
gitlab url conains backend:5000 which should be example.com:

&redirect_uri=https%3A%2F%2Fbackend%3A5000%2Fauth%2Fauthorized%2Fgitlab&scope=openid+read_user

The config.py contains this for oauth:

OAUTH_REMOTE_APP_GITLAB = dict(
        consumer_key=os.getenv('OAUTH_GITLAB_CONSUMER_KEY', ''),
        consumer_secret=os.getenv('OAUTH_GITLAB_CONSUMER_SECRET', ''),
        base_url='https://gitlab.com/api/v4/user',
        access_token_url='https://gitlab.com/oauth/token',
        access_token_method='POST',
        authorize_url='https://gitlab.com/oauth/authorize',
        request_token_url=None,
        request_token_params={'scope': 'openid read_user'},
    )

Adding
SERVER_NAME='example.com' breaks

The problem is url_for in bundles.oauth.views.OAuthController.login,
which creates http://backend:5000.

return provider.authorize(callback=url_for(
            'o_auth_controller.authorized', remote_app=remote_app,
            _external=True, _scheme='https'))

Is there a way to customize the generated url_for.
Setting SERVER_NAME='example.com' breaks, frontend be able to reach the server using backend:5000.

KeyError: 'UserResource.patch'

pip install git+https://github.com/briancappello/flask-unchained
flask new project testproj # y to all
cd testproj/
pip install -r requirements-dev.txt
pip install marshmallow-sqlalchemy==0.14.1
flask run

Bundles Config:

BUNDLES = [
    'flask_unchained.bundles.api',
    'flask_unchained.bundles.mail',
    'flask_unchained.bundles.celery',  # move before mail to send emails synchronously
    'flask_unchained.bundles.security',
    'flask_unchained.bundles.session',
    'flask_unchained.bundles.sqlalchemy',
    'flask_unchained.bundles.webpack',

    'app',  # your app bundle *must* be last
]

Opening localhost:5000 in browser throws following:

flask run
 * Environment: development
 * Debug mode: on
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 117-607-828
127.0.0.1 - - [18/Nov/2018 10:17:36] "GET / HTTP/1.1" 500 -
Traceback (most recent call last):
  File "/home/chriamue/temp/venv/lib/python3.6/site-packages/flask/app.py", line 2309, in __call__
    return self.wsgi_app(environ, start_response)
  File "/home/chriamue/temp/venv/lib/python3.6/site-packages/flask/app.py", line 2295, in wsgi_app
    response = self.handle_exception(e)
  File "/home/chriamue/temp/venv/lib/python3.6/site-packages/flask/app.py", line 1741, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/home/chriamue/temp/venv/lib/python3.6/site-packages/flask/_compat.py", line 35, in reraise
    raise value
  File "/home/chriamue/temp/venv/lib/python3.6/site-packages/flask/app.py", line 2292, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/chriamue/temp/venv/lib/python3.6/site-packages/flask/app.py", line 1808, in full_dispatch_request
    self.try_trigger_before_first_request_functions()
  File "/home/chriamue/temp/venv/lib/python3.6/site-packages/flask/app.py", line 1855, in try_trigger_before_first_request_functions
    func()
  File "/home/chriamue/temp/venv/lib/python3.6/site-packages/flask_unchained/bundles/api/__init__.py", line 62, in register_model_resources
    api.register_model_resource(resource)
  File "/home/chriamue/temp/venv/lib/python3.6/site-packages/flask_unchained/bundles/api/extensions/api.py", line 123, in register_model_resource
    route = unchained.controller_bundle.controller_endpoints[key]
KeyError: 'UserResource.patch'

[BUG] Admin bundle points to security.login, but Security bundle defines security_controller.login

First of, I just want to say thank you for making this package. This is exactly what I need for a project I'm doing.

Anyways, the issue at hand:

The login and logout endpoints specified in the Admin bundle config seems to point to an endpoint in the Security bundle which doesn't exist in the current commit.

i.e. ADMIN_LOGOUT_ENDPOINT = "security.logout"

ADMIN_LOGIN_ENDPOINT = 'security.login'

My workaround is just to set this variable in my project config to ADMIN_LOGOUT_ENDPOINT = "security_controller.logout"

I think a better solution would be to either set the config variable in the Admin bundle itself to "security_controller.<endpoint>", or edit the references in the Security bundle to "security.<endpoint>". I don't have a personal opinion on which option is better. Maybe there's even a better solution.

I can make a PR either way, if needed.

Attached is a screenshot of the werkzeug routing error I encounter when trying to access /admin/.

Screenshot from 2021-01-16 10-33-24

no such table: flask_sessions

With and without

class Config(AppBundleConfig):
SQLALCHEMY_DATABASE_URI = 'sqlite:///db/flaskr.sqlite'

in file app/config.py

127.0.0.1 - - [18/Nov/2018 16:35:46] "GET / HTTP/1.1" 500 -
Traceback (most recent call last):
  File "/home/chriamue/temp/venv/lib/python3.6/site-packages/flask/app.py", line 2309, in __call__
    return self.wsgi_app(environ, start_response)
  File "/home/chriamue/temp/venv/lib/python3.6/site-packages/flask/app.py", line 2295, in wsgi_app
    response = self.handle_exception(e)
  File "/home/chriamue/temp/venv/lib/python3.6/site-packages/flask/app.py", line 1741, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/home/chriamue/temp/venv/lib/python3.6/site-packages/flask/_compat.py", line 35, in reraise
    raise value
  File "/home/chriamue/temp/venv/lib/python3.6/site-packages/flask/app.py", line 2292, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/chriamue/temp/venv/lib/python3.6/site-packages/flask/app.py", line 1816, in full_dispatch_request
    return self.finalize_request(rv)
  File "/home/chriamue/temp/venv/lib/python3.6/site-packages/flask/app.py", line 1833, in finalize_request
    response = self.process_response(response)
  File "/home/chriamue/temp/venv/lib/python3.6/site-packages/flask/app.py", line 2114, in process_response
    self.session_interface.save_session(self, ctx.session, response)
  File "/home/chriamue/temp/venv/lib/python3.6/site-packages/flask_session/sessions.py", line 535, in save_session
    session_id=store_id).first()
  File "/home/chriamue/temp/venv/lib/python3.6/site-packages/sqlalchemy/orm/query.py", line 2895, in first
    ret = list(self[0:1])
  File "/home/chriamue/temp/venv/lib/python3.6/site-packages/sqlalchemy/orm/query.py", line 2687, in __getitem__
    return list(res)
  File "/home/chriamue/temp/venv/lib/python3.6/site-packages/sqlalchemy/orm/query.py", line 2995, in __iter__
    return self._execute_and_instances(context)
  File "/home/chriamue/temp/venv/lib/python3.6/site-packages/sqlalchemy/orm/query.py", line 3018, in _execute_and_instances
    result = conn.execute(querycontext.statement, self._params)
  File "/home/chriamue/temp/venv/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 948, in execute
    return meth(self, multiparams, params)
  File "/home/chriamue/temp/venv/lib/python3.6/site-packages/sqlalchemy/sql/elements.py", line 269, in _execute_on_connection
    return connection._execute_clauseelement(self, multiparams, params)
  File "/home/chriamue/temp/venv/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 1060, in _execute_clauseelement
    compiled_sql, distilled_params
  File "/home/chriamue/temp/venv/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 1200, in _execute_context
    context)
  File "/home/chriamue/temp/venv/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 1413, in _handle_dbapi_exception
    exc_info
  File "/home/chriamue/temp/venv/lib/python3.6/site-packages/sqlalchemy/util/compat.py", line 265, in raise_from_cause
    reraise(type(exception), exception, tb=exc_tb, cause=cause)
  File "/home/chriamue/temp/venv/lib/python3.6/site-packages/sqlalchemy/util/compat.py", line 248, in reraise
    raise value.with_traceback(tb)
  File "/home/chriamue/temp/venv/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 1193, in _execute_context
    context)
  File "/home/chriamue/temp/venv/lib/python3.6/site-packages/sqlalchemy/engine/default.py", line 509, in do_execute
    cursor.execute(statement, parameters)
sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such table: flask_sessions [SQL: 'SELECT flask_sessions.id AS flask_sessions_id, flask_sessions.session_id AS flask_sessions_session_id, flask_sessions.data AS flask_sessions_data, flask_sessions.expiry AS flask_sessions_expiry, flask_sessions.created_at AS flask_sessions_created_at, flask_sessions.updated_at AS flask_sessions_updated_at \nFROM flask_sessions \nWHERE flask_sessions.session_id = ?\n LIMIT ? OFFSET ?'] [parameters: ('session:31d9ead7-138a-4d50-be58-2f2c8d54a8f2', 1, 0)] (Background on this error at: http://sqlalche.me/e/e3q8)

I tried flask db init, but didn't help.
db/flaskr.sqlite is generated but empty.

stacking route annotations

Hi, a single route annotation works, tried both,
but stacking route annotations, only first works.

    @route('/list/<string:project>/', defaults={'req_path': ''})
    @route('/list/<string:project>/<path:req_path>')
    def image_listing(self, project, req_path):
...

consider using black formatter

Many upstream projects are converging to black, and we did so at my former employer as well. It's extremely opinionated (and I found it somewhat ugly at first sight), but on the other hand, it:

  • completely eliminated all discussions around style internally
  • is nice to read open source code that uses it too, so that hopping from codebase to codebase is less jarring

Consider using it in this project too?

https://github.com/ambv/black

I'd even go so far as to vote for a single, minor customization of changing the default line length back down to 80 columns (instead of its default of 88), but feel free to ignore that suggestion if it's not your cup of tea.

KeyError: 'No serializer found for the User model

It looks like there are serializers for https://github.com/briancappello/flask-unchained/blob/master/flask_unchained/_code_templates/project/app/models/user.py needed, which is missing.

pip install git+https://github.com/briancappello/flask-unchained
flask new project testproj # y to all
cd testproj/
pip install -r requirements-dev.txt
flask run

Traceback (most recent call last):
File "/home/chriamue/temp/venv/lib/python3.6/site-packages/flask_unchained/bundles/api/hooks/register_model_resources_hook.py", line 30, in attach_serializers_to_resource_cls
serializer_cls = self.bundle.serializers_by_model[model_name]
KeyError: 'User'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/home/chriamue/temp/venv/lib/python3.6/site-packages/flask_unchained/cli.py", line 56, in cli_create_app
return AppFactory.create_app(env)
File "/home/chriamue/temp/venv/lib/python3.6/site-packages/flask_unchained/app_factory.py", line 75, in create_app
unchained.init_app(app, env, bundles, _config_overrides=_config_overrides)
File "/home/chriamue/temp/venv/lib/python3.6/site-packages/flask_unchained/unchained.py", line 107, in init_app
run_hooks_hook.run_hook(app, bundles, _config_overrides=_config_overrides)
File "/home/chriamue/temp/venv/lib/python3.6/site-packages/flask_unchained/hooks/run_hooks_hook.py", line 34, in run_hook
hook.run_hook(app, bundles)
File "/home/chriamue/temp/venv/lib/python3.6/site-packages/flask_unchained/app_factory_hook.py", line 98, in run_hook
self.process_objects(app, self.collect_from_bundles(bundles))
File "/home/chriamue/temp/venv/lib/python3.6/site-packages/flask_unchained/bundles/api/hooks/register_model_resources_hook.py", line 25, in process_objects
self.attach_serializers_to_resource_cls(model_name, resource_cls)
File "/home/chriamue/temp/venv/lib/python3.6/site-packages/flask_unchained/bundles/api/hooks/register_model_resources_hook.py", line 32, in attach_serializers_to_resource_cls
raise KeyError(f'No serializer found for the {model_name} model')
KeyError: 'No serializer found for the User model'

Possible switch from venv to pipenv

In my experience, I have found it easier to both work with and teach pipenv over venv, would you be open to switching to that? I am looking to implement dotenv but don't want to double up on work if I can help it.

Where would you put plain python classes?

Let's say you had an API endpoint somewhere. You want to keep some logic out of the view, but you also need to have some method/functionality. For example's sake, it's some generic thing like reversing a list. Some projects might be tempted to make a utils package and start dumping code into that. I try to delay that as much as I can because it turns out to be a junk drawer. Since Flask-Unchained is slightly opinionated (not pejorative - I prefer this in a framework), where would you put plain old python classes?

Answering my own question, here are some thoughts or suggestions:

  • helpers/ - It's too close to utils. Everything should be helping. Eh. I usually have formatters for views or something near something else for this
  • models/ - Is sqlalchemy. Reversing a list doesn't touch the database. The name is very close and a model doesn't have to touch the database. In this case, a list doesn't really contain data. A User / Person / Employee / Product / Comment is a model.
  • lib/ - Is more of a C/C++ convention, I don't hate it though.
  • services/ - I'd consider this hitting the network. A network service. The term is overused. FormObjects are sometimes called services.
  • utils/ - The default. Turns into a junk drawer.
  • list/ - Naming it after the business case, the domain is not how Flask-Unchained is organized. It's organized by technical types.
  • decorators/ - I like this for views, same as FormObjects.
  • presenters/ - Now we're just doing synonyms here. I like this for this example because I'm probably reversing a list for a table maybe? My made up example isn't real.

Maybe the hangup on presents answers the question. I should think more about why I'm reversing a list. If it's on the backend to the database, put it in there. If it's on the backend talking to a service, put it in services. If it's going to the frontend for the view, put it in helpers. If it is so general that it is used by everything, put it in utils?

Naming stuff is hard. ๐ŸŒป

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.