Skip to content

Commit

Permalink
SETUP EventType support
Browse files Browse the repository at this point in the history
  • Loading branch information
pcanto-hopeit committed Feb 21, 2024
1 parent ee292a7 commit f64a671
Show file tree
Hide file tree
Showing 8 changed files with 460 additions and 250 deletions.
5 changes: 3 additions & 2 deletions apps/examples/client-example/api/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -635,7 +635,8 @@
"POST",
"STREAM",
"SERVICE",
"MULTIPART"
"MULTIPART",
"SETUP"
],
"x-enum-name": "EventType",
"x-module-name": "hopeit.app.config"
Expand Down Expand Up @@ -704,7 +705,7 @@
}
},
"x-module-name": "hopeit.app.config",
"description": "\n Event Descriptor: configures event implementation\n\n :field: type, EventType: type of event i.e.: GET, POST, MULTIPART, STREAM, SERVICE\n :field: plug_mode, EventPlugMode: defines whether an event defined in a plugin is created in the\n current app (ON_APP) or it will be created in the original plugin (STANDALONE, default)\n :field: route, optional str: custom route for endpoint. If not specified route will be derived\n from `/api/app_name/app_version/event_name`\n :field: impl, optional str: custom event implementation Python module. If not specified, module\n with same same as event will be imported.\n :field: connections, list of EventConnection: specifies dependencies on other apps/endpoints,\n that can be used by client plugins to call events on external apps\n :field: read_stream, optional ReadStreamDescriptor: specifies source stream to read from.\n Valid only for STREAM events.\n :field: write_stream, optional WriteStreamDescriptor: for any type of events, resultant dataobjects will\n be published to the specified stream.\n :field: auth, list of AuthType: supported authentication schemas for this event. If not specified\n application default will be used.\n :field: setting_keys, list of str: by default EventContext will have access to the settings section\n with the same name of the event using `settings = context.settings(datatype=MySettingsType)`.\n In case additional sections are needed to be accessed from\n EventContext, then a list of setting keys, including the name of the event if needed,\n can be specified here. Then access to a `custom` key can be done using\n `custom_settings = context.settings(key=\"customer\", datatype=MyCustomSettingsType)`\n :field: dataobjects, list of str: list of full qualified dataobject types that this event can process.\n When not specified, the engine will inspect the module implementation and find all datatypes supported\n as payload in the functions defined as `__steps__`. In case of generic functions that support\n `payload: DataObject` argument, then a list of full qualified datatypes must be specified here.\n :field: group, str: group name, if none is assigned it is automatically assigned as 'DEFAULT'.\n "
"description": "\n Event Descriptor: configures event implementation\n\n :field: type, EventType: type of event i.e.: GET, POST, MULTIPART, STREAM, SERVICE, SETUP\n :field: plug_mode, EventPlugMode: defines whether an event defined in a plugin is created in the\n current app (ON_APP) or it will be created in the original plugin (STANDALONE, default)\n :field: route, optional str: custom route for endpoint. If not specified route will be derived\n from `/api/app_name/app_version/event_name`\n :field: impl, optional str: custom event implementation Python module. If not specified, module\n with same same as event will be imported.\n :field: connections, list of EventConnection: specifies dependencies on other apps/endpoints,\n that can be used by client plugins to call events on external apps\n :field: read_stream, optional ReadStreamDescriptor: specifies source stream to read from.\n Valid only for STREAM events.\n :field: write_stream, optional WriteStreamDescriptor: for any type of events, resultant dataobjects will\n be published to the specified stream.\n :field: auth, list of AuthType: supported authentication schemas for this event. If not specified\n application default will be used.\n :field: setting_keys, list of str: by default EventContext will have access to the settings section\n with the same name of the event using `settings = context.settings(datatype=MySettingsType)`.\n In case additional sections are needed to be accessed from\n EventContext, then a list of setting keys, including the name of the event if needed,\n can be specified here. Then access to a `custom` key can be done using\n `custom_settings = context.settings(key=\"customer\", datatype=MyCustomSettingsType)`\n :field: dataobjects, list of str: list of full qualified dataobject types that this event can process.\n When not specified, the engine will inspect the module implementation and find all datatypes supported\n as payload in the functions defined as `__steps__`. In case of generic functions that support\n `payload: DataObject` argument, then a list of full qualified datatypes must be specified here.\n :field: group, str: group name, if none is assigned it is automatically assigned as 'DEFAULT'.\n "
},
"EventConnection": {
"type": "object",
Expand Down
5 changes: 3 additions & 2 deletions apps/examples/simple-example/api/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -1933,7 +1933,8 @@
"POST",
"STREAM",
"SERVICE",
"MULTIPART"
"MULTIPART",
"SETUP"
],
"x-enum-name": "EventType",
"x-module-name": "hopeit.app.config"
Expand Down Expand Up @@ -2002,7 +2003,7 @@
}
},
"x-module-name": "hopeit.app.config",
"description": "\n Event Descriptor: configures event implementation\n\n :field: type, EventType: type of event i.e.: GET, POST, MULTIPART, STREAM, SERVICE\n :field: plug_mode, EventPlugMode: defines whether an event defined in a plugin is created in the\n current app (ON_APP) or it will be created in the original plugin (STANDALONE, default)\n :field: route, optional str: custom route for endpoint. If not specified route will be derived\n from `/api/app_name/app_version/event_name`\n :field: impl, optional str: custom event implementation Python module. If not specified, module\n with same same as event will be imported.\n :field: connections, list of EventConnection: specifies dependencies on other apps/endpoints,\n that can be used by client plugins to call events on external apps\n :field: read_stream, optional ReadStreamDescriptor: specifies source stream to read from.\n Valid only for STREAM events.\n :field: write_stream, optional WriteStreamDescriptor: for any type of events, resultant dataobjects will\n be published to the specified stream.\n :field: auth, list of AuthType: supported authentication schemas for this event. If not specified\n application default will be used.\n :field: setting_keys, list of str: by default EventContext will have access to the settings section\n with the same name of the event using `settings = context.settings(datatype=MySettingsType)`.\n In case additional sections are needed to be accessed from\n EventContext, then a list of setting keys, including the name of the event if needed,\n can be specified here. Then access to a `custom` key can be done using\n `custom_settings = context.settings(key=\"customer\", datatype=MyCustomSettingsType)`\n :field: dataobjects, list of str: list of full qualified dataobject types that this event can process.\n When not specified, the engine will inspect the module implementation and find all datatypes supported\n as payload in the functions defined as `__steps__`. In case of generic functions that support\n `payload: DataObject` argument, then a list of full qualified datatypes must be specified here.\n :field: group, str: group name, if none is assigned it is automatically assigned as 'DEFAULT'.\n "
"description": "\n Event Descriptor: configures event implementation\n\n :field: type, EventType: type of event i.e.: GET, POST, MULTIPART, STREAM, SERVICE, SETUP\n :field: plug_mode, EventPlugMode: defines whether an event defined in a plugin is created in the\n current app (ON_APP) or it will be created in the original plugin (STANDALONE, default)\n :field: route, optional str: custom route for endpoint. If not specified route will be derived\n from `/api/app_name/app_version/event_name`\n :field: impl, optional str: custom event implementation Python module. If not specified, module\n with same same as event will be imported.\n :field: connections, list of EventConnection: specifies dependencies on other apps/endpoints,\n that can be used by client plugins to call events on external apps\n :field: read_stream, optional ReadStreamDescriptor: specifies source stream to read from.\n Valid only for STREAM events.\n :field: write_stream, optional WriteStreamDescriptor: for any type of events, resultant dataobjects will\n be published to the specified stream.\n :field: auth, list of AuthType: supported authentication schemas for this event. If not specified\n application default will be used.\n :field: setting_keys, list of str: by default EventContext will have access to the settings section\n with the same name of the event using `settings = context.settings(datatype=MySettingsType)`.\n In case additional sections are needed to be accessed from\n EventContext, then a list of setting keys, including the name of the event if needed,\n can be specified here. Then access to a `custom` key can be done using\n `custom_settings = context.settings(key=\"customer\", datatype=MyCustomSettingsType)`\n :field: dataobjects, list of str: list of full qualified dataobject types that this event can process.\n When not specified, the engine will inspect the module implementation and find all datatypes supported\n as payload in the functions defined as `__steps__`. In case of generic functions that support\n `payload: DataObject` argument, then a list of full qualified datatypes must be specified here.\n :field: group, str: group name, if none is assigned it is automatically assigned as 'DEFAULT'.\n "
},
"EventConnection": {
"type": "object",
Expand Down
4 changes: 4 additions & 0 deletions apps/examples/simple-example/config/app-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@
}
},
"events": {
"setup_something": {
"type": "SETUP",
"setting_keys": ["fs_storage"]
},
"list_somethings": {
"type": "GET",
"setting_keys": ["fs_storage"]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,29 @@
--------------------------------------------------------------------
Creates and publish Something object every 10 seconds
"""

import asyncio
import random

import os
from hopeit.app.context import EventContext
from hopeit.app.events import Spawn, service_running
from hopeit.app.logger import app_extra_logger

from model import Something, User, SomethingParams

__steps__ = ['create_something']
__steps__ = ["create_something"]

logger, extra = app_extra_logger()


async def __service__(context: EventContext) -> Spawn[SomethingParams]:
i = 1
if not os.path.exists("/tmp/hopeit.initializead"):
raise RuntimeError(
"Missing /tmp/hopeit.initializead file. "
"Service will not start until run setup_something."
)
os.remove("/tmp/hopeit.initializead")
while service_running(context):
logger.info(context, f"Generating something event {i}...")
yield SomethingParams(f"id{i}", f"user{i}")
Expand All @@ -27,13 +34,14 @@ async def __service__(context: EventContext) -> Spawn[SomethingParams]:
logger.info(context, "Service seamlessly exit")


async def create_something(payload: SomethingParams, context: EventContext) -> Something:
logger.info(context, "Creating something...", extra=extra(
payload_id=payload.id, user=payload.user
))
result = Something(
id=payload.id,
user=User(id=payload.user, name=payload.user)
async def create_something(
payload: SomethingParams, context: EventContext
) -> Something:
logger.info(
context,
"Creating something...",
extra=extra(payload_id=payload.id, user=payload.user),
)
result = Something(id=payload.id, user=User(id=payload.user, name=payload.user))
await asyncio.sleep(random.random() * 5.0)
return result
24 changes: 24 additions & 0 deletions apps/examples/simple-example/src/simple_example/setup_something.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
"""
Simple Example: Setup Something
--------------------------------------------------------------------
Setup run before initialize endpoints streams and services
"""

from pathlib import Path

from hopeit.app.context import EventContext
from hopeit.app.logger import app_extra_logger


__steps__ = ["run_once"]


logger, extra = app_extra_logger()


async def run_once(payload: None, context: EventContext):
"""
Load objects that match the given wildcard
"""
logger.info(context, "Setup done")
Path("/tmp/hopeit.initializead").touch()
4 changes: 3 additions & 1 deletion engine/src/hopeit/app/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,14 @@ class EventType(str, Enum):
STREAM: event triggered read events from stream. Can be started and stopped.
SERVICE: event executed on demand or continuously. Long lived. Can be started and stopped.
MULTIPART: event triggered from api postform-multipart request via endpoint.
SETUP: event that is executed once when service is starting
"""
GET = 'GET'
POST = 'POST'
STREAM = 'STREAM'
SERVICE = 'SERVICE'
MULTIPART = 'MULTIPART'
SETUP = 'SETUP'


class StreamQueue:
Expand Down Expand Up @@ -299,7 +301,7 @@ class EventDescriptor:
"""
Event Descriptor: configures event implementation
:field: type, EventType: type of event i.e.: GET, POST, MULTIPART, STREAM, SERVICE
:field: type, EventType: type of event i.e.: GET, POST, MULTIPART, STREAM, SERVICE, SETUP
:field: plug_mode, EventPlugMode: defines whether an event defined in a plugin is created in the
current app (ON_APP) or it will be created in the original plugin (STANDALONE, default)
:field: route, optional str: custom route for endpoint. If not specified route will be derived
Expand Down

0 comments on commit f64a671

Please sign in to comment.