Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 5 additions & 19 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.8]
python-version: [3.12]
steps:

- uses: actions/checkout@v2
Expand All @@ -25,10 +25,8 @@ jobs:
with:
python-version: ${{ matrix.python-version }}

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Install uv
uses: astral-sh/setup-uv@v6

- name: Test with pytest
env:
Expand All @@ -38,27 +36,15 @@ jobs:
ACCESS_TOKEN_SECRET: ${{ secrets.access_token_secret }}
BEARER_TOKEN: ${{ secrets.bearer_token }}
SKIP_ACADEMIC_PRODUCT_TRACK: true
run: python setup.py test
run: uv run pytest

- name: Ensure packages can be built
run: |
python -m pip install wheel
python setup.py sdist bdist_wheel
uv build

- name: Publish to PyPI
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags')
uses: pypa/gh-action-pypi-publish@release/v1
with:
user: __token__
password: ${{ secrets.PYPI_API_TOKEN }}

- name: Slack Notification
uses: rtCamp/action-slack-notify@v2
env:
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
SLACK_USERNAME: docnow-build
SLACK_ICON_EMOJI: ":test-tube:"
SLACK_COLOR: "${{ job.status == 'success' && 'good' || 'danger' }}"
SLACK_MESSAGE: "Tests Results: ${{ job.status }}"


1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ twarc.egg-info
.vscode
.env
site
uv.lock
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# twarc

[![DOI](https://zenodo.org/badge/7605723.svg)](https://zenodo.org/badge/latestdoi/7605723) [![Build Status](https://github.com/docnow/twarc/workflows/tests/badge.svg)](https://github.com/DocNow/twarc/actions/workflows/main.yml) [![Standard](https://img.shields.io/endpoint?url=https%3A%2F%2Ftwbadges.glitch.me%2Fbadges%2Fstandard)](https://developer.twitter.com/en/docs/twitter-api) [![Premium](https://img.shields.io/endpoint?url=https%3A%2F%2Ftwbadges.glitch.me%2Fbadges%2Fpremium)](https://developer.twitter.com/) [![v2](https://img.shields.io/endpoint?url=https%3A%2F%2Ftwbadges.glitch.me%2Fbadges%2Fv2)](https://developer.twitter.com/en/docs/twitter-api)
**Note: twarc is no longer actively supported after changes to Twitter's API quotas made it unusable.**

---

[![DOI](https://zenodo.org/badge/7605723.svg)](https://zenodo.org/badge/latestdoi/7605723)

twarc is a command line tool and Python library for collecting and archiving Twitter JSON
data via the Twitter API. It has separate commands (twarc and twarc2) for working with the older
Expand Down Expand Up @@ -41,7 +45,6 @@ If you are interested in adding functionality to twarc or fixing something that'

git clone https://github.com/docnow/twarc
cd twarc
pip install -r requirements.txt

Create a .env file that included Twitter App keys to use during testing:

Expand All @@ -53,7 +56,7 @@ Create a .env file that included Twitter App keys to use during testing:

Now run the tests:

python setup.py test
uv run pytest

Add your code and some new tests, and send a pull request!

43 changes: 43 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
[project]
name = "twarc"
version = "2.14.1"
description = "Archive tweets from the command line"
license = "MIT"
readme = "README.md"
requires-python = ">=3.13"
dependencies = [
"click>=7,<9",
"click-config-file>=0.6",
"click-plugins>=1",
"humanize>=3.9",
"python-dateutil>=2.8",
"requests_oauthlib>=1.3",
"tqdm>=4.62",
"twarc-csv>=0.7.2",
]

[dependency-groups]
dev = [
"black>=25.9.0",
"pytest>=8.4.2",
"pytest-black>=0.6.0",
"python-dotenv>=1.2.1",
"pytz>=2025.2",
"toml>=0.10.2",
]

[project.scripts]
twarc = "twarc.command:main"
twarc2 = "twarc.command2:twarc2"

[tool.pytest.ini_options]
addopts = "--verbose --black"

[tool.uv.workspace]
members = [
"tmp/twarc",
]

[build-system]
requires = ["uv_build>=0.8.3,<0.9.0"]
build-backend = "uv_build"
7 changes: 0 additions & 7 deletions requirements.txt

This file was deleted.

45 changes: 0 additions & 45 deletions setup.py

This file was deleted.

File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
19 changes: 9 additions & 10 deletions twarc/command2.py → src/twarc/command2.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
The command line interfact to the Twitter v2 API.
"""

from itertools import filterfalse
import os
import re
import json
Expand All @@ -22,7 +21,7 @@

from datetime import timezone
from click_plugins import with_plugins
from pkg_resources import iter_entry_points
from importlib.metadata import entry_points

from twarc.version import version
from twarc.handshake import handshake
Expand All @@ -37,7 +36,7 @@
PLACE_FIELDS,
LIST_FIELDS,
)
from click import command, option, Option, UsageError
from click import Option, UsageError
from click_config_file import configuration_option
from twarc.decorators2 import (
cli_api_error,
Expand All @@ -53,7 +52,7 @@
log = logging.getLogger("twarc")


@with_plugins(iter_entry_points("twarc.plugins"))
@with_plugins(entry_points(group="twarc.plugins"))
@click.group()
@click.option(
"--consumer-key",
Expand Down Expand Up @@ -788,7 +787,7 @@ def tweet(T, tweet_id, outfile, pretty, **kwargs):

if "https" in tweet_id:
tweet_id = tweet_id.split("/")[-1]
if not re.match("^\d+$", tweet_id):
if not re.match(r"^\d+$", tweet_id):
click.echo(click.style("Please enter a tweet URL or ID", fg="red"), err=True)
result = next(T.tweet_lookup([tweet_id], **kwargs))
_write(result, outfile, pretty=pretty)
Expand Down Expand Up @@ -909,7 +908,7 @@ def liking_users(T, tweet_id, outfile, limit, max_results, hide_progress):
"""
lookup_total = 1

if not re.match("^\d+$", str(tweet_id)):
if not re.match(r"^\d+$", str(tweet_id)):
click.echo(click.style("Please enter a tweet ID", fg="red"), err=True)

hide_progress = True if (outfile.name == "<stdout>") else hide_progress
Expand Down Expand Up @@ -959,7 +958,7 @@ def retweeted_by(T, tweet_id, outfile, limit, max_results, hide_progress):
"""
lookup_total = 0

if not re.match("^\d+$", str(tweet_id)):
if not re.match(r"^\d+$", str(tweet_id)):
click.echo(click.style("Please enter a tweet ID", fg="red"), err=True)

hide_progress = True if (outfile.name == "<stdout>") else hide_progress
Expand Down Expand Up @@ -1016,7 +1015,7 @@ def quotes(T, tweet_id, outfile, limit, max_results, hide_progress, **kwargs):
kwargs.pop("poll_fields", None)
kwargs.pop("place_fields", None)

if not re.match("^\d+$", str(tweet_id)):
if not re.match(r"^\d+$", str(tweet_id)):
click.echo(click.style("Please enter a tweet ID", fg="red"), err=True)

hide_progress = True if (outfile.name == "<stdout>") else hide_progress
Expand Down Expand Up @@ -2065,7 +2064,7 @@ def lists_lookup(T, list_id, outfile, pretty, **kwargs):

if "https" in list_id:
list_id = list_id.split("/")[-1]
if not re.match("^\d+$", list_id):
if not re.match(r"^\d+$", list_id):
click.echo(click.style("Please enter a List URL or ID", fg="red"), err=True)
result = T.list_lookup(list_id, **kwargs)
_write(result, outfile, pretty=pretty)
Expand Down Expand Up @@ -2097,7 +2096,7 @@ def lists_bulk_lookup(T, infile, outfile, hide_progress, **kwargs):

if "https" in list_id:
list_id = list_id.split("/")[-1]
if not re.match("^\d+$", list_id):
if not re.match(r"^\d+$", list_id):
click.echo(
click.style("Skipping invalid List URL or ID: {line}", fg="red"),
err=True,
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion twarc/version.py → src/twarc/version.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import platform

version = "2.14.0"
version = "2.14.1"

user_agent = f"twarc/{version} ({platform.system()} {platform.machine()}) {platform.python_implementation()}/{platform.python_version()}"
Loading