async def emit_delete_event(row_id: str, table_name: str) -> dict: env = config.env logger = get_logger("sens-o-matic") if env == "local": return None try: event_id = str(uuid.uuid4()) payload = { "cloud_environment": env, "row_id": row_id, "table_name": table_name } event = { "id": event_id, "source": "prefect_server", "type": "delete", "payload": payload, } result = await sens_o_matic_httpx_client.post( "https://sens-o-matic.prefect.io/", json=event, headers={"X-PREFECT-EVENT": "prefect_server-0.0.1"}, timeout=10, ) logger.debug("Delete event sent to sens-o-matic: %s", str(result)) except Exception as e: # Log the information that we were trying to send to sens-o-matic so Dylan can backfill logger.error("Error during attempt to send event to sens-o-matic: %s", str(event)) logger.error(e) return event
async def test_logs_exception_information(self, caplog): with pytest.raises(APIError): async with reraise_as_api_error(Exception, logger=get_logger()): raise ValueError("Test error") assert caplog.records log = caplog.records[0] # Exc info attached assert "ValueError: Test error" in log.exc_text # Message includes original error message assert log.message == "Encountered internal API exception: Test error" # Logs as error assert log.levelname == "ERROR"
from pathlib import Path import uvicorn from ariadne import load_schema_from_path, make_executable_schema from ariadne.asgi import GraphQL from starlette.applications import Starlette from starlette.requests import Request from starlette.responses import JSONResponse import prefect_server from prefect_server.utilities.graphql import mutation, query from prefect_server.graphql import scalars from prefect_server.utilities import context from prefect_server.utilities.logging import get_logger logger = get_logger("GraphQL Server") sdl = load_schema_from_path(Path(__file__).parents[2] / "graphql" / "schema") schema = make_executable_schema(sdl, query, mutation, *scalars.resolvers) path = prefect_server.config.services.graphql.path or "/" if not path.endswith("/"): path += "/" # The interaction of how Starlette mounts the GraphQL app appears to result in # 404's when the path doesn't end in a trailing slash. This means GraphQL queries # must have a trailing slash if not path.endswith("/"): raise ValueError("GraphQL path must end with '/'")
# https://www.prefect.io/legal/prefect-community-license import asyncio from typing import Any, Dict, Iterable, List, Union from box import Box import prefect_server from prefect.utilities.graphql import EnumValue, parse_graphql, with_args from prefect_server import config from prefect_server.utilities import context, exceptions from prefect_server.utilities.graphql import GraphQLClient from prefect_server.utilities.logging import get_logger GQLObjectTypes = Union[None, str, Dict, Iterable] logger = get_logger("Hasura") class Variable: def __init__(self, name: str, type: str, value: Any): self.name = name self.type = type self.value = value def __str__(self) -> str: return f"${self.name}" def __repr__(self) -> str: return f"<GraphQL Variable: {self.name}>" def __hash__(self) -> int:
import inspect import textwrap import traceback from typing import Any from ariadne.types import Extension from graphql import GraphQLResolveInfo from prefect_server import config from prefect_server.utilities import context, logging logger = logging.get_logger("GraphQL") def log_error(exc: Exception) -> None: ctx = context.get_context() ctx.pop("auth_token", None) if config.env == "local": logger.error( textwrap.dedent(f""" An application error occurred: ### --- Error ------------------------------ {textwrap.indent(traceback.format_exc(), " ")} ### --- Context ------------------------------ {textwrap.indent(str(ctx), " ")} """))
# https://www.prefect.io/legal/prefect-community-license import asyncio import uuid import pendulum from box import Box import prefect from prefect import api, models from prefect.engine.state import Cancelled, Cancelling, State from prefect.utilities.plugins import register_api from prefect_server.utilities import events from prefect_server.utilities.logging import get_logger logger = get_logger("api") state_schema = prefect.serialization.state.StateSchema() @register_api("states.set_flow_run_state") async def set_flow_run_state(flow_run_id: str, state: State, version: int = None, agent_id: str = None) -> models.FlowRunState: """ Updates a flow run state. Args: - flow_run_id (str): the flow run id to update - state (State): the new state
import json import uuid from typing import List import httpx from box import Box import prefect from prefect import api, models from prefect.utilities.plugins import register_api from prefect_server import config as server_config from prefect_server.utilities import events, logging, names cloud_hook_httpx_client = httpx.AsyncClient() logger = logging.get_logger("cloud_hooks") CLOUD_HOOK_TYPES = { "WEBHOOK", "SLACK_WEBHOOK", "PREFECT_MESSAGE", "TWILIO", "PAGERDUTY", } ALL_STATES = [ s.__name__.upper() for s in prefect.engine.state.State.children() ] @register_api("cloud_hooks.create_cloud_hook") async def create_cloud_hook(
import datetime import uuid from typing import Any, Dict, List import pendulum from packaging import version as module_version from pydantic import BaseModel, Field, validator from prefect import api, models from prefect.serialization.schedule import ScheduleSchema from prefect.utilities.graphql import with_args from prefect.utilities.plugins import register_api from prefect_server import config from prefect_server.utilities import logging logger = logging.get_logger("api.flows") schedule_schema = ScheduleSchema() # ----------------------------------------------------- # Schema for deserializing flows # ----------------------------------------------------- class Model(BaseModel): class Config: # allow extra fields in case schema changes extra = "allow" class ClockSchema(Model): parameter_defaults: Dict = Field(default_factory=dict)
def __init__(self, loop_interval=None): self.loop_interval = loop_interval or 0.25 self.logger = logging.get_logger(__name__)