Skip to content

Commit 51a4b03

Browse files
authored
Merge pull request #14 from seapagan/add_dev_command
Run a dev server from the api-admin tool
2 parents 45dc785 + becc42d commit 51a4b03

File tree

3 files changed

+98
-19
lines changed

3 files changed

+98
-19
lines changed

README.md

Lines changed: 56 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -39,17 +39,20 @@ This template is a ready-to-use boilerplate for a FastAPI project. It has the
3939
following advantages to starting your own from scratch :
4040

4141
- Baked-in User database and management. Routes are provided to add/edit/delete
42-
or ban Users.
42+
or ban (and unban) Users.
4343
- Postgresql Integration, using SQLAlchemy ORM, no need for raw SQL queries
4444
(unless you want to!). All database usage is Asynchronous.
4545
- Register and Login routes provided, both of which return a JWT token to be
4646
used in all future requests. JWT Token expires 120 minutes after issue.
4747
- JWT-based security as a Bearer Token to control access to all your routes.
4848
- A clean layout to help structure your project.
49-
- Command line admin tool. At the moment this only allows adding a user but is
50-
open for future functionality.
51-
- Database and Secrets automatically read from Environment variables or a `.env`
52-
file if that is provided.
49+
- **A command-line admin tool**. This allows to configure the project metadata
50+
very easily, add users (and make admin), and run a development server. This
51+
can easily be modified to add your own functionality (for example bulk add
52+
data) since it is based on the excellent
53+
[asyncclick](https://github.com/python-trio/asyncclick) library.
54+
- Database and Secrets are automatically read from Environment variables or a
55+
`.env` file if that is provided.
5356
- User email is validated for correct format on creation (however no checks are
5457
performed to ensure the email or domain actually exists).
5558
- Control permitted CORS Origin through Environment variables.
@@ -59,8 +62,10 @@ The template **Requires Python 3.7+**
5962
This template is free to use but I would request some accreditation. If you do
6063
use it in one of your applications, please put a small note in your readme
6164
stating that you based your project on this Template, with a link back to this
62-
repository. Thank You 😊 For those who let me know they are using this Template,
63-
I'll add links back to your project in this documentation.
65+
repository. Thank You 😊
66+
67+
For those who let me know they are using this Template, I'll add links back to
68+
your project in this documentation.
6469

6570
If this template saves you time/effort/money, or you just wish to show your
6671
appreciation for my work, why not [Buy me a
@@ -152,34 +157,40 @@ The project has been set up using [Poetry](https://python-poetry.org/) to
152157
organize and install dependencies. If you have Poetry installed, simply run the
153158
following to install all that is needed.
154159

155-
```bash
160+
```console
156161
poetry install
157162
```
158163

159164
If you do not (or cannot) have Poetry installed, I have provided an
160165
auto-generated `requirements.txt` in the project root which you can use as
161166
normal:
162167

163-
```bash
168+
```console
164169
pip install -r requirements.txt
165170
```
166171

167172
I definately recommend using Poetry if you can though, it makes dealing with
168173
updates and conflicts very easy.
169174

175+
If using poetry you now need to activate the VirtualEnv:
176+
177+
```console
178+
poetry shell
179+
```
180+
170181
### Migrate the Database
171182

172183
Make sure you have [configured](#configuration) the database. Then run the
173184
following command to setup the database:
174185

175-
```bash
186+
```console
176187
alembic upgrade head
177188
```
178189

179190
Everytime you add or edit a model, create a new migration then run the upgrade
180191
as shown below:
181192

182-
```bash
193+
```console
183194
alembic revision -m "<My commit message>"
184195
alembic upgrade head
185196
```
@@ -281,7 +292,7 @@ the database.
281292
This template includes a command-line utility to create a new user and
282293
optionally make them Admin at the same time:
283294

284-
```bash
295+
```console
285296
./api-admin user create
286297
```
287298

@@ -312,15 +323,44 @@ Options:
312323

313324
The [uvicorn](https://www.uvicorn.org/) ASGI server is automatically installed
314325
when you install the project dependencies. This can be used for testing the API
315-
during development :
326+
during development. There is a built-in command to run this easily :
327+
328+
```console
329+
api-admin dev
330+
```
316331

317-
```bash
332+
This will by default run the server on <http://localhost:8000>, and reload after
333+
any change to the source code. You can add options to change this
334+
335+
```console
336+
$ api-admin dev --help
337+
338+
Usage: api-admin dev [OPTIONS]
339+
340+
Run a development server from the command line.
341+
342+
This will auto-refresh on any changes to the source in real-time.
343+
344+
Options:
345+
-h, --host TEXT Define the interface to run the server on. [default:
346+
localhost]
347+
-p, --port INTEGER Define the port to run the server on [default: 8000]
348+
-r, --reload BOOLEAN [default: True]
349+
--help Show this message and exit.
350+
```
351+
352+
If you need more control, you can run `uvicorn` directly :
353+
354+
```console
318355
uvicorn main:app --reload
319356
```
320357

321358
The above command starts the server running on <http://localhost:8000>, and it
322359
will automatically reload when it detects any changes as you develop.
323360

361+
**Note: Neither of these are suitable to host a project in production, see the
362+
next section for information.**
363+
324364
## Deploying to Production
325365

326366
There are quite a few ways to deploy a FastAPI app to production. There is a
@@ -380,9 +420,8 @@ should also add them to the [settings.py](config/settings.py) or
380420
depoloyment independent) settings should go ing the `metadata` file, while
381421
secrets (or deployment specific) should go in the `settings` and `.env` files
382422

383-
[commands/](/commands) - This directory can hold any commands you need to write
384-
385-
- for example populating a database, create a superuser or other housekeeping
423+
[commands/](/commands) - This directory can hold any commands you need to write,
424+
for example populating a database, create a superuser or other housekeeping
386425
tasks.
387426

388427
[managers/](/managers) - This directory contains individual files for each
@@ -497,4 +536,3 @@ running API for interactive Swagger (OpenAPI) Documentation.
497536
The route table above was automatically generated from an `openapi.json` file by
498537
my [openapi-readme](https://pypi.org/project/openapi-readme/) project. Check it
499538
out for your own API documentation! 😊
500-

api-admin

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"""Run administrative tasks for the Template system."""
33
import asyncclick as click
44

5-
from commands import custom, user
5+
from commands import custom, dev, user
66

77

88
@click.group()
@@ -14,6 +14,7 @@ def control():
1414
"""
1515

1616

17+
control.add_command(dev.dev)
1718
control.add_command(user.user_commands)
1819
control.add_command(custom.customize_group)
1920

commands/dev.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
"""CLI command to run a dev server."""
2+
import subprocess
3+
4+
import asyncclick as click
5+
from rich import print
6+
7+
8+
@click.command(context_settings={"show_default": True})
9+
@click.option(
10+
"-h",
11+
"--host",
12+
type=str,
13+
required=False,
14+
default="localhost",
15+
help="Define the interface to run the server on.",
16+
)
17+
@click.option(
18+
"-p",
19+
"--port",
20+
type=int,
21+
required=False,
22+
default=8000,
23+
help="Define the port to run the server on",
24+
)
25+
@click.option("-r", "--reload", type=bool, required=False, default=True)
26+
def dev(port: int, host: str, reload: bool) -> None:
27+
"""Run a development server from the command line.
28+
29+
This will auto-refresh on any changes to the source in real-time.
30+
"""
31+
print("\n[cyan] -> Running a development server.\n")
32+
print(f"[green]Host : [bold]{host}")
33+
print(f"[green]Port : [bold]{port}")
34+
print(f"[green]Reload : [bold]{reload}")
35+
print()
36+
cmd_line = (
37+
f"uvicorn main:app --port={port} --host={host} "
38+
f"{'--reload' if reload else ''}"
39+
)
40+
subprocess.call(cmd_line, shell=True)

0 commit comments

Comments
 (0)