##########################################
Manually creating an app from the template
##########################################

The preferred way to create a new Safir-based application is via the Squarebot bot on the Rubin Observatory internal project Slack.
See :doc:`set-up-from-template` for instructions.

If you do not have access to that Slack server or want full control of each step, you can instead run the following steps manually.

1. Install necessary prerequisites
==================================

For local development, you will need Python 3.13 or later installed locally.
The fastapi_safir_app_ template does not support earlier versions.

You will also need to have a recent version of uv_ installed locally.
See the `uv documentation <https://docs.astral.sh/uv/getting-started/installation/>`__ for installation instructions.

2. Start the project with the template
======================================

Next, you'll actually create the project files using the template.

.. prompt:: bash

   git clone https://github.com/lsst/templates
   uvx templatekit -r templates make fastapi_safir_app

Answer the prompts, and move into that directory in your shell.

The rest of this tutorial uses ``safirdemo`` as the repository (and package) name:

.. prompt:: bash

   cd safirdemo

3. Initialize the repository
============================

From the root of the project directory, initialize the Git repository:

.. prompt:: bash

   git init .
   git add .
   git commit

4. Initialize the dependencies
==============================

Start by creating and activating a local virtual environment for development.

.. prompt:: bash

   uv venv
   source .venv/bin/activate

You may use other ways to manage your virtual environment if you choose, but using per-checkout virtual environments managed by uv is usually the most convenient and robust.

Now run the initialization command:

.. prompt:: bash

   make update

This command does several important things for you:

1. Based on the dependencies listed in :file:`pyproject.toml`, creates a lockfile of the latest compatible versions of every dependency in :file:`uv.lock`.
2. Installs your project in a locally editable mode, along with the third-party dependencies listed in :file:`uv.lock`.
3. Installs tox_.
4. Installs pre-commit_ hooks.

After the dependencies are locked, commit the uv lockfile:

.. prompt:: bash

   git add uv.lock
   git commit

.. note::

   None of the versions of your project's dependencies will change until you explicitly update them.
   In the future, you can update the dependencies by re-running ``make update`` and re-committing the :file:`uv.lock` file.

   To install the project for development *without* updating dependencies, run:

   .. prompt:: bash

      make init

5. Format code with Ruff
========================

The Python code generated by the template is valid, but there may be minor formatting issues related to line length and your application's chosen name.
You can format the code by running tox_:

.. prompt:: bash

   tox run -e lint
   git commit -a

6. Push to GitHub
=================

Now `create your application's repository on GitHub <https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-new-repository>`__ and push to it.

7. Try the local test commands
==============================

The preferred way to run tests is with tox_:

.. prompt:: bash

   tox run

Tox runs several test steps, each in their own virtual environment.
To learn about these test steps:

.. prompt:: bash

   tox list

For example, to only run mypy to check type annotations:

.. prompt:: bash

   tox run -e typing

Or to only lint the code (and reformat it):

.. prompt:: bash

   tox run -e lint

To run all the default test steps, but in parallel:

.. prompt:: bash

   tox run-parallel -p auto

8. Try the local development server
===================================

In addition to running tests, tox is also configured with a command to spin up a development server:

.. prompt:: bash

   tox run -e run

In another shell, send an HTTP GET request to the development server:

.. prompt:: bash

   curl http://localhost:8000/ | python -m json.tool

This development server auto-reloads, so any time you change the code, the server will restart for you.

