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.
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.
- 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
- 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)
- 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)
- 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
- Use ngrok to make your local server publically accessible
ngrok http http://localhost:5000
- Validate your frame app
- 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)
Built Distribution
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
Algorithm | Hash digest | |
---|---|---|
SHA256 | e3ef583209d2c4e531f8687c584ec4d3c83dd13f02f4d82fe14280be989ed7cb |
|
MD5 | 9ed8fcb136b220cb05c8a6448dd59ff7 |
|
BLAKE2b-256 | c43841eafb6e0f351b7b65e9c1dd79845139c6c82dc4c6d7ecc1201d823f41bd |
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
Algorithm | Hash digest | |
---|---|---|
SHA256 | 66416721c3901f91ffdc3128e36ccefd424e09c5e6f3992e8006aecad071c0d3 |
|
MD5 | c4b59c217626638616e5f195e521a147 |
|
BLAKE2b-256 | f9fd091dfa9a82d33d65c2f098aa8ab8fa750e40b5f25e96fd3f7e320d6fd106 |