Skip to content

Commit

Permalink
feat(sub): sdk and typing (#811)
Browse files Browse the repository at this point in the history
User side of substantial

#### Migration notes

None

- [ ] The change comes with new or modified tests
- [ ] Hard-to-understand functions have explanatory comments
- [ ] End-user documentation is updated to reflect the change
  • Loading branch information
michael-0acf4 authored Aug 18, 2024
1 parent 54b487d commit 58d220f
Show file tree
Hide file tree
Showing 23 changed files with 1,195 additions and 418 deletions.
4 changes: 4 additions & 0 deletions .ghjk/deno.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions libs/common/src/typegraph/runtimes/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use std::path::PathBuf;

use indexmap::IndexMap;
use serde::{Deserialize, Serialize};
use substantial::SubstantialRuntimeData;

use self::deno::DenoRuntimeData;
use self::graphql::GraphQLRuntimeData;
Expand All @@ -25,6 +26,7 @@ pub mod prisma;
pub mod python;
pub mod random;
pub mod s3;
pub mod substantial;
pub mod temporal;
pub mod wasm;

Expand Down Expand Up @@ -55,6 +57,7 @@ pub enum KnownRuntime {
WasmWire(WasmRuntimeData),
Typegate(TypegateRuntimeData),
Typegraph(TypegraphRuntimeData),
Substantial(SubstantialRuntimeData),
Kv(KvRuntimeData),
}

Expand Down Expand Up @@ -88,6 +91,7 @@ impl TGRuntime {
KnownRuntime::WasmReflected(_) => "wasm_reflected",
KnownRuntime::Typegate(_) => "typegate",
KnownRuntime::Typegraph(_) => "typegraph",
KnownRuntime::Substantial(_) => "substantial",
KnownRuntime::Kv(_) => "kv",
},
TGRuntime::Unknown(UnknownRuntime { name, .. }) => name,
Expand Down
26 changes: 26 additions & 0 deletions libs/common/src/typegraph/runtimes/substantial.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright Metatype OÜ, licensed under the Elastic License 2.0.
// SPDX-License-Identifier: Elastic-2.0

use std::path::PathBuf;

use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct SubstantialRuntimeData {
pub endpoint: String,
pub basic_auth_secret: Option<String>,
}

#[derive(Serialize, Deserialize, Clone, Debug)]
#[serde(rename_all = "lowercase")]
pub enum WorkflowKind {
Python,
}

#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct WorkflowMatData {
pub name: String,
pub file: String,
pub kind: WorkflowKind,
pub deps: Vec<PathBuf>,
}
12 changes: 12 additions & 0 deletions libs/metagen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ mod config;
mod mdk;
mod mdk_python;
mod mdk_rust;
mod mdk_substantial;
mod mdk_typescript;

#[cfg(test)]
mod tests;
mod utils;
Expand Down Expand Up @@ -133,6 +135,16 @@ impl GeneratorRunner {
},
},
),
(
"mdk_substantial".to_string(),
GeneratorRunner {
op: |workspace_path: &Path, val| {
let config = mdk_substantial::MdkSubstantialGenConfig::from_json(val, workspace_path)?;
let generator = mdk_substantial::Generator::new(config)?;
Ok(Box::new(generator))
},
},
),
(
"mdk_typescript".to_string(),
GeneratorRunner {
Expand Down
4 changes: 2 additions & 2 deletions libs/metagen/src/mdk_python/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ fn render_main(
context.insert("imports", &exports.join_compact(", ").to_string());

tera.render("main_template", &context)
.wrap_err("Failed to render main template")
.with_context(|| "Failed to render main template")
}

fn render_types(tera: &tera::Tera, required: &MergedRequiredObjects) -> anyhow::Result<String> {
Expand Down Expand Up @@ -252,7 +252,7 @@ fn render_types(tera: &tera::Tera, required: &MergedRequiredObjects) -> anyhow::
context.insert("funcs", &required.funcs);

tera.render("types_template", &context)
.context("Failed to render types template")
.with_context(|| "Failed to render types template")
}

fn gen_required_objects(
Expand Down
95 changes: 95 additions & 0 deletions libs/metagen/src/mdk_substantial/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// Copyright Metatype OÜ, licensed under the Mozilla Public License Version 2.0.
// SPDX-License-Identifier: MPL-2.0

// TODO: keyword filtering

use crate::interlude::*;
use crate::*;

#[derive(Serialize, Deserialize, Debug, garde::Validate)]
pub struct MdkSubstantialGenConfig {
#[serde(flatten)]
#[garde(dive)]
pub base: crate::config::MdkGeneratorConfigBase,
}

impl MdkSubstantialGenConfig {
pub fn from_json(json: serde_json::Value, workspace_path: &Path) -> anyhow::Result<Self> {
let mut config: MdkSubstantialGenConfig = serde_json::from_value(json)?;
config.base.path = workspace_path.join(config.base.path);
config.base.typegraph_path = config
.base
.typegraph_path
.as_ref()
.map(|path| workspace_path.join(path));
Ok(config)
}
}

pub struct Generator {
config: MdkSubstantialGenConfig,
}

impl Generator {
pub const INPUT_TG: &'static str = "tg_name";
pub fn new(config: MdkSubstantialGenConfig) -> Result<Self, garde::Report> {
use garde::Validate;
config.validate(&())?;
Ok(Self { config })
}
}

impl crate::Plugin for Generator {
fn bill_of_inputs(&self) -> HashMap<String, GeneratorInputOrder> {
[(
Self::INPUT_TG.to_string(),
if let Some(tg_name) = &self.config.base.typegraph_name {
GeneratorInputOrder::TypegraphFromTypegate {
name: tg_name.clone(),
}
} else if let Some(tg_path) = &self.config.base.typegraph_path {
GeneratorInputOrder::TypegraphFromPath {
path: tg_path.clone(),
name: self.config.base.typegraph_name.clone(),
}
} else {
unreachable!()
},
)]
.into_iter()
.collect()
}

fn generate(
&self,
// TODO: enable additionnal parameters for metagen
// For example: meta gen --params workflow-name=hello_world
_: HashMap<String, GeneratorInputResolved>,
) -> anyhow::Result<GeneratorOutput> {
let mut files = HashMap::new();
let base = self.config.base.path.clone();
files.insert(
base.join("substantial.py"),
GeneratedFile {
contents: include_str!("static/substantial.py").to_owned(),
overwrite: true,
},
);
files.insert(
base.join("types.py"),
GeneratedFile {
contents: include_str!("static/types.py").to_owned(),
overwrite: true,
},
);
files.insert(
base.join("workflow.py"),
GeneratedFile {
contents: include_str!("static/workflow.py").to_owned(),
overwrite: false,
},
);

Ok(GeneratorOutput(files))
}
}
33 changes: 33 additions & 0 deletions libs/metagen/src/mdk_substantial/static/substantial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
from datetime import timedelta
from typing import Any, Callable, Optional
from types import RetryStrategy


class Context:
async def save(
self,
f: Callable,
*,
timeout: Optional[timedelta] = None,
retry_strategy: Optional[RetryStrategy] = None,
):
pass

def handle(self, event_name: str, cb: Callable[[Any], Any]):
pass

async def ensure(self, f: Callable[[], bool]):
pass

async def sleep(self, duration: timedelta) -> Any:
pass

async def receive(name: str):
pass


def workflow():
def wrapper(f):
pass

return wrapper
9 changes: 9 additions & 0 deletions libs/metagen/src/mdk_substantial/static/types.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from dataclasses import dataclass
from typing import Union


@dataclass
class RetryStrategy:
max_retries: int
initial_backoff_interval: Union[int, None]
max_backoff_interval: Union[int, None]
7 changes: 7 additions & 0 deletions libs/metagen/src/mdk_substantial/static/workflow.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from substantial import workflow, Context # noqa
from substantial.types import RetryStrategy # noqa


@workflow()
def workflow_name(c: Context):
raise NotImplementedError
Loading

0 comments on commit 58d220f

Please sign in to comment.