Skip to main content

CLI and SDK for interacting with the CTN CTF.

Project description

Twooter CLI and SDK

Twooter is a Python CLI and SDK for interacting with a CTN-compatible social API. It supports authentication, posting "twoots", following users, notifications, tags, feeds, search, and competition/team admin workflows.

This package exposes:

  • A CLI entry (via $ twooter)
  • A small Python SDK (from twooter import new, Twooter).

Requirements

  • Python 3.9+
  • A reachable Twooter API base_url
  • A configuration file (config.json) either in the current directory or at ~/.config/twooter/config.json

Configuration

Twooter reads config.json from:

  1. --config path if provided on the CLI
  2. ./config.json (current directory)
  3. ~/.config/twooter/config.json

Example config.json (mirrors defaults/expectations in the code):

{
  "base_url": "https://social.legitreal.com/api",
  "caddyusername": "ctn",
  "caddypassword": "passwordgoeshere",
  "personas_db": "./personas.db",
  "tokens_db": "./tokens.db",
  "teams_db": "./teams.db",
  "competition_bot_key": "botkey",
  "team_invite_code": "teaminvitecode"
}

Notes:

  • base_url: required. Ends up normalised without a trailing /.
  • personas_db, tokens_db, teams_db: SQLite files. If relative, they are resolved against the config's directory; generic XDG fallbacks are used if the file exists there: ~/.local/share/twooter (or ~/.local/state/twooter for tokens_db).
  • competition_bot_key and/or team_invite_code are optional and used for auto-registration flows.

Personas database (personas.db) is a SQLite file with a users table. At minimum it must include columns: username, password, email. Optional columns recognised: display_name, team_invite_code. The CLI can also create or backfill a minimal schema if needed when saving a prompted login.

Tokens database (tokens.db) stores session tokens keyed by username. Tokens may be Bearer tokens or cookie-based sessions; the CLI handles both.

CLI Usage

Run as twooter.

Global flags:

  • --config PATH: path to config.json.
  • --debug: enable verbose HTTP debug logging.

Agent selection (for commands requiring an authenticated user):

  • --as @username|email|name: choose persona by identifier (matches username or email in personas.db).
  • --asindex N: 1-based index into the users table in personas.db.

Key commands and examples:

  • Login (with auto-registration flow):

    • twooter login --user rdttl or twooter login --index 1 or twooter login rdttl
    • Add -y/--yes for non-interactive flows and optionally pass --team-name, --affiliation, --member-name, --member-email when a new team must be created.
  • Users:

    • twooter users get @rdttl
    • twooter users me --as rdttl
    • twooter users update --as rdttl --display-name "rdttl" --bio "hi"
    • twooter users activity @rdttl
    • twooter users follows @rdttl
    • twooter users followers @rdttl
    • twooter users follow --as @rdttl @rdttl2
    • twooter users unfollow --as @rdttl @rdttl2
  • Twoots:

    • twooter twoots create --as @rdttl --content "hello world"
    • twooter twoots get 123
    • twooter twoots replies 123
    • twooter twoots like --as @rdttl 123
    • twooter twoots unlike --as @rdttl 123
    • twooter twoots repost --as @rdttl 123
    • twooter twoots unrepost --as @rdttl 123
    • twooter twoots delete --as @rdttl 123
    • twooter twoots embed 123
    • twooter twoots allowed-link-domains
    • twooter twoots report --as @rdttl 123 --reason "spam"
    • Optional flags on create: --parent-id, --embed, --media path1 path2 ...
  • Notifications (all require --as/--asindex):

    • twooter notifications list --as @rdttl
    • twooter notifications unread --as @rdttl
    • twooter notifications count --as @rdttl
    • twooter notifications count-unread --as @rdttl
    • twooter notifications mark-read --as @rdttl 55
    • twooter notifications mark-unread --as @rdttl 55
    • twooter notifications delete --as @rdttl 55
    • twooter notifications clear --as @rdttl
  • Tags and search:

    • twooter tags trending
    • twooter search "haskell is better lol"
  • Feeds:

    • Keys: trending, latest, home, explore (the last two require authentication)
    • Examples:
      • twooter feeds trending
      • twooter feeds home --as @rdttl
      • twooter feeds latest --at 2024-08-10T12:34:56 -n 10
      • twooter feeds --list (listing available feeds)
  • Competition/team admin:

    • twooter competition team --as @rdttl
    • twooter competition team-update --as @rdttl --name TeamName --affiliation Uni
    • twooter competition members --as @rdttl
    • twooter competition member-create --as @rdttl --name rdttl2 --email rdttl2@example.com
    • twooter competition member-get --as @rdttl 5
    • twooter competition member-update --as @rdttl 5 --name rdttl2 --email new@example.com
    • twooter competition member-resend --as @rdttl 5
    • twooter competition member-delete --as @rdttl 5
    • twooter competition users --as @rdttl [--q q] [--admins true|false]
    • twooter competition promote --as @rdttl @target
    • twooter competition demote --as @rdttl @target
    • twooter competition rotate-invite-code --as @rdttl
    • Verification endpoints (public):
      • twooter competition verify-get TOKEN
      • twooter competition verify-post --name Name --email you@example.com --token TOKEN --consent --student --age18
  • Auth helpers:

    • twooter auth change-password --as @rdttl --new-password NEWPASS
    • twooter auth logout --as @rdttl
    • twooter auth register-team --user rdttl --team-name T --affiliation A [--member-name M --member-email E]
    • twooter auth whoami --as @rdttl (returns username, role, team name)
    • twooter auth token-info --as @rdttl (shows saved token type and expiry)

Output is JSON by default. Use --debug to print raw HTTP traces.

Login and Auto-Registration Flow

On login failure (401/403/404) and with auto-registration enabled, the CLI tries in order:

  1. Register with competition_bot_key (if configured)
  2. Register with team_invite_code (if configured)
  3. Create a new team and register the user

When creating a team, use -y and pass --team-name, --affiliation, --member-name, and --member-email for non-interactive flows. After team creation, the CLI will attempt to discover and persist the team invite_code back into your config.json for convenience.

SDK Usage

A minimal example using the SDK and your config.json:

from twooter import new

# Load from XDG/current-dir config; enables debug output
client = new(use_env=True, debug=True)

# Login (automatically creates the user/team when needed)
client.login("rdttl", "password")

# Who am I?
print(client.whoami())

# Post a twoot
print(client.post("Hello world!"))

# Like a post
print(client.post_like(123))

# Fetch a feed
print(client.tags_trending())

Files

  • config.json: CLI/SDK config (see above).
  • personas.db: SQLite personas store (users table with username/password/email/etc.).
  • tokens.db: SQLite token store for session management.
  • teams.db: Included in config and created as needed.

Troubleshooting

  • Missing config: create a config.json as shown above.
  • Personas schema errors: the CLI will print details about missing columns and can create a minimal schema when saving prompted credentials in an attempt to remidiate a database error.
  • Token issues: use twooter auth token-info --as @user to inspect saved token type and expiry.
  • HTTP issues: run with --debug to dump requests/responses.

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

twooter-1.0.7.tar.gz (26.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

twooter-1.0.7-py3-none-any.whl (31.6 kB view details)

Uploaded Python 3

File details

Details for the file twooter-1.0.7.tar.gz.

File metadata

  • Download URL: twooter-1.0.7.tar.gz
  • Upload date:
  • Size: 26.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for twooter-1.0.7.tar.gz
Algorithm Hash digest
SHA256 6b0c10fbcc908e9c8454609d48d429b4d7aea337fc4aafeaa2ab5ebfd6cdc003
MD5 2263d560c16d385845a73ad49ae9ef3a
BLAKE2b-256 6988bd82a3f234dc570d2068aa1c5a0271db8924840032cc761e34f62d63b462

See more details on using hashes here.

File details

Details for the file twooter-1.0.7-py3-none-any.whl.

File metadata

  • Download URL: twooter-1.0.7-py3-none-any.whl
  • Upload date:
  • Size: 31.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for twooter-1.0.7-py3-none-any.whl
Algorithm Hash digest
SHA256 54d860c22d8d9089d88427eac66e1f9c3cb7c56a530f08fc22405be04a892df7
MD5 b0451722c725a22399e9c9d59ec9cd02
BLAKE2b-256 32e6718672fa61388c1390719842f946785da08ca2b1f04848f0159c25f341ec

See more details on using hashes here.

Supported by

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