Skip to main content

tungsten-hr

HR plugin for Tungsten, the admin panel for FastAPI.

What you get

  • Employees with a code (EMP-0007), job title, department, manager, type (full time, part time, contract, intern), status (active, on probation, on notice, left), joining date, birthday, salary, address, emergency contact, photo, documents and your own extra details (bank, PAN, Aadhaar...).
  • Departments with a head.
  • Attendance: one row per person per day (present, work from home, half day, absent, on leave, holiday), check-in and check-out times, hours worked and late marks.
  • A Check in / Check out button for each person who logs in to the panel. Short days become half days by themselves.
  • Biometric machines (eSSL, ZKTeco and others): the machine sends punches by itself (ADMS / Cloud server), the panel fetches them over the office network, or you send them by API or upload a CSV / Excel file. First punch is the check-in, last is the check-out.
  • Mark attendance for many people at once from the Employees list.
  • Leave requests with leave types (Casual, Sick, Earned...), days per year, half days, and balances (left, used, waiting).
  • Leave days skip weekends and holidays. Clashing requests and requests over the balance are stopped with a clear message.
  • Approve / Reject buttons (one by one or many at once). Approved days show as "On leave" in attendance.
  • The manager (or the department head) gets a bell note for each request. The employee gets a bell note and an email when it is approved or rejected.
  • Holidays list, with optional holidays.
  • Employee page with leave left this year and attendance this month, plus their attendance and leave tables.
  • Dashboard numbers: employees, at work today, on leave today, leave to approve.
  • Hooks so other plugins (payroll, WhatsApp, Slack...) can act on new employees and leave.

Install

pip install tungsten-hr
from tungsten_hr import HRPlugin

panel = Panel(..., auth=Auth(User, mailer=send_mail))
panel.plugin(HRPlugin())
panel.create_tables(engine)   # creates the HR tables too

To let a person check in and ask for leave, pick their panel login in the employee's Logs in as field.

Options

HRPlugin(
    weekend=(5, 6),               # days off: Monday is 0. (6,) for Sunday only
    late_after=time(9, 30),       # later check-ins are marked late. None: never late
    half_day_hours=4,             # fewer hours than this is a half day
    code_prefix="EMP-",
    email_employees=True,         # email people when their leave is approved or rejected
    notify=True,                  # bell notes for approvers and employees
    mailer=None,                  # defaults to Auth(mailer=...)
    navigation_group="HR",
    device_push=True,             # biometric machines send punches to /iclock/cdata
    auto_accept_devices=False,    # a new machine waits until you turn it on
    api_token=None,               # turns on POST <panel>/api/hr/punches
)

Biometric machines

Set each person's Machine ID (their user ID / PIN on the machine). Then use any of these:

  1. Machine sends punches: in the machine's Cloud Server / ADMS setting, put your site address (no /admin). It shows up under Biometric machines; turn it on.
  2. Panel fetches them over the office network: pip install "tungsten-hr[zk]", add the machine's IP, press Fetch punches (or run pull_all(db) from cron).
  3. API or file: POST <panel>/api/hr/punches with X-HR-Token, or Upload punches on the Punches screen.
curl -X POST https://hr.example.com/admin/api/hr/punches -H "X-HR-Token: long-secret" \
  -H "Content-Type: application/json" -d '{"punches": [{"employee": "EMP-0002", "time": "2026-11-02 09:12:00"}]}'

See the guide for the machine settings.

From code

from tungsten_hr import approve_leave, check_in, check_out, leave_balance, mark_attendance, request_leave

check_in(db, employee)                         # or check_out(db, employee)
mark_attendance(db, employee, date(2026, 11, 2), "absent")
request = request_leave(db, employee, leave_type, date(2026, 11, 2), date(2026, 11, 4), reason="Wedding")
approve_leave(db, request, user_id="1")
leave_balance(db, employee)                    # [{"name": "Casual", "allowed": 12, "used": 3, "left": 9, ...}]
db.commit()

request_leave raises LeaveError with a plain message when the leave can't be given.

Hooks

hr = panel.get_plugin("hr")
hr.on_employee_created("payroll", lambda db, employee: ...)
hr.on_leave_requested("slack", lambda db, request: ...)
hr.on_leave_decided("whatsapp", lambda db, request, old_status: ...)

Try it

pip install -e . -e plugins/hr uvicorn
uvicorn plugins.hr.example:app --reload

Sign in at http://127.0.0.1:8000/admin with admin@example.com / password. Sign in as rohit@example.com / password to see the employee side.

More Tungsten plugins

Package What it adds Docs
tungsten-tickets Help desk: tickets, replies, notes, SLA and a customer support page Guide
tungsten-leads Leads list, stages, timeline and your own lead form fields README
tungsten-blog Blog built for SEO, GEO and AEO, with a live score, sitemap and llms.txt Guide
tungsten-mcp MCP server, so AI assistants like Claude can read and change your data Guide
tungsten-finance Accounts like Tally or Zoho Books: GST invoices, bills, ledger, stock, P&L, balance sheet, GSTR-1/3B Guide

See all plugins.

Metadata

Release files for tungsten-hr 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for tungsten-hr 0.1.0
File Size Uploaded
tungsten_hr-0.1.0.tar.gz 32.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for tungsten-hr 0.1.0
File Interpreter ABI Platform
tungsten_hr-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 61.7 kB

Release files / tungsten_hr-0.1.0.tar.gz

Download URL tungsten_hr-0.1.0.tar.gz
Size 32.0 kB
Tags Source
SHA-256 checksum
How to use checksums
6a4ea4e8f68750e1a7d32701e4534c07d2d9e425c8e7be056370bf9df613d36b
BLAKE2b-256 checksum
How to use checksums
232ec1496418508e7f74e7aab9c4da14a8ea4c028967208ef44abf7e660d2a64
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Release files / tungsten_hr-0.1.0-py3-none-any.whl

Download URL tungsten_hr-0.1.0-py3-none-any.whl
Size 29.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4dd7caa2f10a3620be1cbd0652d2e24464a245101720964a70f2546ce3c124e6
BLAKE2b-256 checksum
How to use checksums
3dc487c2eaaa8ccb95e18197b4a7c839e2553fa0b0539fd90fda6f32eb7afbfd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page