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.9.tar.gz (25.7 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.9-py3-none-any.whl (32.2 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: twooter-1.0.9.tar.gz
  • Upload date:
  • Size: 25.7 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.9.tar.gz
Algorithm Hash digest
SHA256 0aab94c11279dffa256c15adc7a3fcee827a6b8e575a5403e8ffa553ad86933d
MD5 a2b94b3e1fcc92f6bf1113cb523b81e6
BLAKE2b-256 979963b2b7d37ed92917bd1a39341d9baac06d6b7074c0432c7737c2c5fc5e4f

See more details on using hashes here.

File details

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

File metadata

  • Download URL: twooter-1.0.9-py3-none-any.whl
  • Upload date:
  • Size: 32.2 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.9-py3-none-any.whl
Algorithm Hash digest
SHA256 4f1570211f51b0cb357ba698896c50aa7d6b0cbfbd6b7f557ccb44d3912022a3
MD5 88df4d3e193d2f75a28b749da05fb04e
BLAKE2b-256 303da0e635151f2291a10a0231898a6e0277c60d6c446231bf4b02608988a016

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