tungsten-leads
Leads plugin for Tungsten, the admin panel for FastAPI.
What you get
- Leads list with stages (New, Contacted, Qualified, Proposal sent, Won, Lost), source, owner, deal value and next follow-up.
- Tabs for My leads, Follow-up due, New and Won; filters; search; export to CSV or Excel.
- Bulk actions: assign to a user, mark won, mark lost, delete.
- A timeline on each lead for notes, calls, emails and messages.
- Lead fields: admins add their own form fields (text, number, date, dropdown, checkboxes, yes/no...) from the panel, without code. Values are saved on the lead.
- Dashboard numbers: total, new this week, follow-ups due, won and win rate.
- Optional website form API: POST leads to
<panel>/api/leads.
Install
pip install tungsten-leads
from tungsten_leads import LeadsPlugin
panel.plugin(LeadsPlugin())
panel.create_tables(engine) # creates the leads tables too
Options
LeadsPlugin(
statuses={"new": ("New", "info"), "demo": ("Demo booked", "primary"), "won": ("Won", "success"), "lost": ("Lost", "danger")},
sources={"manual": "Added by hand", "website": "Website", "walk_in": "Walk-in"},
capture_token="long-random-text", # turns on the website form API
dashboard_widget=True,
)
Website form API
curl -X POST https://admin.example.com/admin/api/leads \
-H "X-Leads-Token: long-random-text" -H "Content-Type: application/json" \
-d '{"name": "Amit", "phone": "+91 98765 43210", "city": "Pune"}'
name, email, phone, company and notes go to the lead itself. Any other key is saved in the lead's extra
fields. Send an external_id (the row id in your own site's database) and the same lead is never added twice, so a
form that posts again is safe.
Use it from your code or other plugins
from tungsten_leads import add_activity, create_lead, find_lead, on_lead_created
lead = create_lead(db, name="Amit", phone="+919876543210", source="meta", external_id="meta-lead-id")
add_activity(db, lead, "Asked about the MBA course", type="call")
db.commit()
@on_lead_created
def welcome(db, lead):
... # send a WhatsApp message, an email...
create_lead skips a lead whose external_id is already saved, so the same Meta lead is never added twice.
Hooks for other plugins
leads = panel.get_plugin("leads")
leads.on_lead_created("my-plugin.welcome", lambda db, lead: ...) # only this panel's leads
leads.add_lead_action(lambda: Action("quote").label("Send quote").action(...)) # a button on every lead
leads.add_lead_bulk_action(lambda: BulkAction("tag").label("Tag").action(...)) # a bulk action
Metadata
Release files for tungsten-leads 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| tungsten_leads-0.1.1.tar.gz | 14.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| tungsten_leads-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 28.0 kB
Release files / tungsten_leads-0.1.1.tar.gz
| Download URL | tungsten_leads-0.1.1.tar.gz |
|---|---|
| Size | 14.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a97f1b1a2c8d455eda12a203ccbb43d5423c7db4820156538d97f158e8e6c937
|
|
BLAKE2b-256 checksum How to use checksums |
fae641a8a53d9deb4940ee103ef8339a1ffbbff0fbce87bae29c002e2d2e0cb4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Release files / tungsten_leads-0.1.1-py3-none-any.whl
| Download URL | tungsten_leads-0.1.1-py3-none-any.whl |
|---|---|
| Size | 14.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
1fd3fa3176e934024947f4f38e6f646b7338173f483eef5535d3fbf7deeed5be
|
|
BLAKE2b-256 checksum How to use checksums |
e950edf01d6d73deb47188e69529c6eb57b983c9777fea1ad81e47789f042a00
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|