Coder Social home page Coder Social logo

django-devserver's Introduction

About

A drop in replacement for Django's built-in runserver command. Features include:

  • An extendable interface for handling things such as real-time logging.
  • Integration with the werkzeug interactive debugger.
  • Threaded (default) and multi-process development servers.
  • Ability to specify a WSGI application as your target environment.

Note

django-devserver works on Django 1.3 and newer

Installation

To install the latest stable version:

pip install git+git://github.com/dcramer/django-devserver#egg=django-devserver

django-devserver has some optional dependancies, which we highly recommend installing.

  • pip install sqlparse -- pretty SQL formatting
  • pip install werkzeug -- interactive debugger
  • pip install guppy -- tracks memory usage (required for MemoryUseModule)
  • pip install line_profiler -- does line-by-line profiling (required for LineProfilerModule)

You will need to include devserver in your INSTALLED_APPS:

INSTALLED_APPS = (
    ...
    'devserver',            
)

If you're using django.contrib.staticfiles or any other apps with management command runserver, make sure to put devserver above any of them (or below, for Django<1.7). Otherwise devserver will log an error, but it will fail to work properly.

Usage

Once installed, using the new runserver replacement is easy. You must specify verbosity of 0 to disable real-time log output:

python manage.py runserver

Note: This will force settings.DEBUG to True.

By default, devserver would bind itself to 127.0.0.1:8000. To change this default, DEVSERVER_DEFAULT_ADDR and DEVSERVER_DEFAULT_PORT settings are available.

Additional CLI Options

--werkzeug

Tells Django to use the Werkzeug interactive debugger, instead of it's own.

--forked

Use a forking (multi-process) web server instead of threaded.

--dozer

Enable the dozer memory debugging middleware (at /_dozer)

--wsgi-app

Load the specified WSGI app as the server endpoint.

Please see python manage.py runserver --help for more information additional options.

Note: You may also use devserver's middleware outside of the management command:

MIDDLEWARE_CLASSES = (
    'devserver.middleware.DevServerMiddleware',
)

Configuration

The following options may be configured via your settings.py:

DEVSERVER_ARGS = []

Additional command line arguments to pass to the runserver command (as defaults).

DEVSERVER_DEFAULT_ADDR = '127.0.0.1'

The default address to bind to.

DEVSERVER_DEFAULT_PORT = '8000'

The default port to bind to.

DEVSERVER_WSGI_MIDDLEWARE

A list of additional WSGI middleware to apply to the runserver command.

DEVSERVER_MODULES = []

A list of devserver modules to load.

DEVSERVER_IGNORED_PREFIXES = ['/media', '/uploads']

A list of prefixes to surpress and skip process on. By default, ADMIN_MEDIA_PREFIX, MEDIA_URL and STATIC_URL (for Django >= 1.3) will be ignored (assuming MEDIA_URL and STATIC_URL is relative)

Modules

django-devserver includes several modules by default, but is also extendable by 3rd party modules. This is done via the DEVSERVER_MODULES setting:

DEVSERVER_MODULES = (
    'devserver.modules.sql.SQLRealTimeModule',
    'devserver.modules.sql.SQLSummaryModule',
    'devserver.modules.profile.ProfileSummaryModule',

    # Modules not enabled by default
    'devserver.modules.ajax.AjaxDumpModule',
    'devserver.modules.profile.MemoryUseModule',
    'devserver.modules.cache.CacheSummaryModule',
    'devserver.modules.profile.LineProfilerModule',
)

devserver.modules.sql.SQLRealTimeModule

Outputs queries as they happen to the terminal, including time taken.

Disable SQL query truncation (used in SQLRealTimeModule) with the DEVSERVER_TRUNCATE_SQL setting:

DEVSERVER_TRUNCATE_SQL = False

Filter SQL queries with the DEVSERVER_FILTER_SQL setting:

DEVSERVER_FILTER_SQL = (
    re.compile('djkombu_\w+'),  # Filter all queries related to Celery
)

devserver.modules.sql.SQLSummaryModule

Outputs a summary of your SQL usage.

devserver.modules.profile.ProfileSummaryModule

Outputs a summary of the request performance.

devserver.modules.profile.MemoryUseModule

Outputs a notice when memory use is increased (at the end of a request cycle).

devserver.modules.profile.LineProfilerModule

Profiles view methods on a line by line basis. There are 2 ways to profile your view functions, by setting setting.DEVSERVER_AUTO_PROFILE = True or by decorating the view functions you want profiled with devserver.modules.profile.devserver_profile. The decoration takes an optional argument follow which is a sequence of functions that are called by your view function that you would also like profiled.

An example of a decorated function:

@devserver_profile(follow=[foo, bar])
def home(request):
    result['foo'] = foo()
    result['bar'] = bar()

When using the decorator, we recommend that rather than import the decoration directly from devserver that you have code somewhere in your project like:

try:
    if 'devserver' not in settings.INSTALLED_APPS:
        raise ImportError
    from devserver.modules.profile import devserver_profile
except ImportError:
    from functools import wraps
    class devserver_profile(object):
        def __init__(self, *args, **kwargs):
            pass
        def __call__(self, func):
            def nothing(*args, **kwargs):
                return func(*args, **kwargs)
            return wraps(func)(nothing)

By importing the decoration using this method, devserver_profile will be a pass through decoration if you aren't using devserver (eg in production)

devserver.modules.cache.CacheSummaryModule

Outputs a summary of your cache calls at the end of the request.

devserver.modules.ajax.AjaxDumpModule

Outputs the content of any AJAX responses

Change the maximum response length to dump with the DEVSERVER_AJAX_CONTENT_LENGTH setting:

DEVSERVER_AJAX_CONTENT_LENGTH = 300

devserver.modules.request.SessionInfoModule

Outputs information about the current session and user.

Building Modules

Building modules in devserver is quite simple. In fact, it resembles the middleware API almost identically.

Let's take a sample module, which simple tells us when a request has started, and when it has finished:

from devserver.modules import DevServerModule

class UselessModule(DevServerModule):
    logger_name = 'useless'

    def process_request(self, request):
        self.logger.info('Request started')

    def process_response(self, request, response):
        self.logger.info('Request ended')

There are additional arguments which may be sent to logger methods, such as duration:

# duration is in milliseconds
self.logger.info('message', duration=13.134)

django-devserver's People

Contributors

acdha avatar almost avatar coagulant avatar dcharbonnier avatar dcramer avatar dmclain avatar egrubbs avatar ekohl avatar fadur avatar gjcourt avatar glasslion avatar jimr avatar jzelez avatar k4ml avatar kronuz avatar libram avatar manfre avatar markvl avatar mattrobenolt avatar meteozond avatar miracle2k avatar mkai avatar nealtodd avatar rassie avatar ronnypfannschmidt avatar ryankask avatar streeter avatar svetlyak40wt avatar tkaemming avatar yesimon 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  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  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

django-devserver's Issues

KeyError: 'time' on sql.py

I'm having a KeyError: 'time' on modules/sql.py
This only happens on the first request, after running: ./manage.py rundevserver

Traceback (most recent call last):

  File "/usr/local/lib/python2.6/dist-packages/django/core/servers/basehttp.py", line 279, in run
    self.result = application(self.environ, self.start_response)

  File "/usr/local/lib/python2.6/dist-packages/django/core/servers/basehttp.py", line 651, in __call__
    return self.application(environ, start_response)

  File "/home/nmariz/Projects/Python/project/apps/devserver/handlers.py", line 200, in __call__
    DevServerMiddleware().process_complete(request)

  File "/home/nmariz/Projects/Python/project/apps/devserver/handlers.py", line 141, in process_complete
    mod.process_complete(request)

  File "/home/nmariz/Projects/Python/project/apps/devserver/modules/sql.py", line 131, in process_complete
    ), duration=sum(float(c['time']) for c in connection.queries))

  File "/home/nmariz/Projects/Python/project/apps/devserver/modules/sql.py", line 131, in 
    ), duration=sum(float(c['time']) for c in connection.queries))

KeyError: 'time'

UnicodeDecodeError in DatabaseStatTracker

File "/home/vagrant/env/lib/python2.6/site-packages/devserver/modules/sql.py", line 62, in execute

formatted_sql = sql % (params if isinstance(params, dict) else tuple(params))

UnicodeDecodeError: 'ascii' codec can't decode byte 0x8b in position 1: ordinal not in range(128)

Allow interoperability with Django Debug Toolbar

It would be cool if the panels from DDT and Devserver were the same, and they only rendered a different template on output.

This would allow for an ecosystem of these style of plugins, I think. Totally a pony, but something worth thinking about.

reload fails with "Address already in use"

sometimes, reloading fails with the following errors:

Validating models...
0 errors found

Django version 1.2.3, using settings 'testing123.settings'
Running django-devserver 0.0.4 (0477c17a47a251d58531b957fd480eff6e6d6d3d)
Forked server is running at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
 * Running on http://127.0.0.1:8000/
Unhandled exception in thread started by <function inner_run at 0x16e28c0>
Traceback (most recent call last):
  File "/home/alex/.virtualenvs/test/src/devserver/devserver/management/commands/runserver.py", line 146, in inner_run
    use_reloader=use_reloader, use_debugger=True)
  File "/home/alex/.virtualenvs/test/lib/python2.6/site-packages/werkzeug/serving.py", line 529, in run_simple
    test_socket.bind((hostname, port))
  File "<string>", line 1, in bind
socket.error: [Errno 98] Address already in use

the same happens with the threaded server.
usually, touching the file again makes the server work again.

sometimes, it prints the following

 * Detected change in '/home/alex/.virtualenvs/test/lib/python2.6/site-packages/simplecms/models.py', reloading

above or below.

this is with Werkzeug==0.6.2 and devserver 0477c17

Inifinite recursion in sql module

Running django application through devserver (django 1.6rc, devserver 0.7.0) causes infinite recursion error on line 77 devserver/modules/sql.py
return super(DatabaseStatTracker, self).execute(sql, params)

runserver fails w/o arguments

When starting runserver w/o arguments it reads settings.py for DEVSERVER_DEFAULT_ADDR.
Unfortunately it fails as it ties to do it inappropriate api. See logs.

delta:ad1 munhitsu$ ./bin/django runserver /Users/munhitsu/workspace-aptana/ad1/parts/django-devserver/devserver/modules/profile.py:50: UserWarning: MemoryUseModule requires guppy to be installed. warnings.warn('MemoryUseModule requires guppy to be installed.') Traceback (most recent call last): File "./bin/django", line 60, in <module> djangorecipe.manage.main('ad1.production') File "/Users/munhitsu/workspace-aptana/ad1/eggs/djangorecipe-0.99-py2.7.egg/djangorecipe/manage.py", line 16, in main management.execute_manager(mod) File "/Users/munhitsu/workspace-aptana/ad1/eggs/Django-1.3-py2.7.egg/django/core/management/__init__.py", line 438, in execute_manager utility.execute() File "/Users/munhitsu/workspace-aptana/ad1/eggs/Django-1.3-py2.7.egg/django/core/management/__init__.py", line 379, in execute self.fetch_command(subcommand).run_from_argv(self.argv) File "/Users/munhitsu/workspace-aptana/ad1/eggs/Django-1.3-py2.7.egg/django/core/management/base.py", line 191, in run_from_argv self.execute(*args, **options.__dict__) File "/Users/munhitsu/workspace-aptana/ad1/eggs/Django-1.3-py2.7.egg/django/core/management/base.py", line 220, in execute output = self.handle(*args, **options) File "/Users/munhitsu/workspace-aptana/ad1/parts/django-devserver/devserver/management/commands/runserver.py", line 54, in handle addr = settings.get("DEVSERVER_DEFAULT_ADDR", '') File "/Users/munhitsu/workspace-aptana/ad1/eggs/Django-1.3-py2.7.egg/django/utils/functional.py", line 277, in __getattr__ return getattr(self._wrapped, name) AttributeError: 'Settings' object has no attribute 'get'

'MemoryUseModule' object has no attribute 'heapy'

Trackeback

Environment:

Request Method: GET
Request URL: http://127.0.0.1:8000/

Django Version: 1.3
Python Version: 2.7.1
Installed Applications:
['django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.markup',
'codrspace',
'devserver']
Installed Middleware:
('django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware')

Traceback:
File "/Users/glenbot/.virtualenv/codrspace_app/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response

  1.             response = middleware_method(request, response)
    
    File "/Users/glenbot/.virtualenv/codrspace_app/lib/python2.7/site-packages/devserver/middleware.py" in process_response
  2.     self.process_complete(request)
    
    File "/Users/glenbot/.virtualenv/codrspace_app/lib/python2.7/site-packages/devserver/middleware.py" in process_complete
  3.             mod.process_complete(request)
    
    File "/Users/glenbot/.virtualenv/codrspace_app/lib/python2.7/site-packages/devserver/modules/profile.py" in process_complete
  4.         h = self.heapy.heap()
    

Exception Type: AttributeError at /
Exception Value: 'MemoryUseModule' object has no attribute 'heapy'

Show stats from all DBs in multi-db situations

I have some local changes, you know, hacks, to show DB stats for all DBs in multi-db setups.

There will need to be some work to make it compatible across newer and older Django versions, but it shouldn't be too hard.

I can work up a proper patch from my local edits on Monday, assuming the maintainers here are interested.

Support Django custom user models in devserver.modules.request.SessionInfoModule

Hey there,

Found an error which is thrown due to the assumption that request.user.username will always exist in devserver.modules.request.SessionInfoModule. In my custom user model configuration I've replaced 'username' with 'email'.


Traceback (most recent call last):
File "/Users/jesselatham/Envs/portfolio/src/django/django/contrib/staticfiles/handlers.py", line 72, in call
return self.application(environ, start_response)
File "/Users/jesselatham/Envs/portfolio/src/django/django/core/handlers/wsgi.py", line 255, in call
response = self.get_response(request)
File "/Users/jesselatham/Envs/portfolio/src/django/django/core/handlers/base.py", line 191, in get_response
response = self.handle_uncaught_exception(request, resolver, sys.exc_info())
File "/Users/jesselatham/Envs/portfolio/src/django/django/core/handlers/base.py", line 217, in handle_uncaught_exception
return debug.technical_500_response(request, *exc_info)
File "/Users/jesselatham/Envs/portfolio/src/django/django/core/handlers/base.py", line 187, in get_response
response = middleware_method(request, response)
File "/Users/jesselatham/Envs/portfolio/src/django-devserver/devserver/middleware.py", line 47, in process_response
mod.process_response(request, response)
File "/Users/jesselatham/Envs/portfolio/src/django-devserver/devserver/modules/request.py", line 23, in process_response
user = '%s (id:%s)' % (request.user.username, request.user.pk)
File "/Users/jesselatham/Envs/portfolio/src/django/django/utils/functional.py", line 202, in inner
return func(self._wrapped, *args)
AttributeError: 'User' object has no attribute 'username'


I've able to successfully patch this line on my end by changing 'username' to 'email' to keep it working.

For what it's work this is the dev server that I've been looking for!

Thanks,
Jess

Restart with reloader without validating models etc

I have no idea if this is easily possible or if its completely outside the domain of how devserver is put together, but it would be very useful if restarting of django could be done in such a way as to skip django's full restart routine.

validating models is not needed if only some small typo has been fixed.

crashes on long queries

I have a view that executes a huge query which takes 15 seconds to complete. With the rundevserver, it always crashes right after the query finishes. Here is what gets outputted:

Debugging middleware catched exception in streamed response at a point where response headers were already sent.
Traceback (most recent call last):
  File "/home/chris/.virtualenvs/flightloggin/lib/python2.6/site-packages/django/core/servers/basehttp.py", line 651, in __call__
    return self.application(environ, start_response)
  File "/home/chris/.virtualenvs/flightloggin/src/django/devserver/handlers.py", line 215, in __call__
    DevServerMiddleware().process_complete(request)
  File "/home/chris/.virtualenvs/flightloggin/src/django/devserver/handlers.py", line 156, in process_complete
    mod.process_complete(request)
  File "/home/chris/.virtualenvs/flightloggin/src/django/devserver/modules/sql.py", line 137, in process_complete
    ), duration=sum(float(c['time']) for c in connection.queries))
  File "/home/chris/.virtualenvs/flightloggin/src/django/devserver/modules/sql.py", line 137, in <genexpr>
    ), duration=sum(float(c['time']) for c in connection.queries))
KeyError: 'time'
192.168.1.145 - - [13/Feb/2010 02:42:30] "GET /stats_save.py?sk=sss HTTP/1.1" 20

Add LICENSE file to official releases

Hi,
would it be possible for you to include the LICENSE file in the official releases on pypi? I'm currently packaging django-devserver for Fedora and we need to have these things clear.

Thanks!

"Memory usage was increased by" message is misleading

I see that you are using self.heapy.domisize for this number, but from guppy, this really is

The dominated size of the set x. The dominated size of x is the total size of memory that will become deallocated, directly or indirectly, when the objects in x are deallocated.

which is a mouthful.

"Memory usage was increased by X Kb" is incorrect and it might freak people out. It certainly freaked me out as I saw the console output and thought some memory must have been reclaimed by GC, it can't just increase monotonically like that.

Perhaps "X KB of memory could have been reclaimed if all newly allocated objects are deallocated", but I think not.

So maybe you could use self.heapy.size (or self.heapy.indisize) and simply say "X KB of memory was allocated".

NameError thrown when two devservers running on the same port

This case needs a sane error message. If I'm running on ./manage.py runserver 0.0.0.0:80 on one app, and try to run the same command in another terminal, I get the following traceback.

Validating models...
0 errors found

Django version 1.3, using settings 'app.settings'
Running django-devserver 0.2.0
Threaded server is running at http://0.0.0.0:80/
Quit the server with CONTROL-C.
Unhandled exception in thread started by <function inner_run at 0x101757c80>
Traceback (most recent call last):
  File "/usr/local/Cellar/python/2.7.2/lib/python2.7/site-packages/devserver/management/commands/runserver.py", line 136, in inner_run
    error_text = ERRORS[e.args[0].args[0]]
NameError: free variable 'e' referenced before assignment in enclosing scope

Division by zero

Ok, maybe something to do with my setup, but I'm getting a division by zero.

Traceback (most recent call last):

  File "/Library/Python/2.6/site-packages/django/core/servers/basehttp.py", line 279, in run
    self.result = application(self.environ, self.start_response)

  File "/Library/Python/2.6/site-packages/django/core/servers/basehttp.py", line 651, in __call__
    return self.application(environ, start_response)

  File "/Library/Python/2.6/site-packages/django/core/handlers/wsgi.py", line 245, in __call__
    response = middleware_method(request, response)

  File "/Library/Python/2.6/site-packages/django_devserver-0.0.2-py2.6.egg/devserver/middleware.py", line 30, in process_response
    self.process_complete(request)

  File "/Library/Python/2.6/site-packages/django_devserver-0.0.2-py2.6.egg/devserver/middleware.py", line 57, in process_complete
    mod.process_complete(request)

  File "/Library/Python/2.6/site-packages/django_devserver-0.0.2-py2.6.egg/devserver/modules/cache.py", line 31, in process_complete
    ratio = int(hits / float(misses + hits) * 100)

ZeroDivisionError: float division

bulk insert error

work with a bulk insert, where I think a specific amount of records for one user but django.devser the following error:

Traceback:
File "/Users/alejo8591/Documents/etv/venv/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response

  1.                     response = callback(request, _callback_args, *_callback_kwargs)
    
    File "/Users/alejo8591/Documents/etv/venv/lib/python2.7/site-packages/django/contrib/admin/options.py" in wrapper
  2.             return self.admin_site.admin_view(view)(_args, *_kwargs)
    
    File "/Users/alejo8591/Documents/etv/venv/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapped_view
  3.                 response = view_func(request, _args, *_kwargs)
    
    File "/Users/alejo8591/Documents/etv/venv/lib/python2.7/site-packages/django/views/decorators/cache.py" in _wrapped_view_func
  4.     response = view_func(request, _args, *_kwargs)
    
    File "/Users/alejo8591/Documents/etv/venv/lib/python2.7/site-packages/django/contrib/admin/sites.py" in inner
  5.         return view(request, _args, *_kwargs)
    
    File "/Users/alejo8591/Documents/etv/venv/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapper
  6.         return bound_func(_args, *_kwargs)
    
    File "/Users/alejo8591/Documents/etv/venv/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapped_view
  7.                 response = view_func(request, _args, *_kwargs)
    
    File "/Users/alejo8591/Documents/etv/venv/lib/python2.7/site-packages/django/utils/decorators.py" in bound_func
  8.             return func(self, _args2, *_kwargs2)
    
    File "/Users/alejo8591/Documents/etv/venv/lib/python2.7/site-packages/django/db/transaction.py" in inner
  9.             return func(_args, *_kwargs)
    
    File "/Users/alejo8591/Documents/etv/venv/lib/python2.7/site-packages/django/contrib/admin/options.py" in add_view
  10.             self.save_model(request, new_object, form, False)
    
    File "/Users/alejo8591/Documents/etv/venv/lib/python2.7/site-packages/django/contrib/admin/options.py" in save_model
  11.     obj.save()
    
    File "/Users/alejo8591/Documents/etv/users/models.py" in save
  12.     bulk.insertMany(CreateCodes,values)
    
    File "/Users/alejo8591/Documents/etv/users/classes/BulkInsert.py" in insertMany
  13.     self._insertMany(_args, *_kwargs)
    
    File "/Users/alejo8591/Documents/etv/users/classes/BulkInsert.py" in _insertMany
  14.     con.cursor().executemany(sql, parameters)
    
    File "/Users/alejo8591/Documents/etv/venv/lib/python2.7/site-packages/devserver/modules/sql.py" in executemany
  15.             message = 'Executed %s times\n%s' % message
    

Exception Type: TypeError at /elevate/users/createcodes/add/
Exception Value: not enough arguments for format string

Picture Error
Captura de pantalla 2013-01-10 a la s 17 07 00

Creating correct before using the bulk insert data
Captura de pantalla 2013-01-10 a la s 17 08 04

add DEBUG to settings.py

Hi,

I think we should add this line to settings.py:

DEBUG = getattr(settings, 'DEBUG', False)

because we use it in modules/sql.py.

It gives an error in my env.

Wrong (?) pip URL

IMHO the pip install url should read:

pip install git+git://github.com/dcramer/django-devserver#egg=django_devserver

instead of

pip install git+git://github.com/dcramer/django-devserver#egg=django-devserver

note the "_" in django_devserver.

With the "-" I get weird errors from pip when used in requirement files.

ADDITION:
To trigger the bug(?) you also need to have django (with snv://....#egg=django) in the same requirements file. It seems pip splits on "-" and then assumes django-devserver and django are the same thing.

Django 1.3 (staticfiles) may interfere with devserver.

This one took me a bit to figure out.

The latest trunk builds of django (1.3+) contain staticfiles, which includes its own runserver command. If your INSTALLED_APPS contains django.contrib.staticfiles, and this appears after devserver, then the staticfiles one will override it.

I'm guessing at some stage someone else will hit this issue: wondering if it could be added in some form to the docs.

Exception on auto-redirect

When a request comes in that is a redirect because a trailing slash has been omitted, devserver presents an error:

File "[…]/devserver/modules/profile.py", line 19, in process_complete
duration = datetime.now() - self.start
AttributeError: 'ProfileSummaryModule' object has no attribute 'start'

What seems to be happening is that process_request() in the DevServerMiddleware is not being called, and process_response() is being called. (Putting a pdb breakpoint in process_request() does not drop us into the debugger when running this request).

I haven't been able to figure out why this is.

Use logging handler instead of stdout

I think using logging handler which specified in settings.py is better way.
So need new settings to specify handler_name.

ex:

DEV_SERVER_LOG_HANDLER = 'handler_name'

IPv6 support

IPv6 is awesome. It's the future. django-devserver should support it.

The django runserver added support for a this in 1.3.

KeyError: 'time' on the first request and KeyError: 'duration' on the subsequent requests

I receive the same exception as the user in issue #1 on the first request:

Traceback (most recent call last):

  File "E:\Other\Software\Django\django\core\servers\basehttp.py", line 279, in run
    self.result = application(self.environ, self.start_response)

  File "E:\Other\Software\Django\django\core\servers\basehttp.py", line 651, in __call__
    return self.application(environ, start_response)

  File "C:\Python26\lib\site-packages\devserver\handlers.py", line 200, in __call__
    DevServerMiddleware().process_complete(request)

  File "C:\Python26\lib\site-packages\devserver\handlers.py", line 141, in process_complete
    mod.process_complete(request)

  File "C:\Python26\lib\site-packages\devserver\modules\sql.py", line 131, in process_complete
    ), duration=sum(float(c['time']) for c in connection.queries))

  File "C:\Python26\lib\site-packages\devserver\modules\sql.py", line 131, in <genexpr>
    ), duration=sum(float(c['time']) for c in connection.queries))

KeyError: 'time'

and this one on all the subsequent requests if I'm using it in combination with debug-toolbar:

Traceback (most recent call last):

  File "E:\Other\Software\Django\django\core\servers\basehttp.py", line 279, in run
    self.result = application(self.environ, self.start_response)

  File "E:\Other\Software\Django\django\core\servers\basehttp.py", line 651, in __call__
    return self.application(environ, start_response)

  File "C:\Python26\lib\site-packages\devserver\handlers.py", line 182, in __call__
    response = middleware_method(request, response)

  File "C:\Python26\lib\site-packages\django_debug_toolbar-0.8.1-py2.6.egg\debug_toolbar\middleware.py", line 91, in process_response
    response.content = replace_insensitive(smart_unicode(response.content), u'</body>', smart_unicode(self.debug_toolbars[request].render_toolbar() + u'</body>'))

  File "C:\Python26\lib\site-packages\django_debug_toolbar-0.8.1-py2.6.egg\debug_toolbar\toolbar\loader.py", line 72, in render_toolbar
    'BASE_URL': self.request.META.get('SCRIPT_NAME', ''),

  File "E:\Other\Software\Django\django\template\loader.py", line 173, in render_to_string
    return t.render(context_instance)

  File "E:\Other\Software\Django\django\test\utils.py", line 29, in instrumented_test_render
    return self.nodelist.render(context)

  File "E:\Other\Software\Django\django\template\__init__.py", line 787, in render
    bits.append(self.render_node(node, context))

  File "E:\Other\Software\Django\django\template\debug.py", line 82, in render_node
    raise wrapped

TemplateSyntaxError: Caught an exception while rendering: duration

Original Traceback (most recent call last):
  File "E:\Other\Software\Django\django\template\debug.py", line 72, in render_node
    result = node.render(context)
  File "E:\Other\Software\Django\django\template\defaulttags.py", line 176, in render
    nodelist.append(node.render(context))
  File "E:\Other\Software\Django\django\template\defaulttags.py", line 428, in render
    val = self.var.resolve(context)
  File "E:\Other\Software\Django\django\template\__init__.py", line 554, in resolve
    obj = self.var.resolve(context)
  File "E:\Other\Software\Django\django\template\__init__.py", line 695, in resolve
    value = self._resolve_lookup(context)
  File "E:\Other\Software\Django\django\template\__init__.py", line 730, in _resolve_lookup
    current = current()
  File "C:\Python26\lib\site-packages\django_debug_toolbar-0.8.1-py2.6.egg\debug_toolbar\panels\sql.py", line 150, in nav_subtitle
    self._sql_time = sum([q['duration'] for q in self._queries])
KeyError: 'duration'

Provide a syslog logger

I know this sounds odd given that the logger writes to Django's console output, but a syslog logger would be useful for my debugging my current project.

AttributeError: 'WSGIRequest' object has no attribute 'session'

When I remove django.contrib.sessions.middleware.SessionMiddleware then I got next trace:

  File "/usr/share/pyshared/django/core/servers/basehttp.py", line 674, in __call__
   return self.application(environ, start_response)
  File "/usr/share/pyshared/django/core/handlers/wsgi.py", line 245, in __call__
   response = middleware_method(request, response)
  File "/tmp/python/src/django/devserver/middleware.py", line 32, in process_response
   mod.process_response(request, response)
  File "/tmp/python/src/django/devserver/modules/request.py", line 23, in process_response
   self.logger.info('Session %s authenticated by %s', request.session.session_key, user)
AttributeError: 'WSGIRequest' object has no attribute 'session'

There is a bug at the request.py:

    self.has_session = bool(getattr(request, 'session', False))
    if self.has_session is not None:

Must be:

    self.has_session = bool(getattr(request, 'session', False))
    if self.has_session == True:

(I could remove devserver.modules.request.SessionInfoModule of course)

make it possible to run with DEBUG=False

this would be useful in general, to run devserver with --debug=False

but in particular its quite important for checking memory leaks. I see memory increasing on each page load and I'm pretty certain that is the size of the queries being saved. its the same amount for the same exact queries. different queries, different but consistent amount.

or so it seems ... I'm not sure ! thus I want to run with debug=False

would also be very useful in day to day use without having to open up the settings file to switch

Line Profiler not found

Also happens with other modules (the memory one i believe).

line-profiler is installed correctly via pip, any thoughts?

stacktrace:

HackBook-Air:readrboard tbrock$ ./manage.py runserver 8080
Traceback (most recent call last):
File "./manage.py", line 11, in
execute_manager(settings)
File "/Library/Python/2.6/site-packages/django/core/management/init.py", line 438, in execute_manager
utility.execute()
File "/Library/Python/2.6/site-packages/django/core/management/init.py", line 379, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/Library/Python/2.6/site-packages/django/core/management/init.py", line 261, in fetch_command
klass = load_command_class(app_name, subcommand)
File "/Library/Python/2.6/site-packages/django/core/management/init.py", line 67, in load_command_class
module = import_module('%s.management.commands.%s' % (app_name, name))
File "/Library/Python/2.6/site-packages/django/utils/importlib.py", line 35, in import_module
import(name)
File "/Library/Python/2.6/site-packages/devserver/management/commands/runserver.py", line 12, in
from devserver.handlers import DevServerHandler
File "/Library/Python/2.6/site-packages/devserver/handlers.py", line 4, in
from devserver.middleware import DevServerMiddleware
File "/Library/Python/2.6/site-packages/devserver/middleware.py", line 1, in
from devserver.models import MODULES
File "/Library/Python/2.6/site-packages/devserver/models.py", line 37, in
load_modules()
File "/Library/Python/2.6/site-packages/devserver/models.py", line 31, in load_modules
instance = cls(GenericLogger(cls))
File "/Library/Python/2.6/site-packages/devserver/modules/profile.py", line 82, in new
warnings.warn('LineProfilerModule requires line_profiler to be installed.')
NameError: global name 'warnings' is not defined

Drop in replacement may fail in Django 1.7 with django.contrib.staticfiles

In Django 1.7, if django.contrib.staticfiles is in INSTALLED_APPS and django.contrib.staticfiles comes before devserver in INSTALLED_APPS then staticfile's sub-classed runserver management command is used instead of django-devserver's runserver management command.

This breaks the drop-in replacement nature of devserver.

Putting devserver ahead of django.contrib.staticfiles results in django-devserver's runserver being used.

Might not be anything that can be done about that other than a note in the README about the ordering in INSTALLED_APPS.

AdminMediaHandler deprecated in django 1.4

For django 1.4, AdminMediaHandler has been replaced by StaticFilesHandler with the same signature.

See this fix for gunicorn.

Works OOTB if implemented in devserver.

--- a/devserver/management/commands/runserver.py
+++ b/devserver/management/commands/runserver.py
@@ -1,7 +1,8 @@
 from django.conf import settings
 from django.core.management.base import BaseCommand, CommandError, handle_default_options
-from django.core.servers.basehttp import AdminMediaHandler, WSGIServerException, \
+from django.core.servers.basehttp import WSGIServerException, \
                                          WSGIServer
+from django.contrib.staticfiles.handlers import StaticFilesHandler
 from django.core.handlers.wsgi import WSGIHandler

 import os
@@ -163,7 +164,7 @@ class Command(BaseCommand):
                 from django.contrib.staticfiles.handlers import StaticFilesHandler
                 app = StaticFilesHandler(app)
             else:
-                app = AdminMediaHandler(app, admin_media_path)
+                app = StaticFilesHandler(app, admin_media_path)

             if options['use_dozer']:
                 from dozer import Dozer
diff --git a/devserver/testcases.py b/devserver/testcases.py
index c18ebc7..f499b96 100644
--- a/devserver/testcases.py
+++ b/devserver/testcases.py
@@ -3,8 +3,9 @@ import SocketServer
 from django.conf import settings
 from django.core.handlers.wsgi import WSGIHandler
 from django.core.management import call_command
-from django.core.servers.basehttp import StoppableWSGIServer, AdminMediaHandler, WSGIServerException
+from django.core.servers.basehttp import StoppableWSGIServer, WSGIServerException
 from django.test.testcases import TestServerThread
+from django.contrib.staticfiles.handlers import StaticFilesHandler

'devserver_profile' object has no attribute '__name__'

When using the devserver profiler, this error propagates no matter what view I'm using.

Here's the full traceback

Traceback:
File "/usr/local/Cellar/python/2.7.1/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
  101.                             request.path_info)
File "/usr/local/Cellar/python/2.7.1/lib/python2.7/site-packages/django/core/urlresolvers.py" in resolve
  252.                     sub_match = pattern.resolve(new_path)
File "/usr/local/Cellar/python/2.7.1/lib/python2.7/site-packages/django/core/urlresolvers.py" in resolve
  158.             return ResolverMatch(self.callback, args, kwargs, self.name)
File "/usr/local/Cellar/python/2.7.1/lib/python2.7/site-packages/django/core/urlresolvers.py" in _get_callback
  170.             raise ViewDoesNotExist("Tried %s in module %s. Error was: %s" % (func_name, mod_name, str(e)))

Exception Type: ViewDoesNotExist at /
Exception Value: Tried home in module app.views. Error was: 'devserver_profile' object has no attribute '__name__'

Werkzeug is disabled and can't be turned on

Hi

I installed ver 0.1.5 from easy_install and there is no way to turn on werkzeug. In one of the last revisions it was disabled by default and there is no option in runserver command to activate it. There is only --werkzeug param which "Tells Django to NOT use the Werkzeug interactive debugger.", but now it make no sense.

So, please change option to --werkzeug to activate werkzeug or make it active by default.

Workaround and possible resolution: in management/commands/runserver.py, line 34, change from:
make_option('--werkzeug', action='store_false', dest='use_werkzeug', default=False,
help='Tells Django to NOT use the Werkzeug interactive debugger.'),
to
make_option('--werkzeug', action='store_true', dest='use_werkzeug', default=False,
help='Tells Django to use the Werkzeug interactive debugger.'),
and now --werkzeug param makes dubugger active.

Realtime SQL Hangs on bulk_create

whenn running a large bulk create while having sql realtime enabled,
the python process did take 100% cpu and no query was sent out

the issue disappeared with disableing the sql display

MemoryUseModule interferes with page load

When this is turned on, some of my sites pages never finish loading: this includes some admin pages.

It seems like it may be related to loading up some javascript files, perhaps /admin/jsi18n/, as that is the last request that was sent before the freeze: the next one to load is /media/admin/media/js/core.js.

DatabaseStatTracker - ValueError: None is not in list

A exception is thrown (ValueError: None is not in list) if you have a text param that contains a sql keyword, module/sql line 76:
message = sqlparse.format(message, reindent=True, keyword_case='upper')

because the formatted_sql doesn't quote text param and sqlparse assumed that is a keyword not a regular text

i.e.:
sql = """INSERT INTO example ("name", "address") VALUES (%s, %s)"""
params = ("where", "other")
formatted_sql = sql % (params if isinstance(params, dict) else tuple(params))
message = sqlparse.format(message, reindent=True, keyword_case='upper')

Oracle cursor.excecutemany causes SQL logger to crash

I use devserver with cx_Oracle 5.1.1 and Django 1.3.1

At one place I've non Django code:

connections['default'].cursor().executemany(in_sql, values)

This leads to crash in:

File "keycom-dev-std/lib/site-packages/devserver/modules/sql.py", line 99, in executemany
   message = 'Executed %s times\n%s' % message

Integration with werkzeug debugger?

I use runserver_plus which uses the werkzeug debugger... wondering if that'd be hard to implement with devserver... maybe if the debugger is present - use it?

Strongly outdated CHANGES File

I just noticed that the CHANGES File was not updated since version 0.3.1, which was 2 years ago.

With a up to date CHANGES File it is easier possible to follow changes like the removeal of WSGIServerException and the bugfix done here: #86.

Would it be possible to get it up to date?

sql logger should quote query params

It would be nice if the sql logger would quote params in the printed queries to make it easier to copy/paste into a CLI client for closer optimization/examination.

Eg instead of:

sql SELECT ...
FROM foo
WHERE foo.name = bob
sql Found 1 matching rows

it would print:

sql SELECT ...
FROM foo
WHERE foo.name = "bob"
sql Found 1 matching rows

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.