Skip to content

Commit cd56d31

Browse files
authored
feat: add dev command (#83)
* feat: add dev command * fix: update lockfile * chore: remove boto3 * chore: revert gateway auth key changes * chore: update lockfile * fix: do not store handler in function * chore: update poetry lock * fix: missing scaleway-functions-python * test: increase retry * docs: add README section
1 parent 130d284 commit cd56d31

File tree

12 files changed

+224
-29
lines changed

12 files changed

+224
-29
lines changed

README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,20 @@ def hello_world(event, context):
5959
The configuration is done by passing arguments to the decorator.
6060
To view which arguments are supported, head over to this [documentation](https://serverless-api-framework-python.readthedocs.io/) page.
6161

62+
### Local testing
63+
64+
Before deploying, you can run your functions locally with the dev command:
65+
66+
```console
67+
scw-serverless dev app.py
68+
```
69+
70+
This runs a local Flask server with your Serverless handlers. If no `relative_url` is defined for a function, it will be served on `/name` with `name` being the name of your Python function.
71+
72+
By default, this runs Flask in debug mode which includes hot-reloading. You can disable this behavior by passing the `--no-debug` flag.
73+
74+
### Deploying
75+
6276
When you are ready, you can deploy your function with the `scw-serverless` CLI tool:
6377

6478
```console

docs/source/deploying.rst

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,30 @@
11
Deploying
22
=========
33

4-
After writing your functions, the included CLI tool `scw-serverless` helps deploy your application on Scaleway.
4+
After writing your functions, the included CLI tool `scw-serverless` helps test and deploy your application on Scaleway.
5+
6+
Running locally
7+
---------------
8+
9+
You can test your functions locally before deploying with the `dev` command:
10+
11+
.. code-block:: console
12+
13+
scw-serverless dev app.py
14+
15+
This will start a local Flask server with your functions that will behave similarly to Scaleway Functions.
16+
17+
By default, functions are served by `/name` on port 8080 with the name being the name of the Python function.
18+
19+
You can then use your favorite tools to query the functions:
20+
21+
.. code-block:: console
22+
23+
# For a function named def handle()...
24+
curl http://localhost:8080/handle
25+
26+
This command allows you to test your code, but as this test environment is not quite the same as Scaleway Functions,
27+
there might be slight differences when deploying.
528

629
Deploy
730
------

examples/hello_world/handler.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@ def handle(_event: dict[str, Any], _content: dict[str, Any]) -> dict[str, Any]:
1313
context (dict): function call metadata
1414
"""
1515

16-
return {"message": "Hello from Scaleway functions using Serverless API Framework"}
16+
return {"body": "Hello from Scaleway functions using Serverless API Framework"}

poetry.lock

Lines changed: 99 additions & 17 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,10 @@ include = ["CHANGELOG.md"]
3333
scw-serverless = "scw_serverless.cli:cli"
3434

3535
[tool.poetry.dependencies]
36-
python = "^3.9"
36+
python = ">=3.9,<3.12"
3737
click = "^8.1.3"
3838
scaleway = ">=0.7,<0.13"
39+
scaleway-functions-python = "^0.2.0"
3940
requests = "^2.28.2"
4041
typing-extensions = { version = "^4.4.0", python = "<3.11" }
4142

scw_serverless/cli.py

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
import click
66
from scaleway import ScalewayException
77

8-
from scw_serverless import deployment, loader, logger
8+
import scw_serverless
9+
from scw_serverless import app, deployment, loader, local_app, logger
910
from scw_serverless.dependencies_manager import DependenciesManager
1011
from scw_serverless.gateway.gateway_manager import GatewayManager
1112

@@ -145,3 +146,30 @@ def deploy(
145146
sdk_client=client,
146147
)
147148
manager.update_routes()
149+
150+
151+
@cli.command()
152+
@CLICK_ARG_FILE
153+
@click.option(
154+
"--port",
155+
"-p",
156+
"port",
157+
default=8080,
158+
show_default=True,
159+
help="Set port to listen on.",
160+
)
161+
@click.option(
162+
"--debug/--no-debug",
163+
"debug",
164+
default=True,
165+
show_default=True,
166+
help="Run Flask in debug mode.",
167+
)
168+
def dev(file: Path, port: int, debug: bool) -> None:
169+
"""Run functions locally with Serverless Local Testing."""
170+
app.Serverless = local_app.ServerlessLocal
171+
scw_serverless.Serverless = local_app.ServerlessLocal
172+
app_instance = cast(
173+
local_app.ServerlessLocal, loader.load_app_instance(file.resolve())
174+
)
175+
app_instance.local_server.serve(port=port, debug=debug)

scw_serverless/config/function.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ class Function:
5757
"""Representation of a Scaleway function."""
5858

5959
name: str
60-
handler: str # Path to the handler
60+
handler_path: str
6161
environment_variables: Optional[dict[str, str]] = None
6262
min_scale: Optional[int] = None
6363
max_scale: Optional[int] = None
@@ -85,7 +85,7 @@ def from_handler(
8585
gateway_route = GatewayRoute(url, http_methods=args.get("http_methods"))
8686
return Function(
8787
name=to_valid_function_name(handler.__name__),
88-
handler=module_to_path(handler.__module__) + "." + handler.__name__,
88+
handler_path=module_to_path(handler.__module__) + "." + handler.__name__,
8989
environment_variables=args.get("env"),
9090
min_scale=args.get("min_scale"),
9191
max_scale=args.get("max_scale"),

scw_serverless/deployment/api_wrapper.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ def create_function(
8989
max_scale=function.max_scale,
9090
memory_limit=function.memory_limit,
9191
timeout=function.timeout,
92-
handler=function.handler,
92+
handler=function.handler_path,
9393
description=function.description,
9494
secret_environment_variables=self._get_secrets_from_dict(
9595
function.secret_environment_variables
@@ -110,7 +110,7 @@ def update_function(
110110
max_scale=function.max_scale,
111111
memory_limit=function.memory_limit,
112112
timeout=function.timeout,
113-
handler=function.handler,
113+
handler=function.handler_path,
114114
description=function.description,
115115
secret_environment_variables=self._get_secrets_from_dict(
116116
function.secret_environment_variables

0 commit comments

Comments
 (0)