Skip to content

Commit

Permalink
Refactor CLI Folder Structure (#12) (#196)
Browse files Browse the repository at this point in the history
* Refactor CLI Folder Structure (#12)

- Creates separate command folder structure

- Refactored cli __init__ to import commands explicitly

* Rename 'cmd_server' to 'server' in cli commands.

* Add simple tests for CLI

* Change mokeypatching to mocking. Add pytest-mock.
  • Loading branch information
bryanculver authored and patrick91 committed Oct 31, 2019
1 parent d08b17e commit 052ef48
Show file tree
Hide file tree
Showing 9 changed files with 111 additions and 40 deletions.
3 changes: 3 additions & 0 deletions RELEASE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Release type: minor

Refactored CLI folder structure, importing click commands from a subfolder. Follows click's complex example.
14 changes: 13 additions & 1 deletion poetry.lock

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

1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ mypy = "^0.740"
flake8-bugbear = "^19.8"
pytest-django = {version = "^3.6", optional = true}
pytest-mypy-plugins = "^1.1"
pytest-mock = "^1.11"

[tool.poetry.extras]
django = ["django","pytest-django"]
Expand Down
41 changes: 2 additions & 39 deletions strawberry/cli/__init__.py
Original file line number Diff line number Diff line change
@@ -1,48 +1,11 @@
import click
import sys

import os
from starlette.applications import Starlette
from starlette.middleware.cors import CORSMiddleware

import importlib

import uvicorn

import hupper

from strawberry.asgi import GraphQL
from .commands.server import server as cmd_server


@click.group()
def run():
pass


@run.command("server")
@click.argument("module", type=str)
@click.option("-h", "--host", default="0.0.0.0", type=str)
@click.option("-p", "--port", default=8000, type=int)
def server(module, host, port):
sys.path.append(os.getcwd())

reloader = hupper.start_reloader("strawberry.cli.run", verbose=False)

schema_module = importlib.import_module(module)

reloader.watch_files([schema_module.__file__])

app = Starlette(debug=True)

app.add_middleware(
CORSMiddleware, allow_headers=["*"], allow_origins=["*"], allow_methods=["*"]
)

graphql_app = GraphQL(schema_module.schema, debug=True)

app.add_route("/graphql", graphql_app)
app.add_websocket_route("/graphql", graphql_app)

print(f"Running strawberry on http://{host}:{port}/graphql 🍓")

uvicorn.run(app, host=host, port=port, log_level="error")
run.add_command(cmd_server)
Empty file.
43 changes: 43 additions & 0 deletions strawberry/cli/commands/server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import click
import sys

import os
from starlette.applications import Starlette
from starlette.middleware.cors import CORSMiddleware

import importlib

import uvicorn

import hupper

from strawberry.asgi import GraphQL


@click.command("server", short_help='Starts debug server')
@click.argument("module", type=str)
@click.option("-h", "--host", default="0.0.0.0", type=str)
@click.option("-p", "--port", default=8000, type=int)
def server(module, host, port):
sys.path.append(os.getcwd())

reloader = hupper.start_reloader("strawberry.cli.run", verbose=False)

schema_module = importlib.import_module(module)

reloader.watch_files([schema_module.__file__])

app = Starlette(debug=True)

app.add_middleware(
CORSMiddleware, allow_headers=["*"], allow_origins=["*"], allow_methods=["*"]
)

graphql_app = GraphQL(schema_module.schema, debug=True)

app.add_route("/graphql", graphql_app)
app.add_websocket_route("/graphql", graphql_app)

print(f"Running strawberry on http://{host}:{port}/graphql 🍓")

uvicorn.run(app, host=host, port=port, log_level="error")
Empty file added tests/cli/__init__.py
Empty file.
17 changes: 17 additions & 0 deletions tests/cli/helpers/sample_schema.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import strawberry


@strawberry.type
class User:
name: str
age: int


@strawberry.type
class Query:
@strawberry.field
def user(self, info) -> User:
return User(name="Patrick", age=100)


schema = strawberry.Schema(query=Query)
32 changes: 32 additions & 0 deletions tests/cli/test_server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from click.testing import CliRunner

from strawberry.cli.commands.server import server as cmd_server

import uvicorn
import hupper


def test_cli_cmd_server(mocker):

# Mock of uvicorn.run
uvicorn_run_patch = mocker.patch('uvicorn.run')
uvicorn_run_patch.return_value = True
# Mock to prevent the reloader from kicking in
hupper_reloader_patch = mocker.patch('hupper.start_reloader')
hupper_reloader_patch.return_value = MockReloader()
runner = CliRunner()

result = runner.invoke(cmd_server, ['tests.cli.helpers.sample_schema'], "")
assert result.exit_code == 0

# We started the reloader
assert hupper.start_reloader.call_count == 1
assert uvicorn.run.call_count == 1

assert result.output == 'Running strawberry on http://0.0.0.0:8000/graphql 🍓\n'


class MockReloader:
@staticmethod
def watch_files(*args, **kwargs):
return True

0 comments on commit 052ef48

Please sign in to comment.