fastapi-cloudevents


Namefastapi-cloudevents JSON
Version 2.0.2 PyPI version JSON
download
home_pagehttps://github.com/sasha-tkachev/fastapi-cloudevents
SummaryFastAPI plugin for CloudEvents Integration
upload_time2024-02-24 19:52:18
maintainer
docs_urlNone
authorAlexander Tkachev
requires_python
license
keywords fastapi cloudevents[pydantic] ce cloud events event middleware rest rest-api plugin pydantic fastapi-extension
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # fastapi-cloudevents

[![](https://github.com/sasha-tkachev/fastapi-cloudevents/actions/workflows/main.yaml/badge.svg)](https://github.com/sasha-tkachev/fastapi-cloudevents/actions/workflows/main.yaml)
[![](https://img.shields.io/badge/coverage-100%25-brightgreen)](https://github.com/sasha-tkachev/fastapi-cloudevents/blob/main/tests/test_docs.py#L35)

[FastAPI](https://fastapi.tiangolo.com/) plugin for [CloudEvents](https://cloudevents.io/) Integration

Allows to easily consume and produce CloudEvents over REST API.

Automatically parses CloudEvents both in the binary and structured format and
provides an interface very similar to the regular FastAPI interface. No more
hustling with `to_structured` and `from_http` function calls!

```python
@app.post("/")
async def on_event(event: CloudEvent) -> CloudEvent:
   pass
```

See more examples below

### Install

```shell script
pip install fastapi-cloudevents
```

## Examples

### [Simple Example](examples/simple_server)

```python
import uvicorn
from fastapi import FastAPI

from fastapi_cloudevents import CloudEvent, install_fastapi_cloudevents

app = FastAPI()
app = install_fastapi_cloudevents(app)


@app.post("/")
async def on_event(event: CloudEvent) -> CloudEvent:
    return CloudEvent(
        type="my.response-type.v1",
        data=event.data,
        datacontenttype=event.datacontenttype,
    )


if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8000)
```

The rout accepts both binary CloudEvents

```shell script
curl http://localhost:8000 -i -X POST -d "Hello World!" \
  -H "Content-Type: text/plain" \
  -H "ce-specversion: 1.0" \
  -H "ce-type: my.request-type.v1" \
  -H "ce-id: 123" \
  -H "ce-source: my-source"
```

And structured CloudEvents

```shell script
curl http://localhost:8000 -i -X POST -H "Content-Type: application/json" \
  -d '{"data":"Hello World", "source":"my-source", "id":"123", "type":"my.request-type.v1","specversion":"1.0"}'
```

Both of the requests will yield a response in the same format:

```text
HTTP/1.1 200 OK
date: Fri, 05 Aug 2022 23:50:52 GMT
server: uvicorn
content-length: 13
content-type: application/json
ce-specversion: 1.0
ce-id: 25cd28f0-0605-4a76-b1d8-cffbe3375413
ce-source: http://localhost:8000/
ce-type: my.response-type.v1
ce-time: 2022-08-05T23:50:52.809697+00:00

"Hello World"
```

### [CloudEvent Type Routing](examples/type_routing)

```python
from typing import Literal, Union

import uvicorn
from fastapi import FastAPI, Body
from pydantic import Field
from typing_extensions import Annotated

from fastapi_cloudevents import (
    CloudEvent,
    CloudEventSettings,
    ContentMode,
    install_fastapi_cloudevents,
)

app = FastAPI()
app = install_fastapi_cloudevents(
    app, settings=CloudEventSettings(default_response_mode=ContentMode.structured)
)


class MyEvent(CloudEvent):
    type: Literal["my.type.v1"]


class YourEvent(CloudEvent):
    type: Literal["your.type.v1"]


OurEvent = Annotated[Union[MyEvent, YourEvent], Body(discriminator="type")]

_source = "dummy:source"


@app.post("/")
async def on_event(event: OurEvent) -> CloudEvent:
    if isinstance(event, MyEvent):
        return CloudEvent(
            type="my.response-type.v1",
            data=f"got {event.data} from my event!",
            datacontenttype="text/plain",
        )
    else:
        return CloudEvent(
            type="your.response-type.v1",
            data=f"got {event.data} from your event!",
            datacontenttype="text/plain",
        )


if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8002)
```

### [Structured Response Example](examples/structured_response_server)

To send the response in the http CloudEvent structured format, you MAY use the
`BinaryCloudEventResponse` class

```python
import uvicorn
from fastapi import FastAPI

from fastapi_cloudevents import (CloudEvent, StructuredCloudEventResponse,
                                 install_fastapi_cloudevents)

app = FastAPI()
app = install_fastapi_cloudevents(app)


@app.post("/", response_class=StructuredCloudEventResponse)
async def on_event(event: CloudEvent) -> CloudEvent:
    return CloudEvent(
        type="com.my-corp.response.v1",
        data=event.data,
        datacontenttype=event.datacontenttype,
    )


if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8001)

```

```shell script
curl http://localhost:8001 -i -X POST -d "Hello World!" \
  -H "Content-Type: text/plain" \
  -H "ce-specversion: 1.0" \
  -H "ce-type: my.request-type.v1" \
  -H "ce-id: 123" \
  -H "ce-source: my-source"
```

```text
HTTP/1.1 200 OK
date: Fri, 05 Aug 2022 23:51:26 GMT
server: uvicorn
content-length: 247
content-type: application/json

{"data":"Hello World!","source":"http://localhost:8001/","id":"3412321f-85b3-4f7f-a551-f4c23a05de3a","type":"com.my-corp.response.v1","specversion":"1.0","time":"2022-08-05T23:51:26.878723+00:00","datacontenttype":"text/plain"}
```

## More Examples

- [Custom Default Source](examples/custom_default_source)
- [Mixed Usage of events and regular models](examples/events_and_basemodels_mixed)



            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/sasha-tkachev/fastapi-cloudevents",
    "name": "fastapi-cloudevents",
    "maintainer": "",
    "docs_url": null,
    "requires_python": "",
    "maintainer_email": "",
    "keywords": "fastapi,cloudevents[pydantic],ce,cloud,events,event,middleware,rest,rest-api,plugin,pydantic,fastapi-extension",
    "author": "Alexander Tkachev",
    "author_email": "sasha64sasha@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/1b/6e/21bb3a8ca082fa952fe7278ad7ce05c8e8c8a04e61a150d13313c291d55b/fastapi-cloudevents-2.0.2.tar.gz",
    "platform": null,
    "description": "# fastapi-cloudevents\r\n\r\n[![](https://github.com/sasha-tkachev/fastapi-cloudevents/actions/workflows/main.yaml/badge.svg)](https://github.com/sasha-tkachev/fastapi-cloudevents/actions/workflows/main.yaml)\r\n[![](https://img.shields.io/badge/coverage-100%25-brightgreen)](https://github.com/sasha-tkachev/fastapi-cloudevents/blob/main/tests/test_docs.py#L35)\r\n\r\n[FastAPI](https://fastapi.tiangolo.com/) plugin for [CloudEvents](https://cloudevents.io/) Integration\r\n\r\nAllows to easily consume and produce CloudEvents over REST API.\r\n\r\nAutomatically parses CloudEvents both in the binary and structured format and\r\nprovides an interface very similar to the regular FastAPI interface. No more\r\nhustling with `to_structured` and `from_http` function calls!\r\n\r\n```python\r\n@app.post(\"/\")\r\nasync def on_event(event: CloudEvent) -> CloudEvent:\r\n   pass\r\n```\r\n\r\nSee more examples below\r\n\r\n### Install\r\n\r\n```shell script\r\npip install fastapi-cloudevents\r\n```\r\n\r\n## Examples\r\n\r\n### [Simple Example](examples/simple_server)\r\n\r\n```python\r\nimport uvicorn\r\nfrom fastapi import FastAPI\r\n\r\nfrom fastapi_cloudevents import CloudEvent, install_fastapi_cloudevents\r\n\r\napp = FastAPI()\r\napp = install_fastapi_cloudevents(app)\r\n\r\n\r\n@app.post(\"/\")\r\nasync def on_event(event: CloudEvent) -> CloudEvent:\r\n    return CloudEvent(\r\n        type=\"my.response-type.v1\",\r\n        data=event.data,\r\n        datacontenttype=event.datacontenttype,\r\n    )\r\n\r\n\r\nif __name__ == \"__main__\":\r\n    uvicorn.run(app, host=\"0.0.0.0\", port=8000)\r\n```\r\n\r\nThe rout accepts both binary CloudEvents\r\n\r\n```shell script\r\ncurl http://localhost:8000 -i -X POST -d \"Hello World!\" \\\r\n  -H \"Content-Type: text/plain\" \\\r\n  -H \"ce-specversion: 1.0\" \\\r\n  -H \"ce-type: my.request-type.v1\" \\\r\n  -H \"ce-id: 123\" \\\r\n  -H \"ce-source: my-source\"\r\n```\r\n\r\nAnd structured CloudEvents\r\n\r\n```shell script\r\ncurl http://localhost:8000 -i -X POST -H \"Content-Type: application/json\" \\\r\n  -d '{\"data\":\"Hello World\", \"source\":\"my-source\", \"id\":\"123\", \"type\":\"my.request-type.v1\",\"specversion\":\"1.0\"}'\r\n```\r\n\r\nBoth of the requests will yield a response in the same format:\r\n\r\n```text\r\nHTTP/1.1 200 OK\r\ndate: Fri, 05 Aug 2022 23:50:52 GMT\r\nserver: uvicorn\r\ncontent-length: 13\r\ncontent-type: application/json\r\nce-specversion: 1.0\r\nce-id: 25cd28f0-0605-4a76-b1d8-cffbe3375413\r\nce-source: http://localhost:8000/\r\nce-type: my.response-type.v1\r\nce-time: 2022-08-05T23:50:52.809697+00:00\r\n\r\n\"Hello World\"\r\n```\r\n\r\n### [CloudEvent Type Routing](examples/type_routing)\r\n\r\n```python\r\nfrom typing import Literal, Union\r\n\r\nimport uvicorn\r\nfrom fastapi import FastAPI, Body\r\nfrom pydantic import Field\r\nfrom typing_extensions import Annotated\r\n\r\nfrom fastapi_cloudevents import (\r\n    CloudEvent,\r\n    CloudEventSettings,\r\n    ContentMode,\r\n    install_fastapi_cloudevents,\r\n)\r\n\r\napp = FastAPI()\r\napp = install_fastapi_cloudevents(\r\n    app, settings=CloudEventSettings(default_response_mode=ContentMode.structured)\r\n)\r\n\r\n\r\nclass MyEvent(CloudEvent):\r\n    type: Literal[\"my.type.v1\"]\r\n\r\n\r\nclass YourEvent(CloudEvent):\r\n    type: Literal[\"your.type.v1\"]\r\n\r\n\r\nOurEvent = Annotated[Union[MyEvent, YourEvent], Body(discriminator=\"type\")]\r\n\r\n_source = \"dummy:source\"\r\n\r\n\r\n@app.post(\"/\")\r\nasync def on_event(event: OurEvent) -> CloudEvent:\r\n    if isinstance(event, MyEvent):\r\n        return CloudEvent(\r\n            type=\"my.response-type.v1\",\r\n            data=f\"got {event.data} from my event!\",\r\n            datacontenttype=\"text/plain\",\r\n        )\r\n    else:\r\n        return CloudEvent(\r\n            type=\"your.response-type.v1\",\r\n            data=f\"got {event.data} from your event!\",\r\n            datacontenttype=\"text/plain\",\r\n        )\r\n\r\n\r\nif __name__ == \"__main__\":\r\n    uvicorn.run(app, host=\"0.0.0.0\", port=8002)\r\n```\r\n\r\n### [Structured Response Example](examples/structured_response_server)\r\n\r\nTo send the response in the http CloudEvent structured format, you MAY use the\r\n`BinaryCloudEventResponse` class\r\n\r\n```python\r\nimport uvicorn\r\nfrom fastapi import FastAPI\r\n\r\nfrom fastapi_cloudevents import (CloudEvent, StructuredCloudEventResponse,\r\n                                 install_fastapi_cloudevents)\r\n\r\napp = FastAPI()\r\napp = install_fastapi_cloudevents(app)\r\n\r\n\r\n@app.post(\"/\", response_class=StructuredCloudEventResponse)\r\nasync def on_event(event: CloudEvent) -> CloudEvent:\r\n    return CloudEvent(\r\n        type=\"com.my-corp.response.v1\",\r\n        data=event.data,\r\n        datacontenttype=event.datacontenttype,\r\n    )\r\n\r\n\r\nif __name__ == \"__main__\":\r\n    uvicorn.run(app, host=\"0.0.0.0\", port=8001)\r\n\r\n```\r\n\r\n```shell script\r\ncurl http://localhost:8001 -i -X POST -d \"Hello World!\" \\\r\n  -H \"Content-Type: text/plain\" \\\r\n  -H \"ce-specversion: 1.0\" \\\r\n  -H \"ce-type: my.request-type.v1\" \\\r\n  -H \"ce-id: 123\" \\\r\n  -H \"ce-source: my-source\"\r\n```\r\n\r\n```text\r\nHTTP/1.1 200 OK\r\ndate: Fri, 05 Aug 2022 23:51:26 GMT\r\nserver: uvicorn\r\ncontent-length: 247\r\ncontent-type: application/json\r\n\r\n{\"data\":\"Hello World!\",\"source\":\"http://localhost:8001/\",\"id\":\"3412321f-85b3-4f7f-a551-f4c23a05de3a\",\"type\":\"com.my-corp.response.v1\",\"specversion\":\"1.0\",\"time\":\"2022-08-05T23:51:26.878723+00:00\",\"datacontenttype\":\"text/plain\"}\r\n```\r\n\r\n## More Examples\r\n\r\n- [Custom Default Source](examples/custom_default_source)\r\n- [Mixed Usage of events and regular models](examples/events_and_basemodels_mixed)\r\n\r\n\r\n",
    "bugtrack_url": null,
    "license": "",
    "summary": "FastAPI plugin for CloudEvents Integration",
    "version": "2.0.2",
    "project_urls": {
        "Homepage": "https://github.com/sasha-tkachev/fastapi-cloudevents"
    },
    "split_keywords": [
        "fastapi",
        "cloudevents[pydantic]",
        "ce",
        "cloud",
        "events",
        "event",
        "middleware",
        "rest",
        "rest-api",
        "plugin",
        "pydantic",
        "fastapi-extension"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "3d425f0b74272891b739b0f7347d128c7d4abbc46feb22d8a53dc8ee0e6e5993",
                "md5": "ab37102333b1366d0d258ee7dfd2a8ab",
                "sha256": "d069705203756df592fb8d7151519ac57b386ce26e42421f4f0b61bfc37f6abf"
            },
            "downloads": -1,
            "filename": "fastapi_cloudevents-2.0.2-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "ab37102333b1366d0d258ee7dfd2a8ab",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": null,
            "size": 16596,
            "upload_time": "2024-02-24T19:52:04",
            "upload_time_iso_8601": "2024-02-24T19:52:04.642216Z",
            "url": "https://files.pythonhosted.org/packages/3d/42/5f0b74272891b739b0f7347d128c7d4abbc46feb22d8a53dc8ee0e6e5993/fastapi_cloudevents-2.0.2-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "1b6e21bb3a8ca082fa952fe7278ad7ce05c8e8c8a04e61a150d13313c291d55b",
                "md5": "393c52b682ca3a0155f030abcb3916f4",
                "sha256": "0e07d56caa39d829c63bdafb2bfead8795c678c293680e1142de14979275416f"
            },
            "downloads": -1,
            "filename": "fastapi-cloudevents-2.0.2.tar.gz",
            "has_sig": false,
            "md5_digest": "393c52b682ca3a0155f030abcb3916f4",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 14161,
            "upload_time": "2024-02-24T19:52:18",
            "upload_time_iso_8601": "2024-02-24T19:52:18.218194Z",
            "url": "https://files.pythonhosted.org/packages/1b/6e/21bb3a8ca082fa952fe7278ad7ce05c8e8c8a04e61a150d13313c291d55b/fastapi-cloudevents-2.0.2.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-02-24 19:52:18",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "sasha-tkachev",
    "github_project": "fastapi-cloudevents",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [],
    "tox": true,
    "lcname": "fastapi-cloudevents"
}
        
Elapsed time: 0.43118s