Skip to main content

A framework for creating Frame apps in an intuitive and declarative manner

Project description

sufficient

A framework for creating Frame apps in an intuitive and declarative manner.

PyPI - Version PyPI - Python Version


Installation

pip install sufficient

Quick Start

Code snippets here are excerpted from gm-universe under repo frame-app-examples, you may also want to check it.

  1. Create a python project with a directory structure looks like this.
api
└── index.py
frame
├── app.py
├── static
│   ├── features.png
│   ├── home.png
│   ├── howitworks.png
│   ├── howitworks_deploy.png
│   ├── howitworks_programming.png
│   └── unexpected.png
└── templates
    ├── features.svg
    ├── features_casters.svg
    ├── features_chaindata.svg
    └── features_reactions.svg
  1. Define your frame app in frame/app.py.
from sufficient.frames import *


class App:
    name = "GM Universe"
    description = "Greetings from your first frame app using sufficient-py"
    image = "{uri}/static/home.png"
    uri = "{uri}"
    start = "PageHome"


class PageHome:
    def view(self, action: Action, result: ActionResult):
        return ImageFile("home.png")

    def btn_explore(self, action: Action):
        return "PageFeatures"


class PageFeatures:
    def view(self, action: Action, result: ActionResult):
        if "PageHome.btn_explore" == action.source:
            return ImageFile("features.png")
        elif "PageFeatures.btn_casters" == action.source:
            return SvgTemplate("features_casters.svg", result)
        elif "PageFeatures.btn_reactions" == action.source:
            return SvgTemplate("features_reactions.svg", result)
        elif "PageFeatures.btn_chain_data" == action.source:
            return SvgTemplate("features_chaindata.svg", result)
        else:
            return ImageFile("unexpected.png")

    def btn_casters(self, action: Action):
        c = FarcasterClient()
        users = c.neynar_get_users_bulk([action.actor, action.caster])
        actor_pfp = users[0]["pfp_url"]
        actor_name = users[0]["display_name"]
        caster_pfp = users[1]["pfp_url"]
        caster_name = users[1]["display_name"]
        return "PageFeatures", ActionResult(actor_name=actor_name,
                                            actor_pfp=actor_pfp,
                                            caster_name=caster_name,
                                            caster_pfp=caster_pfp)
  1. In api/index.py, create routes as endpoints of your frame server.
from flask import Flask, request, send_from_directory, redirect
import os
import io
import json
from sufficient.frames import FrameAppRunner
from frame import app as frame_app


app = Flask(__name__, instance_relative_config=True)

static_dir = os.path.abspath("frame/static")
templates_dir = os.path.abspath("frame/templates")
# data_dir = app.instance_path
data_dir = "/tmp/data"

runner = FrameAppRunner(frame_app, static_dir,
                        templates_dir, data_dir=data_dir)
try:
    os.makedirs(data_dir)
except OSError:
    pass


@app.route('/')
def frame_index():
    framelet = runner.start()
    return runner.gen_frame_html(framelet, request.host_url, og=True)


@app.route('/static/<string:path>')
def frame_static(path):
    return send_from_directory(static_dir, path)


@app.route('/view/<string:path>')
def frame_image(path):
    return send_from_directory(data_dir, path)


@app.route('/<string:page>/click', methods=['POST'])
def frame_click(page):
    tag, value = runner.click(page, request.json)
    if tag == "framelet":
        return runner.gen_frame_html(value, request.host_url)
    elif tag == "redirection":
        return redirect(value, code=302)
  1. Run your app locally for testing
python3 -m venv venv
source venv/bin/activate
pip install sufficient flask
python -m flask --app api.index run
  1. Use ngrok to make your local server publically accessible
ngrok http http://localhost:5000
  1. Validate your frame app
  1. Deploy

The following instructions are assuming you are going to deploy on vercel. see https://vercel.com/docs/functions/serverless-functions/runtimes/python for more info.

create vercel.json with content:

{
  "rewrites": [{ "source": "/(.*)", "destination": "/api/index" }]
}
vercel deploy

License

sufficient is distributed under the terms of the MIT license.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sufficient-0.1.1.tar.gz (12.5 kB view details)

Uploaded Source

Built Distribution

sufficient-0.1.1-py3-none-any.whl (10.3 kB view details)

Uploaded Python 3

File details

Details for the file sufficient-0.1.1.tar.gz.

File metadata

  • Download URL: sufficient-0.1.1.tar.gz
  • Upload date:
  • Size: 12.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: python-httpx/0.26.0

File hashes

Hashes for sufficient-0.1.1.tar.gz
Algorithm Hash digest
SHA256 e3ef583209d2c4e531f8687c584ec4d3c83dd13f02f4d82fe14280be989ed7cb
MD5 9ed8fcb136b220cb05c8a6448dd59ff7
BLAKE2b-256 c43841eafb6e0f351b7b65e9c1dd79845139c6c82dc4c6d7ecc1201d823f41bd

See more details on using hashes here.

File details

Details for the file sufficient-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: sufficient-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 10.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: python-httpx/0.26.0

File hashes

Hashes for sufficient-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 66416721c3901f91ffdc3128e36ccefd424e09c5e6f3992e8006aecad071c0d3
MD5 c4b59c217626638616e5f195e521a147
BLAKE2b-256 f9fd091dfa9a82d33d65c2f098aa8ab8fa750e40b5f25e96fd3f7e320d6fd106

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page