Skip to main content

objectionengine2-teams

Render a Microsoft Teams chat or channel as an Objection Engine 2 video. This is a separate Python 3.10–3.14 package using Microsoft Graph delegated access.

Install

Install Python 3.10–3.14, uv, FFmpeg and ffprobe, then install the command from PyPI:

uv tool install --torch-backend cpu objectionengine2-teams

The install includes objectionengine2 and its sentiment dependencies. The first render downloads the Hugging Face sentiment model.

Objection Engine saves its asset pack and sentiment model under the platformdirs user cache for objectionengine2. The first render populates the cache. See the cache path with uv run --no-project --torch-backend cpu --with objectionengine2-teams python -c 'from objectionengine2.cache import cache_path; print(cache_path())'. Run the installed command:

mkdir -p outputs
objectionengine2-teams \
  'https://teams.microsoft.com/l/chat/19:example@thread.v2/conversations' \
  -o outputs/teams.mp4

Replace the example URL with a real link copied from a chat or channel. A successful render saves its settings next to the video as teams.mp4.json. The file includes the rendered conversation, Teams links and authentication settings, but no tokens. Evidence paths refer to files in the local image cache. Scene choices are randomized, so the settings do not guarantee an identical video. A channel link renders the channel; a channel message link renders only its thread. Its parentMessageId identifies the thread root, while the message ID in the URL path is the first message rendered. A chat message link likewise starts at the linked message. You can bound the render with another message link in the same chat or channel thread:

objectionengine2-teams \
  '<start message link>' --end-link '<end message link>' -o outputs/teams.mp4

Both endpoints are included. --max-messages 20 selects the first 20 rendered messages after a start link, or the newest 20 for an unbounded chat/channel link. The CLI sorts them by creation time, skips empty messages, and excludes thread titles from dialogue. Rich reactions, deleted messages, and system events are not represented. The first inline image in each message is displayed as evidence when Microsoft Graph provides it as hosted content. Other attachments become a short placeholder when there is no message text. Images are cached in the user cache for objectionengine2-teams; remove its images directory to delete them. Images that cannot be downloaded are omitted.

Sign-in and permissions

The default public client ID is the requested Microsoft Office ID, d3590ed6-52b3-4102-aeff-aad2292ab01c. Azure Identity uses InteractiveBrowserBrokerCredential by default and requests only the delegated permission needed for the link:

Link Delegated Microsoft Graph permission
Chat Chat.ReadWrite
Channel ChannelMessage.Read.All

The signed-in user must have access to the conversation. Microsoft Entra may reject this client or require administrator consent, especially for the channel permission. The client ID does not itself guarantee a grant. If the Office client cannot obtain the requested scope, register a public client application in your tenant with the Graph delegated permission and pass its ID through --client-id. Broker sign-in uses the platform's broker redirect URI; on Windows and WSL, that is ms-appx-web://Microsoft.AAD.BrokerPlugin/<client-id>. The application must allow that redirect. The --redirect-uri option applies only to explicit --auth-method browser sign-in, whose default callback is http://localhost:8400.

On Windows, broker sign-in uses Web Account Manager. On WSL 2.4.13 or newer, it can use the Windows broker as well. On other Linux setups it may open a browser if a supported broker is unavailable. To select another method, use:

objectionengine2-teams '<Teams message link>' \
  --auth-method browser -o outputs/teams.mp4
objectionengine2-teams '<Teams message link>' \
  --auth-method device-code -o outputs/teams.mp4

Azure Identity persists tokens in a per-user cache and reuses them on later runs. Broker sign-in first tries the default broker account silently and then offers interactive sign-in if needed. Use --auth-method cache to read an already cached token without an interactive fallback. Azure Identity encrypts the persistent cache when the platform supports it; on platforms without user-data encryption (including some WSL installations), it may store tokens unencrypted. Keep your user profile private. Browser and device-code sign-in also save a separate non-secret account record under the user state directory (~/.local/state/objectionengine2-teams/ on Linux unless XDG_STATE_HOME is set). The methods use the same named persistent token cache.

Sentiment and objections

Teams messages have no explicit Comment.score. Teams renders use the core Hugging Face sentiment model by default. The normal command is enough:

objectionengine2-teams \
  '<Teams message link>' -o outputs/teams.mp4

Set oe_sentiment_model=neutral or oe_bypass_sentiment=1 to use neutral sentiment for a render. An explicit oe_sentiment_model value is respected. A strongly negative classification (confidence above 0.5) has roughly a 70% chance of triggering an objection; a strongly positive one has roughly a 30% chance. An objection is therefore possible, not guaranteed, for any particular message. If you need to choose the sentiment yourself, call fetch_comments, set comment.score to a negative or positive value above 0.5 in magnitude, then pass the comments to objectionengine2.renderer.render_comment_list. The objection still has a random chance of occurring.

Python API

from objectionengine2_teams import fetch_comments, render_teams_link

comments = fetch_comments(start_message_url, end_link=end_message_url)
render_teams_link(start_message_url, "outputs/teams.mp4", end_link=end_message_url)

fetch_comments returns objectionengine2.beans.comment.Comment objects. render_teams_link enables Hugging Face sentiment by default for its render. Both calls default to broker sign-in. Pass auth_method="browser", auth_method="device-code", or auth_method="cache" to select another method. Later calls reuse cached tokens when valid. To inspect messages and render without fetching them twice, use the comments with objectionengine2.renderer.render_comment_list directly.

Tests

For development, clone the repository and install its locked dependencies with uv:

cd ~/development/objectionengine2-teams
uv sync --locked
uv run --locked pytest -q
uv build --no-sources

The default tests use fake Graph responses and Azure Identity credentials. They never access a tenant, download assets or models, or render private Teams content. To exercise the complete video encoder with local fixture messages, run:

uv run --locked pytest -q -m asset_integration

That test calls objectionengine2.utils.ensure_assets_are_available() first, then renders with default Hugging Face sentiment. It populates the platform cache with assets and the model when necessary. A live Teams render still requires a link, sign-in, and Graph consent; it cannot be validated by the offline suite.

Metadata

Release files for objectionengine2-teams 1.0.2

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

Source distribution (sdist)

Source distribution for objectionengine2-teams 1.0.2
File Size Uploaded Provenance Actions
objectionengine2_teams-1.0.2.tar.gz 13.7 kB With provenance Details for objectionengine2_teams-1.0.2.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for objectionengine2-teams 1.0.2
File Interpreter ABI Platform Actions
objectionengine2_teams-1.0.2-py3-none-any.whl Python 3 none any Details for objectionengine2_teams-1.0.2-py3-none-any.whl

Total release size: 31.4 kB

Release files / objectionengine2_teams-1.0.2.tar.gz

Download URL objectionengine2_teams-1.0.2.tar.gz
Size 13.7 kB
Tags Source
SHA-256 checksum
How to use checksums
4e4cb47b049f71b235845f77bf78a2c9223699d049802c29eb5bee60380c5d79
BLAKE2b-256 checksum
How to use checksums
dcf17e1f3e51ba6b2b6d06245c61f39308a284a8e3bab0de008ff7824c1ee5ad
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 6, 2026.

Transparency log

Release files / objectionengine2_teams-1.0.2-py3-none-any.whl

Download URL objectionengine2_teams-1.0.2-py3-none-any.whl
Size 17.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a8b7f6e5460d4d0402b5cea509f2d246bdd5a4e3a3deb3e33dae6afc4b751f6d
BLAKE2b-256 checksum
How to use checksums
f61cb9756a798f6a16260d85e56706f164aee87af0422e2f4a01ade0041a93e0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 6, 2026.

Transparency log

Security for objectionengine2-teams 1.0.2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for objectionengine2_teams-1.0.2.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 6, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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