Guide

Getting Started

This guide will teach you how to get started with deploying an app to Orrin Apps. It covers the Orrin CLI, the Orrin SDK, and the nuances of developing a standalone app.

Prerequisites

The first step is ensuring you have the correct, and up to date, packages installed.

1. Install Orrin CLI

pip3 install orrin-cli

2. Python SDK (Backend)

pip3 install orrin-sdk

3. Next.js SDK (Frontend)

npm install @orrin-apps/sdk

Configuration

Once installed, configure the CLI with your developer API key and email address for correspondence. Run the following command:

orrin config configure-dev

This command prompts you to enter your email and confirm it, then enter your Developer API Key.

Developer Account

A developer API key can be received in the Orrin Dashboard. If you do not have a developer account, you will be prompted to create one.

When you create a developer account, it’s automatically linked to your Orrin account. Your Orrin username will be displayed on your app’s marketplace listing and used to identify your developer status, granting access to the developer portal.

Cost: $2.99/month (Covers hosting & caching)

Architecture Note

Orrin Apps keeps the backend and frontend separate. All communication between your UI and the backend logic is handled by Stellr's servers.

An app is created upon a backend submission. You must submit a backend first. Without a backend, the UI is "stateless" and cannot be linked.

Step 1 Submit Backend
Step 2 Link Frontend
Logic

The Backend

Orrin Apps utilizes Python for all backend functionality. Functions exposed to the frontend are called actions. The Orrin SDK enforces an allowlist of libraries to ensure security and stability.

Allowed Libraries

openai
requests
json
datetime
math
numpy
pandas
beautifulsoup
pydantic
pillow
nltk
tiktoken
anthropic
google-generativeai
orrinsdk

Initialization

Import the OrrinSDK class and create an instance. The constructor takes 3 required arguments:

Argument Type Description
developer_api_key str Your Developer API key from the dashboard.
app_name str Unique name of the app. No spaces allowed.
desc str A brief (1-sentence) description.
from orrinsdk import OrrinSDK

orrin_sdk = OrrinSDK(
    developer_api_key='<your_api_key>',
    app_name='<YourAppName>',
    desc='<DescriptionOfYourApp>'
)

Registering Actions

Use the @action decorator to register a function. The action name determines the entrypoint and must match the function name.

Argument Type Description
name str Required. Must explicitly match function name.
required_payload list List of dicts defining arguments (if no default value).
extra_metadata dict Optional context dictionary.

Defining Payload Schema

# Structure for required_payload list items:
{
    "name": "<argument_name>",
    "type": "<argument_type>" # Use "any" for no restrictions
}

Example Action Registration

# Assuming orrin_sdk is initialized

@orrin_sdk.action('test')
def test():
    return {"Message": "Done!"}

Example Action Registration with Arguments

# Assuming orrin_sdk is initialized

@orrin_sdk.action(
    'test',
    required_payload=[{"name": "a", "type": "any"}]
)
def test(a):
    return {"Message": f"{a}"}

Example Action Registration with Extra Metadata

# Assuming orrin_sdk is initialized

@orrin_sdk.action(
    'test',
    required_payload=[{"name": "a", "type": "any"}],
    extra_metadata={"usage": "use for testing"}
)
def test(a):
    return {"Message": f"{a}"}

* Actions must return a Python dictionary.

Finalizing

Code execution happens in the abstract until you invoke finalize(). This method bundles your configuration and sends it to the server. Add this to the very end of your script.

orrin_sdk.finalize()

Upon success, you will receive an App ID. Keep this safe! You will need it to link your Frontend.

Interface

The Frontend

Orrin Apps utilizes Next.js as the frontend framework. The Next.js SDK provides an OrrinProvider to handle authentication and API communication.

Step 1: Create Client

Create a file (e.g., client.ts) to initialize your Orrin Client.

import { OrrinClient } from "@orrin-apps/sdk"

export const client = new OrrinClient({
    apiKey: "<your_api_key>",
    appID: "<app_id>" // The App ID received after uploading backend
});

Step 2: Create Providers Wrapper

Since OrrinProvider utilizes context, create a client-side wrapper (e.g., providers.tsx).

"use client";

import { OrrinProvider } from "@orrin-apps/sdk";
import { client } from "./client";

export function Providers({ children }: { children: React.ReactNode }) {
  return (
    <OrrinProvider client={client}>
      {children}
    </OrrinProvider>
  );
}

Step 3: Update Layout

Wrap your application in layout.tsx.

import { Providers } from "./providers";

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="en">
      <body>
        <Providers>{children}</Providers>
      </body>
    </html>
  );
}

Using Actions

To call backend functions, use the useAction hook. It returns an execution function and a loading state.

Hook Return Values
  • execute: Function to trigger action & pass payload.
  • loading: Boolean state for UI feedback.
// Inside a component
const { execute, loading } = useAction("test");

// Execution example
const response = execute({"a": "test!"});

Full Component Example*

// Example usage
export default function Home() {
  const { execute, loading } = useAction(
    "test"
  );
  const [toShow, setToShow] = useState<string>("");

  useEffect(() => {
    const d = async () => {
      try {
        const b = await execute({
          "a": "lol"
        });

        setToShow(b.result["message"]);

      } catch (e) {
        alert(e);
      }
    }

    d()
  }, []);

  return (<p>{toShow}</p>)
}

* You do not need to name the destructured variables from useAction as they are seen in the example. Apply your naming convention to the variables so you know what they do.

The response will be wrapped in a result object: { "result": { ...your_backend_return } }.

If the backend has not been authorized, execute will return a 400 response with backend_not_authorized as the message.

Deployment

Next.Config.ts Requirement

Your next.config.ts file must be configured for static export with a specific base path matching your App Name.

const nextConfig = {
  output: 'export',
  trailingSlash: true,
  basePath: '/<YourAppName>/current', // Must match Backend App Name
  reactStrictMode: true,
};

module.exports = nextConfig;

1. Generate ZIP

From the root of your Next.js directory, run:

orrin ui generate-zip

This builds the project, exports it, and zips the static content.

2. Upload & Link

Upload the UI and link it to the app created by your backend code:

orrin ui upload --app <AppName>