17
17
import click
18
18
19
19
from ._compat import iteritems , reraise
20
+ from .helpers import get_debug_flag
20
21
21
22
22
23
class NoAppException (click .UsageError ):
@@ -98,6 +99,15 @@ def locate_app(app_id):
98
99
return app
99
100
100
101
102
+ def find_default_import_path ():
103
+ app = os .environ .get ('FLASK_APP' )
104
+ if app is None :
105
+ return
106
+ if os .path .isfile (app ):
107
+ return prepare_exec_for_file (app )
108
+ return app
109
+
110
+
101
111
class DispatchingApp (object ):
102
112
"""Special application that dispatches to a flask application which
103
113
is imported by name in a background thread. If an error happens
@@ -158,12 +168,13 @@ class ScriptInfo(object):
158
168
to click.
159
169
"""
160
170
161
- def __init__ (self , app_import_path = None , debug = None , create_app = None ):
162
- #: The application import path
163
- self .app_import_path = app_import_path
164
- #: The debug flag. If this is not None, the application will
165
- #: automatically have it's debug flag overridden with this value.
166
- self .debug = debug
171
+ def __init__ (self , app_import_path = None , create_app = None ):
172
+ if create_app is None :
173
+ if app_import_path is None :
174
+ app_import_path = find_default_import_path ()
175
+ self .app_import_path = app_import_path
176
+ else :
177
+ self .app_import_path = None
167
178
#: Optionally a function that is passed the script info to create
168
179
#: the instance of the application.
169
180
self .create_app = create_app
@@ -185,11 +196,12 @@ def load_app(self):
185
196
else :
186
197
if self .app_import_path is None :
187
198
raise NoAppException ('Could not locate Flask application. '
188
- 'You did not provide FLASK_APP or the '
189
- '--app parameter .' )
199
+ 'You did not provide the FLASK_APP '
200
+ 'environment variable .' )
190
201
rv = locate_app (self .app_import_path )
191
- if self .debug is not None :
192
- rv .debug = self .debug
202
+ debug = get_debug_flag ()
203
+ if debug is not None :
204
+ rv .debug = debug
193
205
self ._loaded_app = rv
194
206
return rv
195
207
@@ -210,29 +222,6 @@ def decorator(__ctx, *args, **kwargs):
210
222
return update_wrapper (decorator , f )
211
223
212
224
213
- def set_debug_value (ctx , param , value ):
214
- ctx .ensure_object (ScriptInfo ).debug = value
215
-
216
-
217
- def set_app_value (ctx , param , value ):
218
- if value is not None :
219
- if os .path .isfile (value ):
220
- value = prepare_exec_for_file (value )
221
- elif '.' not in sys .path :
222
- sys .path .insert (0 , '.' )
223
- ctx .ensure_object (ScriptInfo ).app_import_path = value
224
-
225
-
226
- debug_option = click .Option (['--debug/--no-debug' ],
227
- help = 'Enable or disable debug mode.' ,
228
- default = None , callback = set_debug_value )
229
-
230
-
231
- app_option = click .Option (['-a' , '--app' ],
232
- help = 'The application to run' ,
233
- callback = set_app_value , is_eager = True )
234
-
235
-
236
225
class AppGroup (click .Group ):
237
226
"""This works similar to a regular click :class:`~click.Group` but it
238
227
changes the behavior of the :meth:`command` decorator so that it
@@ -273,25 +262,12 @@ class FlaskGroup(AppGroup):
273
262
274
263
:param add_default_commands: if this is True then the default run and
275
264
shell commands wil be added.
276
- :param add_app_option: adds the default :option:`--app` option. This gets
277
- automatically disabled if a `create_app`
278
- callback is defined.
279
- :param add_debug_option: adds the default :option:`--debug` option.
280
265
:param create_app: an optional callback that is passed the script info
281
266
and returns the loaded app.
282
267
"""
283
268
284
- def __init__ (self , add_default_commands = True , add_app_option = None ,
285
- add_debug_option = True , create_app = None , ** extra ):
286
- params = list (extra .pop ('params' , None ) or ())
287
- if add_app_option is None :
288
- add_app_option = create_app is None
289
- if add_app_option :
290
- params .append (app_option )
291
- if add_debug_option :
292
- params .append (debug_option )
293
-
294
- AppGroup .__init__ (self , params = params , ** extra )
269
+ def __init__ (self , add_default_commands = True , create_app = None , ** extra ):
270
+ AppGroup .__init__ (self , ** extra )
295
271
self .create_app = create_app
296
272
297
273
if add_default_commands :
@@ -342,33 +318,6 @@ def main(self, *args, **kwargs):
342
318
return AppGroup .main (self , * args , ** kwargs )
343
319
344
320
345
- def script_info_option (* args , ** kwargs ):
346
- """This decorator works exactly like :func:`click.option` but is eager
347
- by default and stores the value in the :attr:`ScriptInfo.data`. This
348
- is useful to further customize an application factory in very complex
349
- situations.
350
-
351
- :param script_info_key: this is a mandatory keyword argument which
352
- defines under which data key the value should
353
- be stored.
354
- """
355
- try :
356
- key = kwargs .pop ('script_info_key' )
357
- except LookupError :
358
- raise TypeError ('script_info_key not provided.' )
359
-
360
- real_callback = kwargs .get ('callback' )
361
- def callback (ctx , param , value ):
362
- if real_callback is not None :
363
- value = real_callback (ctx , value )
364
- ctx .ensure_object (ScriptInfo ).data [key ] = value
365
- return value
366
-
367
- kwargs ['callback' ] = callback
368
- kwargs .setdefault ('is_eager' , True )
369
- return click .option (* args , ** kwargs )
370
-
371
-
372
321
@click .command ('run' , short_help = 'Runs a development server.' )
373
322
@click .option ('--host' , '-h' , default = '127.0.0.1' ,
374
323
help = 'The interface to bind to.' )
@@ -400,10 +349,12 @@ def run_command(info, host, port, reload, debugger, eager_loading,
400
349
Flask is enabled and disabled otherwise.
401
350
"""
402
351
from werkzeug .serving import run_simple
352
+
353
+ debug = get_debug_flag ()
403
354
if reload is None :
404
- reload = info . debug
355
+ reload = bool ( debug )
405
356
if debugger is None :
406
- debugger = info . debug
357
+ debugger = bool ( debug )
407
358
if eager_loading is None :
408
359
eager_loading = not reload
409
360
@@ -418,12 +369,9 @@ def run_command(info, host, port, reload, debugger, eager_loading,
418
369
# we won't print anything.
419
370
if info .app_import_path is not None :
420
371
print (' * Serving Flask app "%s"' % info .app_import_path )
421
- if info .debug is not None :
422
- print (' * Forcing debug %s' % (info .debug and 'on' or 'off' ))
423
372
424
373
run_simple (host , port , app , use_reloader = reload ,
425
- use_debugger = debugger , threaded = with_threads ,
426
- passthrough_errors = True )
374
+ use_debugger = debugger , threaded = with_threads )
427
375
428
376
429
377
@click .command ('shell' , short_help = 'Runs a shell in the app context.' )
@@ -464,15 +412,21 @@ def shell_command():
464
412
This shell command acts as general utility script for Flask applications.
465
413
466
414
It loads the application configured (either through the FLASK_APP environment
467
- variable or the --app parameter ) and then provides commands either provided
468
- by the application or Flask itself.
415
+ variable) and then provides commands either provided by the application or
416
+ Flask itself.
469
417
470
418
The most useful commands are the "run" and "shell" command.
471
419
472
420
Example usage:
473
421
474
- flask --app=hello --debug run
475
- """ )
422
+ \b
423
+ %(prefix)s%(cmd)s FLASK_APP=hello
424
+ %(prefix)s%(cmd)s FLASK_DEBUG=1
425
+ %(prefix)sflask run
426
+ """ % {
427
+ 'cmd' : os .name == 'posix' and 'export' or 'set' ,
428
+ 'prefix' : os .name == 'posix' and '$ ' or '' ,
429
+ })
476
430
477
431
478
432
def main (as_module = False ):
0 commit comments