Skip to content
This repository has been archived by the owner on Sep 8, 2024. It is now read-only.

Commit

Permalink
Update backend runtime, backend-frontend connection, and console output
Browse files Browse the repository at this point in the history
- Change 'API_URL' to a specific localhost port for simplicity and rename it for clarity
- Add 'update me' not to backend 'settings.py' for clarity
- Update docstring for 'ExampleDB' in backend for clarity
- Refactor backend 'build.py' -> 'start.py' and move into project for 'app' directory for Poetry script configuration
- Add details in console, after project build, to inform next steps
- Update backend run command to 'app-start'
- Update README
  • Loading branch information
Achronus committed Jun 24, 2024
1 parent 86af436 commit a1923c6
Show file tree
Hide file tree
Showing 20 changed files with 130 additions and 48 deletions.
86 changes: 74 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,25 @@
# Create API App Quickstart Tool
# Create API App Quickstart Tool <!-- omit in toc -->

Welcome to the quickstart tool for creating a `FastAPI` project with a `NextJS` frontend.
![PyPI - Python Version](https://img.shields.io/pypi/pyversions/create-api-app?style=flat&color=green)

This tool is intended to be dynamic and installs the most recent packages where possible, while maintaining compatibility across the main OS's (Mac, Linux and Windows). You can use the tool by installing the `PIP` package. See the [Using The Tool section](#using-the-tool) for more details.
Welcome to the quickstart tool for creating a `FastAPI` project with a `NextJS` frontend.

If there are any issues using the tool, please flag them in the [issues](https://github.com/Achronus/create-api-app/issues) section of this repository.
This tool creates a predefined template while installing the most recent packages where possible.

Found on:

- [PyPi](https://pypi.org/project/create-api-app/)
- [GitHub](https://github.com/Achronus/create-api-app/)

## Contents <!-- omit in toc -->

- [Why This Tool?](#why-this-tool)
- [The Stack](#the-stack)
- [Installation](#installation)
- [Running The Backend](#running-the-backend)
- [Running the Frontend](#running-the-frontend)
- [Customization](#customization)

## Why This Tool?

Creating a project from scratch can be a tedious process. Not only do you have to create all the files yourself, it typically requires a lot of small minor changes that can easily be automated. So, rather than wasting a lot of time setting up projects, I created a tool that does it all for me!
Expand All @@ -24,6 +33,7 @@ All projects are created using the same stack, consisting of the following:
1. Backend

- [FastAPI](https://github.com/tiangolo/fastapi)
- [Pydantic](https://docs.pydantic.dev/)
- [MongoDB](https://www.mongodb.com/)
- [Beanie](https://beanie-odm.dev/)
- [Poetry](https://python-poetry.org/)
Expand All @@ -42,26 +52,78 @@ All projects are created using the same stack, consisting of the following:

_Note: all libraries and packages are automatically installed to their latest versions when running the tool._

### Useful Styling Options

- [Clerk Themes](https://clerk.com/docs/components/customization/themes)
- [Shadcn UI Theme Generator](https://gradient.page/tools/shadcn-ui-theme-generator)
- [Modern Background Snippets](https://bg.ibelick.com/)
We've also added some extra files too! You can find out more about them in our [documentation](https://create.achronus.dev/file-structure/).

## Using The Tool
## Installation

1. Firstly, install [Docker](https://docs.docker.com/get-docker/), we use this to create the frontend files dynamically using the [Build NextJS App Tool](https://github.com/Achronus/build-nextjs-app).

2. Install the package through `PIP` using the following command (requires `Python 3.12` minimum):
2. Install the package through `PIP`:

```python
pip install create_api_app
```

3. Create a project with the following command:
3. Create a project:

```python
create-api-app <project_name>
```

And that's it! You'll find two folders in your project, one called `frontend` (for NextJS) and another called `backend` (for FastAPI).

## Running The Backend

1. Open a terminal and navigate to the `backend` directory:

```cmd
cd backend
```

2. Install a virtual environment for `Poetry`:

```cmd
python -m venv env
```

3. Access it using one of the following (first -> `Windows`; second -> `Mac/Linux`):

```cmd
.\env\Scripts\activate
```

```cmd
source ./env/bin/activate
```

_Not working? Refer to the [virtual env docs](https://docs.python.org/3/library/venv.html#how-venvs-work)._

4. Run the `uvicorn` server using the `Poetry` script:

```cmd
app-start
```

## Running the Frontend

1. Open a terminal and navigate to the `frontend` directory:

```cmd
cd frontend
```

2. Install the packages using [Node.js](https://nodejs.org/en):

```cmd
npm install
```

3. Run the development server:

```cmd
npm run dev
```

## Customization

Customization options are found in our [documentation](https://create.achronus.dev/customization/).
4 changes: 2 additions & 2 deletions _project_demo/.env.local.example
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# An optional API URL only used when populating your database with data from an existing API. Refer to 'backend/db_insert.py'
API_URL=
# The URL to connect FastAPI and NextJS together - used in `frontend/next.config.mjs`
FASTAPI_CONNECTION_URL=http://127.0.0.1:8000/

# MongoDB: The connection url to your database
# https://www.mongodb.com/
Expand Down
Empty file removed _project_demo/backend/__init__.py
Empty file.
6 changes: 3 additions & 3 deletions _project_demo/backend/app/config/settings.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import os

from utils.fileloader import FileLoader
from app.utils.fileloader import FileLoader


class Settings:
Expand All @@ -10,8 +10,8 @@ class Settings:
FILEPATHS = __fileloader.FILEPATHS

DB_URL = os.getenv("DATABASE_URL")
DB_NAME = ""
DB_COLLECTION_NAME = ""
DB_NAME = "" # Update me!
DB_COLLECTION_NAME = "" # Update me!


settings = Settings()
6 changes: 5 additions & 1 deletion _project_demo/backend/app/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@


class ExampleDB(Document):
"""The main model for database collection based on the database."""
"""
The main model for your database collection. Should represent the structure of the data in the collection.
For more details check the [Beanie docs](https://beanie-odm.dev/).
"""

name: str
desc: Optional[str] = None
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import uvicorn


def start(env_mode: str = "dev", host: str = "127.0.0.1", port: int = 8000) -> None:
def run(env_mode: str = "dev", host: str = "127.0.0.1", port: int = 8000) -> None:
"""Start the server."""
dev_mode = True if env_mode == "dev" else False

Expand All @@ -25,4 +25,4 @@ def start(env_mode: str = "dev", host: str = "127.0.0.1", port: int = 8000) -> N
parser.add_argument("-pt", "--port", type=int, default=8000, required=False)

args = parser.parse_args()
start(args.env, args.host, args.port)
run(args.env, args.host, args.port)
12 changes: 6 additions & 6 deletions _project_demo/backend/poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions _project_demo/backend/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ authors = ["Ryan Partridge <rpartridge101@gmail.com>"]
readme = "README.md"

[tool.poetry.scripts]
run = "build:start"
app-start = "app.start:run"

[tool.poetry.dependencies]
python = "^3.12"
Expand All @@ -19,7 +19,7 @@ beanie = "^1.26.0"
[tool.poetry.group.dev.dependencies]
pytest = "^8.2.2"
pytest-cov = "^5.0.0"
hypothesis = "^6.103.2"
hypothesis = "^6.103.5"
aiohttp = "^3.9.5"
requests = "^2.32.3"

Expand Down
2 changes: 1 addition & 1 deletion _project_demo/frontend/next.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const loadEnv = (filePath) => {

loadEnv(path.resolve(process.cwd(), ".env.local"));

const apiUrl = process.env.API_URL;
const apiUrl = process.env.FASTAPI_CONNECTION_URL;

const nextConfig = {
images: {
Expand Down
8 changes: 3 additions & 5 deletions create_api_app/conf/constants/content.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
from .filepaths import AssetFilenames


class PoetryContent:
"""A helper class for retrieving content for the Poetry installation."""

def __init__(self) -> None:
self.START_SERVER_CMD = f"{AssetFilenames.BUILD.split('.')[0]}:start"
self.start_server_cmd = "app-start"
self.start_server_location = "app.start:run"

def pyproject_desc(self) -> str:
return 'description = "A FastAPI backend for processing API data and passing it to the frontend."'
Expand All @@ -14,7 +12,7 @@ def pyproject_author(self) -> str:
return "rpartridge101@gmail.com"

def pyproject_scripts(self) -> str:
return f'\n\n[tool.poetry.scripts]\nrun = "{self.START_SERVER_CMD}"\n\n'
return f'\n\n[tool.poetry.scripts]\n{self.start_server_cmd} = "{self.start_server_location}"\n\n'


class FrontendContent:
Expand Down
4 changes: 4 additions & 0 deletions create_api_app/conf/constants/filepaths.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,7 @@ def __init__(self, project_name: str = None) -> None:
self.POETRY_CONF = os.path.join(self.BACKEND, AssetFilenames.POETRY_CONF)

self.TAILWIND_CONF = os.path.join(self.FRONTEND, AssetFilenames.TAILWIND)

self.ENV_LOCAL = os.path.join(self.ROOT, ".env.local")
self.SETTINGS = os.path.join(self.BACKEND_APP, "config", "settings.py")
self.MODELS = os.path.join(self.BACKEND_APP, "models", "__init__.py")
15 changes: 13 additions & 2 deletions create_api_app/main.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import os
import shutil
import textwrap
import time

from create_api_app.setup.clean import CleanupController
Expand All @@ -9,7 +10,7 @@
)
from create_api_app.setup.backend import VEnvController, BackendStaticAssetController

from .conf.constants.filepaths import set_project_name
from .conf.constants.filepaths import ProjectPaths, set_project_name
from .setup import run_frontend_tasks, run_tasks
from .utils.helper import strip_whitespace_and_dashes
from .utils.printables import project_table, project_complete_panel
Expand Down Expand Up @@ -134,7 +135,17 @@ def main(
# End of script
console.print(project_complete_panel())
console.print(
f"Access the project files here [link={os.getcwd()}]{name_print}[/link]\n"
f"Access the project files here [link={os.getcwd()}]{name_print}[/link]"
)

project_paths = ProjectPaths(name)
console.print(
textwrap.dedent(f"""
[dark_goldenrod]Not sure where to start?[/dark_goldenrod]
- [green][link={project_paths.ENV_LOCAL}].env.local[/link][/green] - Update your API keys
- [yellow][link={project_paths.SETTINGS}]config/settings.py[/link][/yellow] - Update the [yellow]DB_NAME[/yellow] and [yellow]DB_COLLECTION_NAME[/yellow] for your [green]MongoDB[/green] database
- [yellow][link={project_paths.MODELS}]models/__init__.py[/link][/yellow] - Update the [green]ExampleDB[/green] model\n
""")
)


Expand Down
Empty file.
6 changes: 3 additions & 3 deletions create_api_app/setup_assets/backend/app/config/settings.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import os

from utils.fileloader import FileLoader
from app.utils.fileloader import FileLoader


class Settings:
Expand All @@ -10,8 +10,8 @@ class Settings:
FILEPATHS = __fileloader.FILEPATHS

DB_URL = os.getenv("DATABASE_URL")
DB_NAME = ""
DB_COLLECTION_NAME = ""
DB_NAME = "" # Update me!
DB_COLLECTION_NAME = "" # Update me!


settings = Settings()
6 changes: 5 additions & 1 deletion create_api_app/setup_assets/backend/app/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@


class ExampleDB(Document):
"""The main model for database collection based on the database."""
"""
The main model for your database collection. Should represent the structure of the data in the collection.
For more details check the [Beanie docs](https://beanie-odm.dev/).
"""

name: str
desc: Optional[str] = None
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import uvicorn


def start(env_mode: str = "dev", host: str = "127.0.0.1", port: int = 8000) -> None:
def run(env_mode: str = "dev", host: str = "127.0.0.1", port: int = 8000) -> None:
"""Start the server."""
dev_mode = True if env_mode == "dev" else False

Expand All @@ -25,4 +25,4 @@ def start(env_mode: str = "dev", host: str = "127.0.0.1", port: int = 8000) -> N
parser.add_argument("-pt", "--port", type=int, default=8000, required=False)

args = parser.parse_args()
start(args.env, args.host, args.port)
run(args.env, args.host, args.port)
2 changes: 1 addition & 1 deletion create_api_app/setup_assets/frontend/next.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const loadEnv = (filePath) => {

loadEnv(path.resolve(process.cwd(), ".env.local"));

const apiUrl = process.env.API_URL;
const apiUrl = process.env.FASTAPI_CONNECTION_URL;

const nextConfig = {
images: {
Expand Down
4 changes: 2 additions & 2 deletions create_api_app/setup_assets/root/.env.local
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# An optional API URL only used when populating your database with data from an existing API. Refer to 'backend/db_insert.py'
API_URL=
# The URL to connect FastAPI and NextJS together - used in `frontend/next.config.mjs`
FASTAPI_CONNECTION_URL=http://127.0.0.1:8000/

# MongoDB: The connection url to your database
# https://www.mongodb.com/
Expand Down
3 changes: 1 addition & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "create-api-app"
version = "2.0.1"
version = "2.0.2"
description = "A quickstart tool for creating a FastAPI project with a NextJS frontend."
authors = ["Ryan Partridge <rpartridge101@gmail.com>"]
readme = "README.md"
Expand All @@ -15,7 +15,6 @@ pytest = "^8.2.2"
build_nextjs_app = "^1.0.2"
docker = "^7.1.0"


[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
2 changes: 1 addition & 1 deletion tests/mappings/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
'readme = "README.md"\n',
"\n",
"[tool.poetry.scripts]\n",
'run = "build:start"\n',
'app-start = "app.start:run"\n',
"\n",
]

Expand Down

0 comments on commit a1923c6

Please sign in to comment.