Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement run command for uvicorn development server #35

Merged
merged 12 commits into from
Feb 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@ This file documents changes to [fastapi-mvc](https://github.com/rszamszur/fastap

## Unreleased

### Features

* Implement CLI `fastapi-mvc run` command for running uvicorn development server [#14](https://github.com/rszamszur/fastapi-mvc/issues/14), [#31](https://github.com/rszamszur/fastapi-mvc/issues/31). PR [#35](https://github.com/rszamszur/fastapi-mvc/pull/35)

### Internal

* Add documentation [#9](https://github.com/rszamszur/fastapi-mvc/issues/9).
* Add documentation [#9](https://github.com/rszamszur/fastapi-mvc/issues/9). PR [#33](https://github.com/rszamszur/fastapi-mvc/pull/33)
* Add make template-checks target for running metrics and tests on template.
* Add make pre-commit target for running package and template checks.
* Add make test target for running package unit and integration tests.
Expand Down
144 changes: 101 additions & 43 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,13 +149,30 @@ Poetry comes with all the tools you might need to manage your project in a deter

## Quick start

Creating a new FastAPI project is as easy as:
```shell
$ pip install fastapi-mvc
$ fastapi-mvc new my-project
$ cd my-project
$ my-project serve
# or
$ poetry run my-project serve
pip install fastapi-mvc
fastapi-mvc new my-project
```

To run development uvicorn server:
```shell
cd my-project
fastapi-mvc run
```

To run production WSGI + ASGI server:
```shell
cd my-project
poetry run my-project serve
# or if Poetry PATH is set
my-project serve
```

To confirm it's working:
```shell
curl localhost:8000/api/ready
{"status":"ok"}
```

## Prerequisites
Expand All @@ -170,46 +187,16 @@ $ poetry run my-project serve
pip install fastapi-mvc
```

## Usage

This package exposes simple CLI for easier interaction:

Or directly from source:
```shell
$ fastapi-mvc --help
Usage: fastapi-mvc [OPTIONS] COMMAND [ARGS]...

Generate and manage fastapi-mvc projects.

Options:
-v, --verbose Enable verbose logging.
--help Show this message and exit.

Commands:
new Create a new FastAPI application.
$ fastapi-mvc new --help
Usage: fastapi-mvc new [OPTIONS] APP_PATH

Create a new FastAPI application.

The 'fastapi-mvc new' command creates a new FastAPI application with a
default directory structure and configuration at the path you specify.

Options:
-R, --skip-redis Skip Redis utility files.
-A, --skip-aiohttp Skip aiohttp utility files.
-V, --skip-vagrantfile Skip Vagrantfile.
-H, --skip-helm Skip Helm chart files.
-G, --skip-actions Skip GitHub actions files.
-C, --skip-codecov Skip codecov in GitHub actions.
-I, --skip-install Dont run make install
--license [MIT|BSD2|BSD3|ISC|Apache2.0|LGPLv3+|LGPLv3|LGPLv2+|LGPLv2|no]
Choose license. [default: MIT]
--repo-url TEXT Repository url.
--help Show this message and exit.
git clone git@github.com:rszamszur/fastapi-mvc.git
cd fastapi-mvc
make install
```

To generate new project:
## Usage

Creating a new FastAPI project is as easy as:
```shell
$ fastapi-mvc new my-project
[install] Begin installing project.
Expand All @@ -232,8 +219,16 @@ To activate shell completion:
- for fish: $ echo 'eval "$(_MY_PROJECT_COMPLETE=source_fish my-project)' >> ~/.config/fish/completions/my-project.fish
```

To serve api:
To run development uvicorn server:
```shell
$ cd my-project/
$ fastapi-mvc run
[2022-02-07 20:31:11 +0100] [1687989] [INFO] Will watch for changes in these directories: ['/tmp/my-project']
[2022-02-07 20:31:11 +0100] [1687989] [INFO] Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
[2022-02-07 20:31:11 +0100] [1687989] [INFO] Started reloader process [1687989] using watchgod
```

To run production WSGI + ASGI server:
```shell
$ cd my-project/
$ my-project serve
Expand Down Expand Up @@ -261,6 +256,69 @@ $ curl localhost:8000/api/ready
{"status":"ok"}
```

## CLI

This package exposes simple CLI for easier interaction:

```shell
$ fastapi-mvc --help
Usage: fastapi-mvc [OPTIONS] COMMAND [ARGS]...

Create and develop production grade FastAPI projects.

Documentation: https://fastapi-mvc.netlify.app

Source Code: https://github.com/rszamszur/fastapi-mvc

Options:
-v, --verbose Enable verbose logging.
--help Show this message and exit.

Commands:
new Create a new FastAPI application.
run Run development uvicorn server.
```
```shell
$ fastapi-mvc new --help
Usage: fastapi-mvc new [OPTIONS] APP_PATH

Create a new FastAPI application.

The 'fastapi-mvc new' command creates a new FastAPI application with a
default directory structure and configuration at the path you specify.

Options:
-R, --skip-redis Skip Redis utility files.
-A, --skip-aiohttp Skip aiohttp utility files.
-V, --skip-vagrantfile Skip Vagrantfile.
-H, --skip-helm Skip Helm chart files.
-G, --skip-actions Skip GitHub actions files.
-C, --skip-codecov Skip codecov in GitHub actions.
-I, --skip-install Dont run make install
--license [MIT|BSD2|BSD3|ISC|Apache2.0|LGPLv3+|LGPLv3|LGPLv2+|LGPLv2|no]
Choose license. [default: MIT]
--repo-url TEXT Repository url.
--help Show this message and exit.
```
```shell
$ fastapi-mvc run --help
Usage: fastapi-mvc run [OPTIONS]

Run development uvicorn server.

The 'fastapi-mvc run' commands runs development uvicorn server for a
fastapi-mvc project at the current working directory.

Options:
--host TEXT Host to bind. [default: 127.0.0.1]
-p, --port INTEGER Port to bind. [default: 8000]
-w, --workers INTEGER RANGE The number of worker processes for handling
requests. [default: 1]

--no-reload Disable auto-reload.
--help Show this message and exit.
```

## Contributing

[CONTRIBUTING](https://github.com/rszamszur/fastapi-mvc/blob/master/CONTRIBUTING.md)
Expand Down
7 changes: 6 additions & 1 deletion fastapi_mvc/cli/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import click
from fastapi_mvc.cli.commands.new import new
from fastapi_mvc.cli.commands.run import run


@click.group()
Expand All @@ -14,8 +15,11 @@
default=False,
)
def cli(**options):
"""Generate and manage fastapi-mvc projects. # noqa: D205,D400
"""Create and develop production grade FastAPI projects.

Documentation: https://fastapi-mvc.netlify.app

Source Code: https://github.com/rszamszur/fastapi-mvc
\f

Args:
Expand All @@ -35,3 +39,4 @@ def cli(**options):


cli.add_command(new)
cli.add_command(run)
2 changes: 2 additions & 0 deletions fastapi_mvc/cli/commands/new.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import click
from cookiecutter.exceptions import OutputDirExistsException
from cookiecutter.main import cookiecutter
from fastapi_mvc.version import __version__


@click.command()
Expand Down Expand Up @@ -139,6 +140,7 @@ def new(app_path, **options):
"email": email,
"repo_url": options["repo_url"],
"year": datetime.today().year,
"fastapi_mvc_version": __version__,
}

try:
Expand Down
82 changes: 82 additions & 0 deletions fastapi_mvc/cli/commands/run.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
"""FastAPI MVC CLI run command implementation."""
import os
import sys
import configparser
from multiprocessing import cpu_count

import click
import uvicorn


@click.command()
@click.option(
"--host",
help="Host to bind.",
type=click.STRING,
default="127.0.0.1",
required=False,
show_default=True,
)
@click.option(
"-p",
"--port",
help="Port to bind.",
type=click.INT,
default=8000,
required=False,
show_default=True,
)
@click.option(
"-w",
"--workers",
help="The number of worker processes for handling requests.",
type=click.IntRange(min=1, max=cpu_count()),
default=1,
required=False,
show_default=True,
)
@click.option(
"--no-reload",
help="Disable auto-reload.",
is_flag=True,
required=False,
)
def run(**options):
"""Run development uvicorn server.

The 'fastapi-mvc run' commands runs development uvicorn server for a
fastapi-mvc project at the current working directory.
\f

Args:
options(dict): CLI command options.

"""
cwd = os.getcwd()
ini_file = os.path.join(cwd, "fastapi-mvc.ini")

if not os.path.exists(ini_file) or not os.path.isfile(ini_file):
click.echo(
"Not a fastapi-mvc project, fastapi-mvc.ini does not exist.",
)
sys.exit(1)

if not os.access(ini_file, os.R_OK):
click.echo("File fastapi-mvc.ini is not readable.")
sys.exit(1)

config = configparser.ConfigParser()
config.read(ini_file)
package_name = config["project"]["package_name"]

sys.exit(
uvicorn.run(
"{0:s}.app.asgi:application".format(package_name),
host=options["host"],
port=options["port"],
reload=True if not options["no_reload"] else False,
workers=options["workers"],
log_config=None,
access_log=True,
)
)
3 changes: 2 additions & 1 deletion fastapi_mvc/template/cookiecutter.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,6 @@
"LGPLv2",
"no"
],
"year": "{{ cookiecutter.year }}"
"year": "{{ cookiecutter.year }}",
"fastapi_mvc_version": "{{ cookiecutter.fastapi_mvc_version }}"
}
12 changes: 12 additions & 0 deletions fastapi_mvc/template/{{cookiecutter.folder_name}}/fastapi-mvc.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[project]
folder_name = {{ cookiecutter.folder_name }}
package_name = {{ cookiecutter.package_name }}
script_name = {{ cookiecutter.script_name }}
redis = {{ cookiecutter.redis }}
github_actions = {{ cookiecutter.github_actions }}
aiohttp = {{ cookiecutter.aiohttp }}
vagrantfile = {{ cookiecutter.vagrantfile }}
helm = {{ cookiecutter.helm }}

[fastapi-mvc]
version = {{ cookiecutter.fastapi_mvc_version }}
Loading