mirror of https://github.com/knative/func.git
docs: python update (#2932)
This commit is contained in:
parent
837988484f
commit
a3dac70419
|
|
@ -1,160 +1,379 @@
|
||||||
# Python Function Developer's Guide
|
# Python Function Developer's Guide
|
||||||
|
|
||||||
When creating a Python function using the `func` CLI, the project directory
|
Python Functions allow for the direct deployment of source code as a production
|
||||||
looks like a typical Python project. Both HTTP and Event functions have the same
|
service to any Kubernetes cluster with Knative installed. The request handler
|
||||||
template structure.
|
method signature follows the ASGI (Asynchronous Server Gateway Interface)
|
||||||
|
standard, allowing for integration with any supporting library.
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
|
||||||
|
When you create a Python function using `func create -l python`, you get a standard Python project structure:
|
||||||
|
|
||||||
```
|
```
|
||||||
❯ func create -l python fn
|
❯ func create -l python myfunc
|
||||||
Project path: /home/developer/src/fn
|
❯ tree myfunc
|
||||||
Function name: fn
|
myfunc/
|
||||||
Runtime: python
|
├── func.yaml # Function configuration
|
||||||
|
├── pyproject.toml # Python project metadata
|
||||||
❯ tree
|
├── function/
|
||||||
fn
|
│ ├── __init__.py
|
||||||
├── func.py
|
│ └── func.py # Your function implementation
|
||||||
├── func.yaml
|
└── tests/
|
||||||
├── requirements.txt
|
└── test_func.py # Unit tests
|
||||||
└── test_func.py
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Aside from the `func.yaml` file, this looks like the beginning of just about
|
The `func.yaml` file contains build and deployment configuration. For details,
|
||||||
any Python project. For now, we will ignore the `func.yaml` file, and just
|
see the [func.yaml reference](../reference/func_yaml.md).
|
||||||
say that it is a configuration file that is used when building your project.
|
|
||||||
If you're really interested, check out the [reference doc](../reference/func_yaml.md).
|
|
||||||
To learn more about the CLI and the details for each supported command, see
|
|
||||||
the [CLI Commands document](../reference/func.md).
|
|
||||||
|
|
||||||
## Running the function locally
|
## Function Implementation
|
||||||
|
|
||||||
To run a function, you'll first need to build it. This step creates an OCI
|
Python functions must implement a method `new()` which returns a new instance
|
||||||
container image that can be run locally on your computer, or on a Kubernetes
|
of your Function class:
|
||||||
cluster.
|
|
||||||
|
|
||||||
```
|
|
||||||
❯ func build
|
|
||||||
```
|
|
||||||
|
|
||||||
After the function has been built, it can be run locally.
|
|
||||||
|
|
||||||
```
|
|
||||||
❯ func run
|
|
||||||
```
|
|
||||||
|
|
||||||
Functions can be invoked with a simple HTTP request.
|
|
||||||
You can test to see if the function is working by using your browser to visit
|
|
||||||
http://localhost:8080. You can also access liveness and readiness
|
|
||||||
endpoints at http://localhost:8080/health/liveness and
|
|
||||||
http://localhost:8080/health/readiness. These two endpoints are used
|
|
||||||
by Kubernetes to determine the health of your function. If everything
|
|
||||||
is good, both of these will return `OK`.
|
|
||||||
|
|
||||||
## Deploying the function to a cluster
|
|
||||||
|
|
||||||
To deploy your function to a Kubernetes cluster, use the `deploy` command.
|
|
||||||
|
|
||||||
```
|
|
||||||
❯ func deploy
|
|
||||||
```
|
|
||||||
|
|
||||||
You can get the URL for your deployed function with the `info` command.
|
|
||||||
|
|
||||||
```
|
|
||||||
❯ func info
|
|
||||||
```
|
|
||||||
|
|
||||||
## Testing a function locally
|
|
||||||
|
|
||||||
|
|
||||||
Python functions can be tested locally on your computer. In the project there is
|
|
||||||
a `test_func.py` file which contains a simple unit test. To run the test locally,
|
|
||||||
you'll need to install the required dependencies. You do this as you would
|
|
||||||
with any Python project.
|
|
||||||
|
|
||||||
```
|
|
||||||
❯ pip install -r requirements.txt
|
|
||||||
```
|
|
||||||
|
|
||||||
Once you have done this, you can run the provided tests with `python3 test_func.py`.
|
|
||||||
The default test framework for Python functions is `unittest`. If you prefer another,
|
|
||||||
that's no problem. Just install a test framework more to your liking.
|
|
||||||
|
|
||||||
## Function reference
|
|
||||||
|
|
||||||
Boson Python functions have very few restrictions. You can add any required dependencies
|
|
||||||
in `requirements.txt`, and you may include additional local Python files. The only real
|
|
||||||
requirements are that your project contain a `func.py` file which contains a `main()` function.
|
|
||||||
In this section, we will look in a little more detail at how Boson functions are invoked,
|
|
||||||
and what APIs are available to you as a developer.
|
|
||||||
|
|
||||||
### Invocation parameters
|
|
||||||
|
|
||||||
When using the `func` CLI to create a function project, you may choose to generate a project
|
|
||||||
that responds to a `CloudEvent` or simple HTTP. `CloudEvents` in Knative are transported over
|
|
||||||
HTTP as a `POST` request, so in many ways, the two types of functions are very much the same.
|
|
||||||
They each will listen and respond to incoming HTTP events.
|
|
||||||
|
|
||||||
When an incoming request is received, your function will be invoked with a `Context`
|
|
||||||
object as the first parameter. This object is a Python class with two attributes. The
|
|
||||||
`request` attribute will always be present, and contains the Flask `request` object.
|
|
||||||
The second attribute, `cloud_event`, will be populated if the incoming request is a
|
|
||||||
`CloudEvent`. Developers may access any `CloudEvent` data from the context object.
|
|
||||||
For example:
|
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def main(context: Context):
|
def new():
|
||||||
"""
|
"""Factory function that returns a Function instance."""
|
||||||
The context parameter contains the Flask request object and any
|
return Function()
|
||||||
CloudEvent received with the request.
|
|
||||||
"""
|
class Function:
|
||||||
print(f"Method: {context.request.method}")
|
"""Your function implementation."""
|
||||||
print(f"Event data {context.cloud_event.data})
|
pass
|
||||||
# ... business logic here
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Return Values
|
### Core Methods
|
||||||
Functions may return any value supported by Flask, as the invocation framework
|
|
||||||
proxies these values directly to the Flask server. See the Flask
|
|
||||||
[documentation](https://flask.palletsprojects.com/en/1.1.x/quickstart/#about-responses)
|
|
||||||
for more information.
|
|
||||||
|
|
||||||
#### Example
|
Your function class can implement several optional methods:
|
||||||
```python
|
|
||||||
def main(context: Context):
|
|
||||||
body = { "message": "Howdy!" }
|
|
||||||
headers = { "content-type": "application/json" }
|
|
||||||
return body, 200, headers
|
|
||||||
```
|
|
||||||
|
|
||||||
Note that functions may set both headers and response codes as secondary
|
#### `handle(self, scope, receive, send)`
|
||||||
and tertiary response values from function invocation.
|
The main request handler following ASGI protocol. This async method processes all HTTP requests except health checks.
|
||||||
|
|
||||||
### CloudEvents
|
|
||||||
All event messages in Knative are sent as `CloudEvents` over HTTP. As noted
|
|
||||||
above, function developers may access an event through the `context` parameter
|
|
||||||
when the function is invoked. Additionally, developers may use an `@event`
|
|
||||||
decorator to inform the invoker that this function's return value should be
|
|
||||||
converted to a `CloudEvent` before sending the response. For example:
|
|
||||||
|
|
||||||
```python
|
```python
|
||||||
@event("event_source"="/my/function", "event_type"="my.type")
|
async def handle(self, scope, receive, send):
|
||||||
def main(context):
|
"""Handle HTTP requests."""
|
||||||
# business logic here
|
# Process the request
|
||||||
data = do_something()
|
await send({
|
||||||
# more data processing
|
'type': 'http.response.start',
|
||||||
return data
|
'status': 200,
|
||||||
|
'headers': [[b'content-type', b'text/plain']],
|
||||||
|
})
|
||||||
|
await send({
|
||||||
|
'type': 'http.response.body',
|
||||||
|
'body': b'Hello, World!',
|
||||||
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
This will result in a `CloudEvent` as the response value, with a type of
|
#### `start(self, cfg)`
|
||||||
`"my.type"`, a source of `"/my/function"`, and the data property set to `data`.
|
|
||||||
Both the `event_source` and `event_type` decorator attributes are optional.
|
|
||||||
If not supplied, the CloudEvent's source attribute will be set to
|
|
||||||
`"/parliament/function"` and the type will be set to `"parliament.response"`.
|
|
||||||
|
|
||||||
## Dependencies
|
Called when a function instance starts (e.g., during scaling or updates). Receives configuration as a dictionary.
|
||||||
Developers are not restricted to the dependencies provided in the template
|
|
||||||
`requirements.txt` file. Additional dependencies can be added as they would be
|
```python
|
||||||
in any other project by simply adding them to the `requirements.txt` file.
|
def start(self, cfg):
|
||||||
When the project is built for deployment, these dependencies will be included
|
"""Initialize function with configuration."""
|
||||||
in the container image.
|
self.debug = cfg.get('DEBUG', 'false').lower() == 'true'
|
||||||
|
logging.info("Function initialized")
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `stop(self)`
|
||||||
|
|
||||||
|
Called when a function instance stops. Use for cleanup operations.
|
||||||
|
|
||||||
|
```python
|
||||||
|
def stop(self):
|
||||||
|
"""Clean up resources."""
|
||||||
|
# Close database connections, flush buffers, etc.
|
||||||
|
logging.info("Function shutting down")
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `alive(self)` and `ready(self)`
|
||||||
|
|
||||||
|
Health check methods exposed at `/health/liveness` and `/health/readiness`:
|
||||||
|
|
||||||
|
```python
|
||||||
|
def alive(self):
|
||||||
|
"""Liveness check."""
|
||||||
|
return True, "Function is alive"
|
||||||
|
|
||||||
|
def ready(self):
|
||||||
|
"""Readiness check."""
|
||||||
|
if self.database_connected:
|
||||||
|
return True, "Ready to serve"
|
||||||
|
return False, "Database not connected"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Local Development
|
||||||
|
|
||||||
|
### Running Your Function
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Build and run on the host (not in a container)
|
||||||
|
func run --builder=host
|
||||||
|
|
||||||
|
# Force rebuild even if no changes detected
|
||||||
|
func run --build
|
||||||
|
```
|
||||||
|
|
||||||
|
### Testing
|
||||||
|
|
||||||
|
Test your function with HTTP requests:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Test the main endpoint
|
||||||
|
curl http://localhost:8080
|
||||||
|
|
||||||
|
# Check health endpoints
|
||||||
|
curl http://localhost:8080/health/liveness
|
||||||
|
curl http://localhost:8080/health/readiness
|
||||||
|
```
|
||||||
|
|
||||||
|
### Testing CloudEvent Functions
|
||||||
|
|
||||||
|
Create a CloudEvent function:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Create a new CloudEvent function
|
||||||
|
func create -l python -t cloudevents myeventfunc
|
||||||
|
```
|
||||||
|
|
||||||
|
Test CloudEvent functions using curl with proper headers:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Invoke with a CloudEvent
|
||||||
|
curl -X POST http://localhost:8080 \
|
||||||
|
-H "Ce-Specversion: 1.0" \
|
||||||
|
-H "Ce-Type: com.example.sampletype" \
|
||||||
|
-H "Ce-Source: example/source" \
|
||||||
|
-H "Ce-Id: 1234-5678-9101" \
|
||||||
|
-H "Ce-Subject: example-subject" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"message": "Hello CloudEvent!"}'
|
||||||
|
```
|
||||||
|
|
||||||
|
Also see `func invoke` which automates this for basic testing.
|
||||||
|
|
||||||
|
### Unit Testing
|
||||||
|
|
||||||
|
Python functions use modern Python packaging with `pyproject.toml` and include
|
||||||
|
pytest with async support for testing ASGI functions. The generated project
|
||||||
|
includes example tests in `tests/test_func.py` that demonstrate how to test the
|
||||||
|
async handler.
|
||||||
|
|
||||||
|
#### Setting Up Your Development Environment
|
||||||
|
|
||||||
|
It's best practice to use a virtual environment to isolate your function's dependencies:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Create a virtual environment (Python 3.3+)
|
||||||
|
python3 -m venv venv
|
||||||
|
|
||||||
|
# Activate the virtual environment
|
||||||
|
# On Linux/macOS:
|
||||||
|
source venv/bin/activate
|
||||||
|
# On Windows:
|
||||||
|
# venv\Scripts\activate
|
||||||
|
|
||||||
|
# Upgrade pip to ensure you have the latest version
|
||||||
|
python -m pip install --upgrade pip
|
||||||
|
|
||||||
|
# Install the function package and its dependencies (including test dependencies)
|
||||||
|
pip install -e .
|
||||||
|
|
||||||
|
# Run tests with pytest
|
||||||
|
pytest
|
||||||
|
|
||||||
|
# Run tests with verbose output
|
||||||
|
pytest -v
|
||||||
|
|
||||||
|
# Run tests with coverage (requires pytest-cov)
|
||||||
|
pip install pytest-cov
|
||||||
|
pytest --cov=function --cov-report=term-missing
|
||||||
|
|
||||||
|
# When done, deactivate the virtual environment
|
||||||
|
deactivate
|
||||||
|
```
|
||||||
|
|
||||||
|
**Note**:
|
||||||
|
- Python 3 typically comes with `venv` module built-in
|
||||||
|
- If `python3` command is not found, try `python` instead
|
||||||
|
- The `-m pip` syntax ensures you're using the pip from your virtual environment
|
||||||
|
- Always activate your virtual environment before running tests or installing dependencies
|
||||||
|
|
||||||
|
#### Writing Tests for ASGI Functions
|
||||||
|
|
||||||
|
The test file demonstrates how to test ASGI functions by mocking the ASGI interface:
|
||||||
|
|
||||||
|
```python
|
||||||
|
import pytest
|
||||||
|
from function import new
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_function_handle():
|
||||||
|
# Create function instance
|
||||||
|
f = new()
|
||||||
|
|
||||||
|
# Mock ASGI scope (request details)
|
||||||
|
scope = {
|
||||||
|
'type': 'http',
|
||||||
|
'method': 'POST',
|
||||||
|
'path': '/',
|
||||||
|
'headers': [(b'content-type', b'application/json')],
|
||||||
|
}
|
||||||
|
|
||||||
|
# Mock receive callable (for request body)
|
||||||
|
async def receive():
|
||||||
|
return {
|
||||||
|
'type': 'http.request',
|
||||||
|
'body': b'{"test": "data"}',
|
||||||
|
'more_body': False,
|
||||||
|
}
|
||||||
|
|
||||||
|
# Track sent responses
|
||||||
|
responses = []
|
||||||
|
|
||||||
|
# Mock send callable
|
||||||
|
async def send(message):
|
||||||
|
responses.append(message)
|
||||||
|
|
||||||
|
# Call the handler
|
||||||
|
await f.handle(scope, receive, send)
|
||||||
|
|
||||||
|
# Assert responses
|
||||||
|
assert len(responses) == 2
|
||||||
|
assert responses[0]['type'] == 'http.response.start'
|
||||||
|
assert responses[0]['status'] == 200
|
||||||
|
assert responses[1]['type'] == 'http.response.body'
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Testing CloudEvent Functions
|
||||||
|
|
||||||
|
For CloudEvent functions, include CloudEvent headers in your test scope:
|
||||||
|
|
||||||
|
```python
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_cloudevent_handler():
|
||||||
|
f = new()
|
||||||
|
|
||||||
|
# CloudEvent headers
|
||||||
|
scope = {
|
||||||
|
'type': 'http',
|
||||||
|
'method': 'POST',
|
||||||
|
'path': '/',
|
||||||
|
'headers': [
|
||||||
|
(b'ce-specversion', b'1.0'),
|
||||||
|
(b'ce-type', b'com.example.test'),
|
||||||
|
(b'ce-source', b'test/unit'),
|
||||||
|
(b'ce-id', b'test-123'),
|
||||||
|
(b'content-type', b'application/json'),
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
# Test with CloudEvent data
|
||||||
|
async def receive():
|
||||||
|
return {
|
||||||
|
'type': 'http.request',
|
||||||
|
'body': b'{"message": "test event"}',
|
||||||
|
'more_body': False,
|
||||||
|
}
|
||||||
|
|
||||||
|
# ... rest of test
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Testing with Real HTTP Clients
|
||||||
|
|
||||||
|
For integration testing, you can use httpx with ASGI support:
|
||||||
|
|
||||||
|
```python
|
||||||
|
import httpx
|
||||||
|
import pytest
|
||||||
|
from function import new
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_with_http_client():
|
||||||
|
f = new()
|
||||||
|
|
||||||
|
# Create ASGI transport with your function
|
||||||
|
transport = httpx.ASGITransport(app=f.handle)
|
||||||
|
|
||||||
|
# Make HTTP requests
|
||||||
|
async with httpx.AsyncClient(transport=transport, base_url="http://test") as client:
|
||||||
|
response = await client.get("/")
|
||||||
|
assert response.status_code == 200
|
||||||
|
|
||||||
|
response = await client.post("/", json={"test": "data"})
|
||||||
|
assert response.status_code == 200
|
||||||
|
```
|
||||||
|
|
||||||
|
## Advanced Implementation Examples
|
||||||
|
|
||||||
|
### Processing Request Data
|
||||||
|
|
||||||
|
```python
|
||||||
|
async def handle(self, scope, receive, send):
|
||||||
|
"""Process POST requests with JSON data."""
|
||||||
|
if scope['method'] == 'POST':
|
||||||
|
# Receive request body
|
||||||
|
body = b''
|
||||||
|
while True:
|
||||||
|
message = await receive()
|
||||||
|
if message['type'] == 'http.request':
|
||||||
|
body += message.get('body', b'')
|
||||||
|
if not message.get('more_body', False):
|
||||||
|
break
|
||||||
|
|
||||||
|
# Process JSON data
|
||||||
|
import json
|
||||||
|
data = json.loads(body)
|
||||||
|
result = process_data(data)
|
||||||
|
|
||||||
|
# Send response
|
||||||
|
response_body = json.dumps(result).encode()
|
||||||
|
await send({
|
||||||
|
'type': 'http.response.start',
|
||||||
|
'status': 200,
|
||||||
|
'headers': [[b'content-type', b'application/json']],
|
||||||
|
})
|
||||||
|
await send({
|
||||||
|
'type': 'http.response.body',
|
||||||
|
'body': response_body,
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
### Environment-Based Configuration
|
||||||
|
|
||||||
|
```python
|
||||||
|
class Function:
|
||||||
|
def start(self, cfg):
|
||||||
|
"""Configure function from environment."""
|
||||||
|
self.api_key = cfg.get('API_KEY')
|
||||||
|
self.cache_ttl = int(cfg.get('CACHE_TTL', '300'))
|
||||||
|
self.log_level = cfg.get('LOG_LEVEL', 'INFO')
|
||||||
|
|
||||||
|
logging.basicConfig(level=self.log_level)
|
||||||
|
```
|
||||||
|
|
||||||
|
### CloudEvent Handling
|
||||||
|
|
||||||
|
For CloudEvent support, parse the headers and body accordingly:
|
||||||
|
|
||||||
|
```python
|
||||||
|
async def handle(self, scope, receive, send):
|
||||||
|
"""Handle CloudEvents."""
|
||||||
|
headers = dict(scope['headers'])
|
||||||
|
|
||||||
|
# Check if this is a CloudEvent
|
||||||
|
if b'ce-type' in headers:
|
||||||
|
event_type = headers[b'ce-type'].decode()
|
||||||
|
event_source = headers[b'ce-source'].decode()
|
||||||
|
# Process CloudEvent...
|
||||||
|
```
|
||||||
|
|
||||||
|
## Deployment
|
||||||
|
|
||||||
|
### Basic Deployment
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Deploy to a specific registry
|
||||||
|
func deploy --builder=host --registry docker.io/myuser
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
For all deploy options, see `func deploy --help`
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,6 +1,50 @@
|
||||||
# Python CloudEvents Function
|
# Python CloudEvents Function
|
||||||
|
|
||||||
Welcome to your new Python Function! A minimal Function implementation can
|
Welcome to your new Python Function! A minimal Function implementation can
|
||||||
be found in ./function/func.py.
|
be found in `./function/func.py`.
|
||||||
|
|
||||||
|
For more, run `func --help` or read the [Python Functions doc](https://github.com/knative/func/blob/main/docs/function-templates/python.md)
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Knative Functions allow for the deployment of your source code directly to a
|
||||||
|
Kubernetes cluster with Knative installed.
|
||||||
|
|
||||||
|
### Function Structure
|
||||||
|
|
||||||
|
Python functions must implement a `new()` method that returns a function
|
||||||
|
instance. The function class can optionally implement:
|
||||||
|
- `handle()` - Process CloudEvent requests
|
||||||
|
- `start()` - Initialize the function with configuration
|
||||||
|
- `stop()` - Clean up resources when the function stops
|
||||||
|
- `alive()` / `ready()` - Health and readiness checks
|
||||||
|
|
||||||
|
See the default implementation in `./function/func.py`
|
||||||
|
|
||||||
|
### Running Locally
|
||||||
|
|
||||||
|
Use `func run` to test your Function locally before deployment.
|
||||||
|
For development environments where Python is installed, it's suggested to use
|
||||||
|
the `host` builder as follows:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Run function on the host (outsdie of a container)
|
||||||
|
func run --builder=host
|
||||||
|
```
|
||||||
|
|
||||||
|
### Deploying
|
||||||
|
|
||||||
|
Use `func deploy` to deploy your Function to a Knative-enabled cluster:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Deploy with interactive prompts (recommended for first deployment)
|
||||||
|
func deploy --registry ghcr.io/myuser
|
||||||
|
```
|
||||||
|
|
||||||
|
Functions are automatically built, containerized, and pushed to a registry
|
||||||
|
before deployment. Subsequent deployments will update the existing function.
|
||||||
|
|
||||||
|
## Roadmap
|
||||||
|
|
||||||
|
Our project roadmap can be found: https://github.com/orgs/knative/projects/49
|
||||||
|
|
||||||
For more, see [the complete documentation]('https://github.com/knative/func/tree/main/docs')
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,50 @@
|
||||||
# Python HTTP Function
|
# Python HTTP Function
|
||||||
|
|
||||||
Welcome to your new Python Function! A minimal Function implementation can
|
Welcome to your new Python Function! A minimal Function implementation can
|
||||||
be found in func.py.
|
be found in `./function/func.py`.
|
||||||
|
|
||||||
|
For more, run `func --help` or read the [Python Functions doc](https://github.com/knative/func/blob/main/docs/function-templates/python.md)
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Knative Functions allow for the deployment of your source code directly to a
|
||||||
|
Kubernetes cluster with Knative installed.
|
||||||
|
|
||||||
|
### Function Structure
|
||||||
|
|
||||||
|
Python functions must implement a `new()` method that returns a function
|
||||||
|
instance. The function class can optionally implement:
|
||||||
|
- `handle()` - Process HTTP requests
|
||||||
|
- `start()` - Initialize the function with configuration
|
||||||
|
- `stop()` - Clean up resources when the function stops
|
||||||
|
- `alive()` / `ready()` - Health and readiness checks
|
||||||
|
|
||||||
|
See the default implementation in `./function/func.py`
|
||||||
|
|
||||||
|
### Running Locally
|
||||||
|
|
||||||
|
Use `func run` to test your Function locally before deployment.
|
||||||
|
For development environments where Python is installed, it's suggested to use
|
||||||
|
the `host` builder as follows:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Run function on the host (outside of a container)
|
||||||
|
func run --builder=host
|
||||||
|
```
|
||||||
|
|
||||||
|
### Deploying
|
||||||
|
|
||||||
|
Use `func deploy` to deploy your Function to a Knative-enabled cluster:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Deploy with interactive prompts (recommended for first deployment)
|
||||||
|
func deploy --registry ghcr.io/myuser
|
||||||
|
```
|
||||||
|
|
||||||
|
Functions are automatically built, containerized, and pushed to a registry
|
||||||
|
before deployment. Subsequent deployments will update the existing function.
|
||||||
|
|
||||||
|
## Roadmap
|
||||||
|
|
||||||
|
Our project roadmap can be found: https://github.com/orgs/knative/projects/49
|
||||||
|
|
||||||
For more, see [the complete documentation]('https://github.com/knative/func/tree/main/docs')
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue