---
url: "https://vueda.dev/v3/reference/api/py/vueda.update.md"
title: "vueda.update"
---

# vueda.update

## Overview

Interactive update workflow for vueda-server deployments.

## Classes

- [ExitWithCode](/v3/reference/api/py/vueda.update/ExitWithCode.md)

## `ask` {#ask}

Ask the user a question, with a list of choices and a default.

### Signature {#ask-signature}

`ask(stdout, stderr, question, choices, default, non_interactive)`

#### Parameters {#ask-parameters}

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| <span id="ask-param-stdout">stdout</span> | `typing.TextIO` | yes |  |  |
| <span id="ask-param-stderr">stderr</span> | `typing.TextIO` | yes |  |  |
| <span id="ask-param-question">question</span> | `str` | yes |  |  |
| <span id="ask-param-choices">choices</span> | `list[str]` | yes |  |  |
| <span id="ask-param-default">default</span> | `str` | yes |  |  |
| <span id="ask-param-non_interactive">non_interactive</span> | `bool` | no | `False` |  |

### Source {#ask-source}

`server/vueda/update.py:148`

## `ask_tag` {#ask_tag}

Ask the user which git tag they would like to check out.
We should not show all tags because there are too many.
We can show the last 5 tags and default to the latest tag.
We should allow the user to enter a tag that is not in the list.
We should allow HEAD as a tag, for development.

### Signature {#ask_tag-signature}

`ask_tag(stdout, stderr, debug_mode)`

#### Parameters {#ask_tag-parameters}

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| <span id="ask_tag-param-stdout">stdout</span> | `typing.TextIO` | yes |  |  |
| <span id="ask_tag-param-stderr">stderr</span> | `typing.TextIO` | yes |  |  |
| <span id="ask_tag-param-debug_mode">debug_mode</span> | `bool` | no | `False` |  |

### Source {#ask_tag-source}

`server/vueda/update.py:179`

## `backup` {#backup}

Clean up backups older than a week. Create a new database backup.

### Signature {#backup-signature}

`backup(stdout, stderr, non_interactive)`

#### Parameters {#backup-parameters}

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| <span id="backup-param-stdout">stdout</span> | `typing.TextIO` | yes |  |  |
| <span id="backup-param-stderr">stderr</span> | `typing.TextIO` | yes |  |  |
| <span id="backup-param-non_interactive">non_interactive</span> | `bool` | no | `False` |  |

### Source {#backup-source}

`server/vueda/update.py:227`

## `configure_django_settings` {#configure_django_settings}

Configure Django settings from the correct directory so relative config lookups work.

### Signature {#configure_django_settings-signature}

`configure_django_settings(manage_py_dir)`

#### Parameters {#configure_django_settings-parameters}

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| <span id="configure_django_settings-param-manage_py_dir">manage_py_dir</span> |  | yes |  |  |

### Source {#configure_django_settings-source}

`server/vueda/update.py:338`

## `detect_package_manager` {#detect_package_manager}

Auto-detect package manager based on lock files and availability.
Works from anywhere within a git repository.
Returns tuple of (package_manager, repo_root, manage_py_dir).

Results are cached to avoid repeated filesystem operations.

### Signature {#detect_package_manager-signature}

`detect_package_manager()`

### Source {#detect_package_manager-source}

`server/vueda/update.py:356`

## `echo_and_eval` {#echo_and_eval}

Print a command to stdout and then execute it.

### Signature {#echo_and_eval-signature}

`echo_and_eval(stdout, stderr, command, extra_env, shell)`

#### Parameters {#echo_and_eval-parameters}

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| <span id="echo_and_eval-param-stdout">stdout</span> | `typing.TextIO` | yes |  |  |
| <span id="echo_and_eval-param-stderr">stderr</span> | `typing.TextIO` | yes |  |  |
| <span id="echo_and_eval-param-command">command</span> | `str \| list[str]` | yes |  |  |
| <span id="echo_and_eval-param-extra_env">extra_env</span> | `dict \| None` | no | `None` |  |
| <span id="echo_and_eval-param-shell">shell</span> | `bool` | no | `False` |  |

### Source {#echo_and_eval-source}

`server/vueda/update.py:214`

## `echo_and_eval_with_cwd` {#echo_and_eval_with_cwd}

Print a command to stdout and then execute it from specified directory.

### Signature {#echo_and_eval_with_cwd-signature}

`echo_and_eval_with_cwd(stdout, stderr, command, cwd, extra_env, shell)`

#### Parameters {#echo_and_eval_with_cwd-parameters}

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| <span id="echo_and_eval_with_cwd-param-stdout">stdout</span> | `typing.TextIO` | yes |  |  |
| <span id="echo_and_eval_with_cwd-param-stderr">stderr</span> | `typing.TextIO` | yes |  |  |
| <span id="echo_and_eval_with_cwd-param-command">command</span> | `str \| list[str]` | yes |  |  |
| <span id="echo_and_eval_with_cwd-param-cwd">cwd</span> | `str \| None` | no | `None` |  |
| <span id="echo_and_eval_with_cwd-param-extra_env">extra_env</span> | `dict \| None` | no | `None` |  |
| <span id="echo_and_eval_with_cwd-param-shell">shell</span> | `bool` | no | `False` |  |

### Source {#echo_and_eval_with_cwd-source}

`server/vueda/update.py:402`

## `find_manage_py` {#find_manage_py}

Find manage.py starting from start_dir (or current directory).
Searches common locations: ., server/, src/, backend/, app/
Returns the directory containing manage.py, or None if not found.

### Signature {#find_manage_py-signature}

`find_manage_py(start_dir)`

#### Parameters {#find_manage_py-parameters}

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| <span id="find_manage_py-param-start_dir">start_dir</span> |  | no | `None` |  |

### Source {#find_manage_py-source}

`server/vueda/update.py:314`

## `find_repo_root` {#find_repo_root}

Find the git repository root directory.
Returns None if not in a git repo.

### Signature {#find_repo_root-signature}

`find_repo_root()`

### Source {#find_repo_root-source}

`server/vueda/update.py:302`

## `get_tag` {#get_tag}

Get the current git tag, if it exists.

### Signature {#get_tag-signature}

`get_tag()`

### Source {#get_tag-source}

`server/vueda/update.py:54`

## `install` {#install}

Install the latest requirements, supporting both uv and pipenv.

Auto-detects package manager or uses PACKAGE_MANAGER setting.
Use sync so deploys get locked files, and so devs don't change the lock unintentionally.

### Signature {#install-signature}

`install(stdout, stderr, non_interactive)`

#### Parameters {#install-parameters}

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| <span id="install-param-stdout">stdout</span> | `typing.TextIO` | yes |  |  |
| <span id="install-param-stderr">stderr</span> | `typing.TextIO` | yes |  |  |
| <span id="install-param-non_interactive">non_interactive</span> | `bool` | no | `False` |  |

### Source {#install-source}

`server/vueda/update.py:433`

## `migrate` {#migrate}

Run Django management command 'migrate' and 'remove_stale_contenttypes'.

### Signature {#migrate-signature}

`migrate(stdout, stderr, non_interactive)`

#### Parameters {#migrate-parameters}

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| <span id="migrate-param-stdout">stdout</span> | `typing.TextIO` | yes |  |  |
| <span id="migrate-param-stderr">stderr</span> | `typing.TextIO` | yes |  |  |
| <span id="migrate-param-non_interactive">non_interactive</span> | `bool` | no | `False` |  |

### Source {#migrate-source}

`server/vueda/update.py:545`

## `orange_char` {#orange_char}

Get single character input, but color it orange.

### Signature {#orange_char-signature}

`orange_char(stdout, stderr, default)`

#### Parameters {#orange_char-parameters}

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| <span id="orange_char-param-stdout">stdout</span> | `typing.TextIO` | yes |  |  |
| <span id="orange_char-param-stderr">stderr</span> | `typing.TextIO` | yes |  |  |
| <span id="orange_char-param-default">default</span> | `str` | yes |  |  |

### Source {#orange_char-source}

`server/vueda/update.py:71`

## `orange_input` {#orange_input}

Get user input, but color it orange.

### Signature {#orange_input-signature}

`orange_input(stdout, _stderr, default)`

#### Parameters {#orange_input-parameters}

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| <span id="orange_input-param-stdout">stdout</span> | `typing.TextIO` | yes |  |  |
| <span id="orange_input-param-_stderr">_stderr</span> | `typing.TextIO` | yes |  |  |
| <span id="orange_input-param-default">default</span> | `str` | yes |  |  |

### Source {#orange_input-source}

`server/vueda/update.py:94`

## `post` {#post}

Run post-update commands. This is historical at the moment.

### Signature {#post-signature}

`post(stdout, stderr, non_interactive)`

#### Parameters {#post-parameters}

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| <span id="post-param-stdout">stdout</span> | `typing.TextIO` | yes |  |  |
| <span id="post-param-stderr">stderr</span> | `typing.TextIO` | yes |  |  |
| <span id="post-param-non_interactive">non_interactive</span> | `bool` | no | `False` |  |

### Source {#post-source}

`server/vueda/update.py:570`

## `print_trace` {#print_trace}

Print an error ``message`` and its ``trace`` to ``stderr`` with an "Error:" prefix.

### Signature {#print_trace-signature}

`print_trace(stderr, message, trace)`

#### Parameters {#print_trace-parameters}

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| <span id="print_trace-param-stderr">stderr</span> |  | yes |  |  |
| <span id="print_trace-param-message">message</span> |  | yes |  |  |
| <span id="print_trace-param-trace">trace</span> |  | yes |  |  |

### Source {#print_trace-source}

`server/vueda/update.py:131`

## `pull` {#pull}

Pull the latest code from git. if on main, we ask the user if they want to
check out a tag. if on a branch, we pull.

### Signature {#pull-signature}

`pull(stdout, stderr, non_interactive)`

#### Parameters {#pull-parameters}

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| <span id="pull-param-stdout">stdout</span> | `typing.TextIO` | yes |  |  |
| <span id="pull-param-stderr">stderr</span> | `typing.TextIO` | yes |  |  |
| <span id="pull-param-non_interactive">non_interactive</span> | `bool` | no | `False` |  |

### Source {#pull-source}

`server/vueda/update.py:275`

## `run` {#run}

Run the update steps from ``parsed_args.first_step`` onward, or only that step with ``--only``.
On a step failure, exit with its code, or return the code when ``exit_on_error`` is false.

### Signature {#run-signature}

`run(parsed_args, exit_on_error, terminal_width)`

#### Parameters {#run-parameters}

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| <span id="run-param-parsed_args">parsed_args</span> | `argparse.Namespace` | yes |  |  |
| <span id="run-param-exit_on_error">exit_on_error</span> |  | no | `True` |  |
| <span id="run-param-terminal_width">terminal_width</span> |  | no | `None` |  |

### Source {#run-source}

`server/vueda/update.py:588`

## `static` {#static}

Run Django management command 'collectstatic', if on a live site.

### Signature {#static-signature}

`static(stdout, stderr, non_interactive)`

#### Parameters {#static-parameters}

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| <span id="static-param-stdout">stdout</span> | `typing.TextIO` | yes |  |  |
| <span id="static-param-stderr">stderr</span> | `typing.TextIO` | yes |  |  |
| <span id="static-param-non_interactive">non_interactive</span> | `bool` | no | `False` |  |

### Source {#static-source}

`server/vueda/update.py:517`

## `temp_terminal_width` {#temp_terminal_width}

Set the shared text wrapper's width to ``width`` for the duration of the ``with`` block.

### Signature {#temp_terminal_width-signature}

`temp_terminal_width(width)`

#### Parameters {#temp_terminal_width-parameters}

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| <span id="temp_terminal_width-param-width">width</span> |  | yes |  |  |

### Source {#temp_terminal_width-source}

`server/vueda/update.py:118`

## `update_for_main` {#update_for_main}

Build the ``update`` argument parser as a subcommand of ``subparsers`` when given.
Return ``run`` and the parser; the caller parses the arguments and passes them to ``run``.

### Signature {#update_for_main-signature}

`update_for_main(subparsers, exit_on_error)`

#### Parameters {#update_for_main-parameters}

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| <span id="update_for_main-param-subparsers">subparsers</span> |  | no | `None` |  |
| <span id="update_for_main-param-exit_on_error">exit_on_error</span> |  | no | `True` |  |

### Source {#update_for_main-source}

`server/vueda/update.py:625`

## `wrap_text` {#wrap_text}

Wrap ``text`` to the shared text wrapper's width and join the lines.

### Signature {#wrap_text-signature}

`wrap_text(text)`

#### Parameters {#wrap_text-parameters}

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| <span id="wrap_text-param-text">text</span> |  | yes |  |  |

### Source {#wrap_text-source}

`server/vueda/update.py:111`

## Source

`server/vueda/update.py`
