[−][src]Module algorithmia::entrypoint
Algorithmia entrypoint for authoring Rust-based algorithms
This module contains the traits that are used for defining the entrypoint of a rust-based algorithm on the Algorithmia platform.
Rust algorithms are loaded by instantiating an Algo
type via Algo::default()
and each API request invokes the apply
method on that instance.
While it is possible to manually define the Algo
type and implement
either EntryPoint
or DecodedEntryPoint
, the #[entrypoint]
attribute will generate these implementations for you based on the signature
of the function (or impl) that it is attached to.
#[entrypoint]
Usage
Just annotate a function with #[entrypoint]
#[entrypoint]
fn apply(name: String) -> Result<String, String> {
Ok(format!("Hello, {}.", name))
}
This will generate the algorithm entrypoint as long the function signature specifices supported input and output types:
Supported input types:
- String types (e.g.
&str
andString
) - Byte types (e.g.
&[u8]
andVec<u8>
) - Json
&Value
type AlgoIo
enum type (for matching on text, json, and binary input)- Any type that implements
serde::Deserialize
(e.g.#[derive(Deserialize)]
)
Supported output (Ok
variant of return value):
String
,Vec<u8>
,Value
,AlgoIo
- Any type that implements
serde::Serialize
(e.g.#[derive(Serialize)]
)
Supported error types (Err
variant of return value):
- Any type with a conversion to
Box<std::error::Error>
. This includesString
and basically any type that implements theError
trait.
Automatic JSON serialization/deserialization
Since #[entrypoint]
supports Deserialize
input and Serialize
output, this example will
accept a JSON array and return a JSON number:
#[entrypoint]
fn start(names: Vec<String>) -> Result<usize, String> {
Ok(name.len())
}
To use your own custom types as input and output, simply implement Deserialize
and
Serialize
respectively.
#[derive(Deserialize)
struct Input { titles: Vec<String> }
#[derive(Serialize)
struct Output { count: u32 }
#[entrypoint]
fn start(input: Input) -> Result<Output, String> {
Ok(Output{ count: input.titles.len() })
}
Preloading (advanced usage)
If your algorithm has a preload step that doesn't vary with user input (e.g. loading a model),
you can create a type that implements Default
, and use a method on that type as your
entrypoint (the #[entrypoint]
annotation goes on the impl of your type. Multiple API calls in
succession from a single user will only instantiate the type once, but call apply
multiple
times:
#[derive(Deserialize)
struct Input { titles: Vec<String>, max: u32 }
#[derive(Serialize)
struct Output { titles: Vec<String> }
struct App { model: Vec<u8> }
#[entrypoint]
impl App {
fn apply(&mut self, input: Input) -> Result<Output, String> {
unimplemented!();
}
}
impl Default for App {
fn default() -> Self {
App { model: load_model() }
}
}
Traits
DecodedEntryPoint | Alternate implementation for |
EntryPoint | Implementing an algorithm involves overriding at least one of these methods |