Where is the code for "bench start"?

I have a bizarre installation defect.

Everything seems to work correctly after installation – until I reboot the server!

After that “bench start” looks like this:

erpdev@mybox:~/frappe-bench$ bench start

Where in the code base would I find the code for “start”??


Good day Martin that’s found here have fun

In a working environment that’s found here:

(env) frappe@ubuntu1804lts:~/frappe-bench$ ls -al ../.bench/bench/commands/
total 60
drwxr-xr-x 3 frappe frappe  4096 May 28 18:10 .
drwxr-xr-x 7 frappe frappe  4096 May 28 18:10 ..
-rw-rw-r-- 1 frappe frappe  2788 May 28 18:10 config.py
-rw-rw-r-- 1 frappe frappe  1010 May 28 18:10 git.py
-rwxrwxr-x 1 frappe frappe  2983 May 28 18:10 __init__.py
-rw-rw-r-- 1 frappe frappe  3304 May 28 18:10 install.py
-rwxrwxr-x 1 frappe frappe  4374 May 28 18:10 make.py
drwxr-xr-x 2 frappe frappe  4096 May 28 18:10 __pycache__
-rwxrwxr-x 1 frappe frappe 11872 May 28 18:10 setup.py
-rwxrwxr-x 1 frappe frappe  2843 May 28 18:10 update.py
-rw-rw-r-- 1 frappe frappe  6437 May 28 18:10 utils.py
1 Like


I poked around a bit but those first steps seem to disappear into Python infrastructure in a way I couldn’t follow.

1 Like

Huh! Wut?

This is weird.

erpdev@mybox:~/frappe-bench$ ls -al ../.bench/bench/commands/
ls: cannot access '../.bench/bench/commands/': No such file or directory


erpdev@mybox:~/frappe-bench$ tree -pL 2 ../.local/
├── [drwxrwxr-x]  bin
│   ├── [-rwxrwxr-x]  bench
│   ├── [-rwxrwxr-x]  chardetect
│   ├── [-rwxrwxr-x]  easy_install
│   ├── [-rwxrwxr-x]  easy_install-3.6
│   ├── [-rwxrwxr-x]  honcho
│   └── [-rwxrwxr-x]  virtualenv
├── [drwx------]  lib
│   └── [drwx------]  python3.6
└── [drwx------]  share
    └── [drwx------]  nano

5 directories, 6 files

I still don’t know where to find the code :face_with_raised_eyebrow:

Ah yes I think depending on install method, dev and production and so on, these clone to different directories, this should help:

frappe@ubuntu1804lts:~/frappe-bench$ find .. -name ‘*.py’ | xargs grep @click.command

edit: add escape to each ‘.’ otherwise this display as ‘…’ !!

1 Like

Wow. That got itself in tangle! :clown_face:

Cut and pasted to the command line it became:

erpdev@mybox:~/frappe-bench$ find … -name ‘*.py’ | xargs grep @click.command
find: ‘…’: No such file or directory

but then:

erpdev@mybox:~/frappe-bench$ find . -name ‘*.py’ | xargs grep @click.command

so finally:

erpdev@mybox:~/frappe-bench$ find . -name '*.py' | xargs grep @click.command
                :                :                :                :                :                :                :                :                :                :
./env/lib/python3.6/site-packages/click/decorators.py:        @click.command()
./env/lib/python3.6/site-packages/click/decorators.py:        @click.command()



But then …

erpdev@mybox:~/frappe-bench$ find . -name '*.py' | xargs grep @click.command | grep start

… finds no “start” command.

Alternatively …

erpdev@mybox:~/frappe-bench$ cat  ./apps/frappe/frappe/commands/utils.py | grep start
				if args.startswith("/api/method"):
@click.option('--restart', is_flag=True, default=False, help='Restart after migration')
def auto_deploy(context, app, migrate=False, restart=False, remote='upstream'):
			if updated or restart:
				subprocess.check_output(['bench', 'restart'], cwd = '..')

… finds no “start” command either.

Coming at this from a different angle. Here’s the full contents of my “bench” command and it’s local directory:

Directory content:

erpdev@mybox:~/frappe-bench$ cd ../.local/bin/
erpdev@mybox:~/.local/bin$ ll
total 32
drwxrwxr-x 2 erpdev erpdev 4096 May 20 15:19 ./
drwxrwxr-x 5 erpdev erpdev 4096 May 20 15:19 ../
-rwxrwxr-x 1 erpdev erpdev  210 May 20 15:19 bench*
-rwxrwxr-x 1 erpdev erpdev  225 May 20 15:19 chardetect*
-rwxrwxr-x 1 erpdev erpdev  234 May 20 15:19 easy_install*
-rwxrwxr-x 1 erpdev erpdev  234 May 20 15:19 easy_install-3.6*
-rwxrwxr-x 1 erpdev erpdev  217 May 20 15:19 honcho*
-rwxrwxr-x 1 erpdev erpdev  213 May 20 15:19 virtualenv*

Bench file content:

erpdev@mybox:~/.local/bin$ cat ../.local/bin/bench

# -*- coding: utf-8 -*-
import re
import sys

from bench.cli import cli

if __name__ == '__main__':
    sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])

It is VERY similar to virtualenv

erpdev@mybox:~/.local/bin$ cat virtualenv 

#-*- coding: utf-8 -*-
import re
import sys

from virtualenv import main

if __name__ == '__main__':
    sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])

I need to remember how to work inside a “virtualenv”.

That’s curious why the extra ‘.’ in the render display and so too on copy paste?

I checked the original save and it remains ‘..’

The idea is to query the parent directory…my learning is to preserve the two ‘.’ in that case one must ‘\’ escape the pair of ‘.’ whooda thought!?

1 Like

I think you quoted text, rather than wrapping it as code.


I did not realize that the accidental ellipsis came from trying to specify the parent directory.

That gives me a much richer vein to mine :partying_face:

erpdev@mybox:~/.local/bin$ find .. -name '*.py' | xargs grep @click.command | grep start
../lib/python3.6/site-packages/bench/commands/utils.py:@click.command('start', help="Start Frappe development processes")
../lib/python3.6/site-packages/bench/commands/utils.py:@click.command('restart', help="Restart supervisor processes or systemd units")
../lib/python3.6/site-packages/bench/commands/config.py:@click.command('restart_supervisor_on_update', help='Enable/Disable auto restart of supervisor processes')
../lib/python3.6/site-packages/bench/commands/config.py:@click.command('restart_systemd_on_update', help='Enable/Disable auto restart of systemd units')
../lib/python3.6/site-packages/bench/commands/setup.py:@click.command("procfile", help="Generate Procfile for bench start")
../lib/python3.6/site-packages/bench/commands/update.py:@click.command('update', help="Updates bench tool and if executed in a bench directory, without any flags will backup, pull, setup requirements, build, run patches and restart bench. Using specific flags will only do certain tasks instead of all")

1 Like

So I found the “real” (ha!) entry point at line 437 in:

erpdev@mybox:~ ll ~/.local/lib/python3.6/site-packages/bench/utils.py 
-rw-rw-r-- 1 erpdev erpdev 32497 May 20 15:19 /home/erpdev/.local/lib/python3.6/site-packages/bench/utils.py

So the code is:

def start(no_dev=False, concurrency=None, procfile=None):
        program = get_process_manager()
        if not program:
                raise Exception("No process manager found")
        os.environ['PYTHONUNBUFFERED'] = "true"
        if not no_dev:
                os.environ['DEV_SERVER'] = "true"

        command = [program, 'start']
        if concurrency:
                command.extend(['-c', concurrency])

        if procfile:
                command.extend(['-f', procfile])

        os.execv(program, command)

But, it seems to be saying…

… grab a carrot …

        program = get_process_manager()

… and scoot off down another rabbit hole …

        os.execv(program, command)


“program” seems to be Honcho.

now I have to learn what Honcho is!

Thanks to @JayRam this should help Breaking down Environment and branch (develop, master) - #5 by clarkej

Thanks for your dig notes I have never grokked load_entry_point…

We ain’t done yet, mister!

So Honcho is a Python port of Foreman…

… now I have to learn what Foreman is!

Aha. Ok! Now we’re getting somewhere!!!

Foreman is a tool for managing Procfile-based applications.

now I have to learn what a “Procfile-based application” is!

OH! Okay!

erpdev@mybox:~/frappe-bench$ ll
total 36
drwxrwxr-x  7 erpdev erpdev 4096 May 28 20:26 ./
drwxr-xr-x 10 erpdev erpdev 4096 May 28 20:22 ../
-rw-rw-r--  1 erpdev erpdev  494 May 28 20:26 Procfile     <<<=======
drwxrwxr-x  5 erpdev erpdev 4096 May 28 20:21 apps/
drwxrwxr-x  3 erpdev erpdev 4096 May 28 20:28 config/
drwxrwxr-x  6 erpdev erpdev 4096 May 20 15:21 env/
drwxrwxr-x  2 erpdev erpdev 4096 May 30 01:44 logs/
-rw-rw-r--  1 erpdev erpdev  194 May 20 15:34 patches.txt
drwxrwxr-x  4 erpdev erpdev 4096 May 20 15:49 sites/
erpdev@mybox:~/frappe-bench$ cat Procfile 

redis_cache: redis-server config/redis_cache.conf
redis_socketio: redis-server config/redis_socketio.conf
redis_queue: redis-server config/redis_queue.conf

web: bench serve --port 8000                               <<<=======

socketio: /usr/bin/node apps/frappe/socketio.js

watch: bench watch

schedule: bench schedule
worker_short: bench worker --queue short --quiet
worker_long: bench worker --queue long --quiet
worker_default: bench worker --queue default --quiet

John ??

Where can I find the code for “bench serve” ??


My money is on :

erpdev@mybox:~/frappe-bench$ find .. -name '*.py' | xargs grep -w "def serve"
../frappe-bench/apps/frappe/frappe/commands/utils.py:def serve(context, port=None, profile=False, no_reload=False, no_threading=False, sites_path='.', site=None):
../frappe-bench/apps/frappe/frappe/app.py:def serve(port=8000, profile=False, no_reload=False, no_threading=False, site=None, sites_path='.'):
1 Like