Skip to content

Conversation

@savannahostrowski
Copy link
Member

This PR adds the initial version of fastapi new, which initializes your project, installs dependencies, and downloads boilerplate code to simplify the fastapi getting started experience.

The goal is to support two core workflows:

# One-off project creation (no install):
uvx fastapi-new my-project

# If they want it integrated:
pip install "fastapi[standard,new]"
fastapi new my-project

The commands above create identical projects with main.py, README.md, and project configuration with a pyproject.toml. This also supports users passing uv init supported flags into fastapi new (e.g., --python) for additional customization.

Once this is merged, I will follow up with a PR to fastapi-cli to register this command
and update our docs to reflect this simpler path to getting started. Later, I'd like to extend this to allow users to pass --template or a similar option to customize the boilerplate downloaded.

image

@savannahostrowski savannahostrowski added feature New feature or request and removed feature New feature or request labels Oct 27, 2025
Copy link

@patrick91 patrick91 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't wait to have this!

I've left some comments, hopefully I'm not too annoying :D

Comment on lines 70 to 76
def _validate_python_version_in_args(extra_args: list[str]) -> str | None:
"""
Check if --python is specified in extra_args and validate it's >= 3.8.
Returns error message if < 3.8, None otherwise.
Let uv handle malformed versions or versions it can't find.
"""
if not extra_args:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mmh, I'd rather "force" people to use latest all the time 🤔

maybe we can remove this and reintroduce it later if people ask for it?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my experience, there will always be users/customers who cannot use the latest version for one reason or another. IMO, it's better to default to their preferred version, so long as FastAPI supports it.

init_cmd = ["uv", "init"]
else:
init_cmd = ["uv", "init", config.name]

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we also pass --app to uv?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we could also pass --bare so it only creates the pyproject file (so we don't have to worry about changes to uv's default template?)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also, I wonder if we should use uv to scaffold the project 🤔

I'm ok with using it for installing things, but maybe we can also create the pyproject.toml on our own?

Especially if we add templates in future, I'm assuming those will also customise the pyproject.toml, so we don't gain a lot of benefits 🤔

Copy link
Member Author

@savannahostrowski savannahostrowski Oct 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we also pass --app to uv?

--app is the default, so we should be good there

we could also pass --bare so it only creates the pyproject file (so we don't have to worry about changes to uv's default template?)

If we pass --bare, this will skip creating a Python pin file...which I think we want?

also, I wonder if we should use uv to scaffold the project 🤔

My inclination was to use uv init for this for now and revisit when we add template support/get more feedback on the experience. I'm not sure I see a ton of benefit in manually scaffolding at this point 🤔 ?

It's possible that we also need to seriously extend the logic in this command because we get a lot of feedback on requiring uv as a dep (on that note: I had initially built a prototype that handled manually checking for venvs/runtimes when uv was not available but there are so many edge cases that I deemed this not worth it in v1).

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we pass --bare, this will skip creating a Python pin file...which I think we want?

.python-version? (we can also add the required python version to the pyproject.toml)

I'm not sure I see a ton of benefit in manually scaffolding at this point 🤔 ?

My thought was mostly on the fact that our code will change anyway, and potentially uv could also change things, but I'm ok leaving as it is now :)

It's possible that we also need to seriously extend the logic in this command because we get a lot of feedback on requiring uv as a dep (on that note: I had initially built a prototype that handled manually checking for venvs/runtimes when uv was not available but there are so many edge cases that I deemed this not worth it in v1).

totally!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yeah, that's a good point re. pyproject.toml. I'll update.

Comment on lines 28 to 29
class TestNewCommand:
def _assert_project_created(

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think in most of the other repos we avoid creating classes for tests (and rely on files instead)

@tiangolo do you have opinions?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants