Skip to content

Tests and Updates#41

Closed
s2t2 wants to merge 14 commits intostanfordio:mainfrom
s2t2:more-tests
Closed

Tests and Updates#41
s2t2 wants to merge 14 commits intostanfordio:mainfrom
s2t2:more-tests

Conversation

@s2t2
Copy link
Copy Markdown
Contributor

@s2t2 s2t2 commented Oct 11, 2024

Maintenance Updates

  1. Implements Continuous Integration using GitHub Actions, to run tests on CI server. To make this work, you need to set the environment variables as repository secrets (see README.md). See working example here: https://github.com/s2t2/truthbrush/actions

  2. Updates to Python 3.10:

poetry env use 3.10
  1. Splits API tests into resource-specific test files, to stay organized.

Functionality Updates

  1. Improves documentation and performance of the pull_statuses method. Makes user_name an optional parameter. Removes unnecessary API call using the username - if a user_id is supplied it uses the user_id in the request instead.

  2. Improves documentation for the search method, designating which resources are valid (closes How to get a group id? #42 ).

  3. Adds a simplified search method (search_simple) which returns only the resources requested.

  4. Adds a datetime conversion utility function which is helpful when asking for posts after a given datetime.

@s2t2

This comment was marked as outdated.

@s2t2 s2t2 marked this pull request as ready for review October 13, 2024 15:55
@s2t2 s2t2 mentioned this pull request Oct 13, 2024
@lxcode lxcode requested a review from milesmcc October 13, 2024 16:18
@s2t2 s2t2 changed the title Pull Statuses - Username Optional Tests and Updates Oct 13, 2024
env:
# set environment variables using repo secrets
TRUTHSOCIAL_USERNAME: ${{ secrets.TRUTHSOCIAL_USERNAME }}
TRUTHSOCIAL_PASSWORD: ${{ secrets.TRUTHSOCIAL_PASSWORD }}
Copy link
Copy Markdown
Contributor Author

@s2t2 s2t2 Oct 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These values need to be set on the upstream repo, using the repository secrets menu in the settings.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe the login isn't really needed: #32

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like that's maybe a change from when we first built the tool. Pretty sure it used to all be authwalled.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Passing the username and password allows us to test auth-walled functionality.

We can use a new test account if concerned about security.

Comment thread truthbrush/api.py
def user_likes(
self, post: str, include_all: bool = False, top_num: int = 40
) -> bool | Any:
) -> Union[bool, Any]:
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixes error by using Union

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm, bool | Any is equivalent to Any; also, the return type of this function doesn't make sense to me — shouldn't this return a list of some sort?

Copy link
Copy Markdown
Contributor Author

@s2t2 s2t2 Oct 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure about type hints or this function specifically. I had run into an issue with bool | Any and that was the suggested change. I'm happy to try changing it back.

Comment thread truthbrush/api.py
Comment thread truthbrush/api.py Outdated
query: str = None,
limit: int = 40,
resolve: bool = 4,
resolve: bool = 4, # bool = 4 ?
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI not sure if bool type and default value of 4 are compatible?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was the one who mistakenly introduced this: 1c74a96#diff-b8a4f09258d1b070faf6806097b4e7047930f99777e63d753dc1b03e7eae31a4R117

Needs to be changed ofc.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK I will change to int

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just curious, what does the resolve do?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, it needs to be a boolean (defaulted to True). Not sure what it does, changing from true to false does not change the output at all.

The params I get when executing a search in TS website are:

params = {
    'q': 'trump',
    'limit': '20',
    'resolve': 'true',
    'type': 'accounts',
}

So probably resolve needs to be 'true' if resolve else 'false' in the HTTP req. 1c74a96#diff-b8a4f09258d1b070faf6806097b4e7047930f99777e63d753dc1b03e7eae31a4R124

Comment thread truthbrush/api.py
)

offset += 40
offset += 40 # use limit here?
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this be referencing the limit?

Comment thread truthbrush/api.py
@s2t2
Copy link
Copy Markdown
Contributor Author

s2t2 commented Oct 13, 2024

FYI this PR is ready for review anytime. Takes some tests and docstring updates from #38 , as requested.

Comment thread truthbrush/api.py
from datetime import datetime, timezone, date
from datetime import datetime, timezone #, date
from curl_cffi import requests
import curl_cffi
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixes error by importing this package

Comment thread truthbrush/api.py

params = {}
user_id = self.lookup(username)["id"]
user_id = user_id or self.lookup(username)["id"]
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

skips separate request when able

Comment thread truthbrush/api.py Outdated
query: str = None,
limit: int = 40,
resolve: bool = 4,
resolve: int = 4,
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updates type hint

Comment thread test/conftest.py


@pytest.fixture(scope="module")
def user_timeline(client):
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI fixtures defined in the conftest.py can get referenced by test functions in other files.

@milesmcc
Copy link
Copy Markdown
Collaborator

Thanks! Ack, will review shortly.

Comment thread truthbrush/api.py
Co-authored-by: Konrad Iturbe <KonradIT@users.noreply.github.com>
@s2t2
Copy link
Copy Markdown
Contributor Author

s2t2 commented Oct 22, 2024

I have started to see some cloudflare restricted pages. I assume when making too many requests in too short a period of time. But does anyone know what the logic is for when they appear?

lxcode added a commit that referenced this pull request Apr 20, 2026
Public/unauthenticated mode (closes #32)
- Api gains keyword-only require_auth=True parameter; default preserves
  strict behavior so no existing caller changes.
- __check_login early-returns when require_auth=False and no token is
  present, instead of raising LoginErrorException.
- _get and _get_paginated omit the Authorization header when auth_id is
  None. Sending no header beats sending "Bearer None".
- CLI: --no-auth global flag on the group, Api constructed once via
  ctx.obj["api"]; all 13 commands take click.Context via pass_context.
  Verified end-to-end: `truthbrush --no-auth user realDonaldTrump`
  returns JSON; `truthbrush trends` (strict, no creds) still raises.

Python 3.14
- pyproject.toml: python = "^3.14"; ruff target-version = "py314".
- Workflow: actions/setup-python bumped to @v5 with python-version: 3.14
  (3.10-dev was a stale pre-release pin).
- Ruff auto-fix pass: timezone.utc -> UTC; stale quoted forward-ref on
  date_to_bound unquoted.

Type hygiene
- ty check truthbrush/ goes from 35 pre-existing diagnostics to zero:
  x: T = None defaults -> X | None = None throughout; generator return
  types -> Iterator[T]; datetime.utcnow() -> datetime.now(UTC);
  ratelimit_reset null-guarded; sorted() over JSON payload narrowed via
  cast(list[dict], result); pull_statuses result-shape validation
  reordered so a non-list response breaks the loop instead of crashing
  in sorted().

Drive-bys cherry-picked from PR #41
- search(resolve: bool = 4) -> True. Default was an int despite the
  bool annotation.
- pull_statuses(username=None, ..., *, user_id=None): either identifier
  works; supplying user_id directly skips the lookup roundtrip, which
  matters in public mode where lookup may be gated. Also calls
  __check_login explicitly (previously relied on transitive call).

Tests
- Two offline tests: one asserts Api(require_auth=False) without creds
  does not raise on a method call that short-circuits before HTTP; one
  asserts the default strict mode still raises LoginErrorException
  without creds. Both use monkeypatch.delenv to guard against a
  loaded .env.

README
- New "Public mode (no credentials)" subsection under Installation.
- --no-auth added to the help block.
- Stale "Please format your code with black" replaced with the ruff/ty
  workflow introduced in 0.3.0.

Authors
- pyproject.toml authors gains David Thiel.
lxcode added a commit that referenced this pull request Apr 20, 2026
Public/unauthenticated mode (closes #32)
- Api gains keyword-only require_auth=True parameter; default preserves
  strict behavior so no existing caller changes.
- __check_login early-returns when require_auth=False and no token is
  present, instead of raising LoginErrorException.
- _get and _get_paginated omit the Authorization header when auth_id is
  None. Sending no header beats sending "Bearer None".
- CLI: --no-auth global flag on the group, Api constructed once via
  ctx.obj["api"]; all 13 commands take click.Context via pass_context.
  Verified end-to-end: `truthbrush --no-auth user realDonaldTrump`
  returns JSON; `truthbrush trends` (strict, no creds) still raises.

Python 3.14
- pyproject.toml: python = "^3.14"; ruff target-version = "py314".
- Workflow: actions/setup-python bumped to @v5 with python-version: 3.14
  (3.10-dev was a stale pre-release pin).
- Ruff auto-fix pass: timezone.utc -> UTC; stale quoted forward-ref on
  date_to_bound unquoted.

Type hygiene
- ty check truthbrush/ goes from 35 pre-existing diagnostics to zero:
  x: T = None defaults -> X | None = None throughout; generator return
  types -> Iterator[T]; datetime.utcnow() -> datetime.now(UTC);
  ratelimit_reset null-guarded; sorted() over JSON payload narrowed via
  cast(list[dict], result); pull_statuses result-shape validation
  reordered so a non-list response breaks the loop instead of crashing
  in sorted().

Drive-bys cherry-picked from PR #41
- search(resolve: bool = 4) -> True. Default was an int despite the
  bool annotation.
- pull_statuses(username=None, ..., *, user_id=None): either identifier
  works; supplying user_id directly skips the lookup roundtrip, which
  matters in public mode where lookup may be gated. Also calls
  __check_login explicitly (previously relied on transitive call).

Tests
- Two offline tests: one asserts Api(require_auth=False) without creds
  does not raise on a method call that short-circuits before HTTP; one
  asserts the default strict mode still raises LoginErrorException
  without creds. Both use monkeypatch.delenv to guard against a
  loaded .env.

README
- New "Public mode (no credentials)" subsection under Installation.
- --no-auth added to the help block.
- Stale "Please format your code with black" replaced with the ruff/ty
  workflow introduced in 0.3.0.

Authors
- pyproject.toml authors gains David Thiel.
@lxcode lxcode mentioned this pull request Apr 20, 2026
@lxcode
Copy link
Copy Markdown
Contributor

lxcode commented Apr 20, 2026

Ok sorry to leave this sitting a while, but I've pulled a couple fixes from here and hopefully some other things have been resolved along the way

@lxcode lxcode closed this Apr 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

How to get a group id?

4 participants