socialchimp 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- socialchimp-0.1.0/.github/workflows/ci.yml +44 -0
- socialchimp-0.1.0/.github/workflows/publish.yml +80 -0
- socialchimp-0.1.0/.gitignore +27 -0
- socialchimp-0.1.0/.pre-commit-config.yaml +49 -0
- socialchimp-0.1.0/CHANGELOG.md +67 -0
- socialchimp-0.1.0/CONTRIBUTING.md +76 -0
- socialchimp-0.1.0/LICENSE +21 -0
- socialchimp-0.1.0/PKG-INFO +159 -0
- socialchimp-0.1.0/README.md +118 -0
- socialchimp-0.1.0/docs/PLAN.md +187 -0
- socialchimp-0.1.0/docs/adding-a-platform.md +306 -0
- socialchimp-0.1.0/docs/frameworks.md +350 -0
- socialchimp-0.1.0/docs/getting-started.md +304 -0
- socialchimp-0.1.0/docs/platforms.md +268 -0
- socialchimp-0.1.0/docs/releasing.md +99 -0
- socialchimp-0.1.0/examples/README.md +7 -0
- socialchimp-0.1.0/examples/post_to_many.py +75 -0
- socialchimp-0.1.0/examples/post_to_mastodon.py +96 -0
- socialchimp-0.1.0/pyproject.toml +196 -0
- socialchimp-0.1.0/src/socialchimp/__init__.py +135 -0
- socialchimp-0.1.0/src/socialchimp/client.py +1176 -0
- socialchimp-0.1.0/src/socialchimp/contrib/__init__.py +26 -0
- socialchimp-0.1.0/src/socialchimp/contrib/django.py +537 -0
- socialchimp-0.1.0/src/socialchimp/contrib/fastapi.py +162 -0
- socialchimp-0.1.0/src/socialchimp/contrib/flask.py +222 -0
- socialchimp-0.1.0/src/socialchimp/contrib/shared.py +739 -0
- socialchimp-0.1.0/src/socialchimp/errors.py +227 -0
- socialchimp-0.1.0/src/socialchimp/events.py +760 -0
- socialchimp-0.1.0/src/socialchimp/features.py +545 -0
- socialchimp-0.1.0/src/socialchimp/http.py +809 -0
- socialchimp-0.1.0/src/socialchimp/models.py +539 -0
- socialchimp-0.1.0/src/socialchimp/platform.py +512 -0
- socialchimp-0.1.0/src/socialchimp/platforms/__init__.py +15 -0
- socialchimp-0.1.0/src/socialchimp/platforms/_meta.py +1418 -0
- socialchimp-0.1.0/src/socialchimp/platforms/bluesky.py +1234 -0
- socialchimp-0.1.0/src/socialchimp/platforms/facebook.py +1260 -0
- socialchimp-0.1.0/src/socialchimp/platforms/instagram.py +1754 -0
- socialchimp-0.1.0/src/socialchimp/platforms/mastodon.py +1162 -0
- socialchimp-0.1.0/src/socialchimp/platforms/pinterest.py +1393 -0
- socialchimp-0.1.0/src/socialchimp/platforms/threads.py +1838 -0
- socialchimp-0.1.0/src/socialchimp/platforms/tiktok.py +2074 -0
- socialchimp-0.1.0/src/socialchimp/platforms/x.py +1678 -0
- socialchimp-0.1.0/src/socialchimp/platforms/youtube.py +1797 -0
- socialchimp-0.1.0/src/socialchimp/py.typed +0 -0
- socialchimp-0.1.0/src/socialchimp/registry.py +293 -0
- socialchimp-0.1.0/src/socialchimp/storage.py +349 -0
- socialchimp-0.1.0/src/socialchimp/testing.py +1696 -0
- socialchimp-0.1.0/src/socialchimp/tokens.py +355 -0
- socialchimp-0.1.0/tests/__init__.py +1 -0
- socialchimp-0.1.0/tests/test_bluesky.py +1340 -0
- socialchimp-0.1.0/tests/test_client.py +1280 -0
- socialchimp-0.1.0/tests/test_contrib_django.py +672 -0
- socialchimp-0.1.0/tests/test_contrib_fastapi.py +257 -0
- socialchimp-0.1.0/tests/test_contrib_flask.py +306 -0
- socialchimp-0.1.0/tests/test_contrib_shared.py +626 -0
- socialchimp-0.1.0/tests/test_errors.py +105 -0
- socialchimp-0.1.0/tests/test_events.py +530 -0
- socialchimp-0.1.0/tests/test_facebook.py +1540 -0
- socialchimp-0.1.0/tests/test_features.py +487 -0
- socialchimp-0.1.0/tests/test_http.py +786 -0
- socialchimp-0.1.0/tests/test_instagram.py +1948 -0
- socialchimp-0.1.0/tests/test_mastodon.py +1255 -0
- socialchimp-0.1.0/tests/test_meta.py +1227 -0
- socialchimp-0.1.0/tests/test_models.py +306 -0
- socialchimp-0.1.0/tests/test_pinterest.py +1578 -0
- socialchimp-0.1.0/tests/test_platform.py +269 -0
- socialchimp-0.1.0/tests/test_registry.py +338 -0
- socialchimp-0.1.0/tests/test_storage.py +237 -0
- socialchimp-0.1.0/tests/test_testing.py +1518 -0
- socialchimp-0.1.0/tests/test_threads.py +1830 -0
- socialchimp-0.1.0/tests/test_tiktok.py +2121 -0
- socialchimp-0.1.0/tests/test_tokens.py +473 -0
- socialchimp-0.1.0/tests/test_x.py +1546 -0
- socialchimp-0.1.0/tests/test_youtube.py +1749 -0
- socialchimp-0.1.0/uv.lock +1227 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
concurrency:
|
|
9
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
10
|
+
cancel-in-progress: true
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
check:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
strategy:
|
|
16
|
+
fail-fast: false
|
|
17
|
+
matrix:
|
|
18
|
+
python-version: ["3.11", "3.12", "3.13"]
|
|
19
|
+
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/checkout@v4
|
|
22
|
+
|
|
23
|
+
- name: Install uv
|
|
24
|
+
uses: astral-sh/setup-uv@v5
|
|
25
|
+
with:
|
|
26
|
+
enable-cache: true
|
|
27
|
+
|
|
28
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
29
|
+
run: uv python install ${{ matrix.python-version }}
|
|
30
|
+
|
|
31
|
+
- name: Install dependencies
|
|
32
|
+
run: uv sync --all-extras --dev
|
|
33
|
+
|
|
34
|
+
- name: Lint
|
|
35
|
+
run: uv run ruff check .
|
|
36
|
+
|
|
37
|
+
- name: Check formatting
|
|
38
|
+
run: uv run ruff format --check .
|
|
39
|
+
|
|
40
|
+
- name: Check types
|
|
41
|
+
run: uv run mypy
|
|
42
|
+
|
|
43
|
+
- name: Run tests
|
|
44
|
+
run: uv run pytest
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
name: Publish
|
|
2
|
+
|
|
3
|
+
# Publishes to PyPI when you publish a GitHub release.
|
|
4
|
+
#
|
|
5
|
+
# There is no API token anywhere. PyPI is told to trust this one workflow, in
|
|
6
|
+
# this one repository, and GitHub proves who it is at the moment it uploads.
|
|
7
|
+
# Nothing to store, nothing to leak, nothing to rotate.
|
|
8
|
+
#
|
|
9
|
+
# To set it up, add a publisher at https://pypi.org/manage/account/publishing/
|
|
10
|
+
# with these exact values:
|
|
11
|
+
#
|
|
12
|
+
# PyPI project name socialchimp
|
|
13
|
+
# Owner raghulj
|
|
14
|
+
# Repository name socialchimp
|
|
15
|
+
# Workflow name publish.yml
|
|
16
|
+
# Environment name pypi
|
|
17
|
+
#
|
|
18
|
+
# See docs/releasing.md for the whole procedure.
|
|
19
|
+
|
|
20
|
+
on:
|
|
21
|
+
release:
|
|
22
|
+
types: [published]
|
|
23
|
+
workflow_dispatch:
|
|
24
|
+
|
|
25
|
+
jobs:
|
|
26
|
+
# Publishing a broken release cannot be undone: PyPI never lets a version
|
|
27
|
+
# be replaced. So everything is checked again here, rather than trusting
|
|
28
|
+
# that the commit was green when it was tagged.
|
|
29
|
+
check:
|
|
30
|
+
runs-on: ubuntu-latest
|
|
31
|
+
strategy:
|
|
32
|
+
fail-fast: false
|
|
33
|
+
matrix:
|
|
34
|
+
python-version: ["3.11", "3.12", "3.13"]
|
|
35
|
+
steps:
|
|
36
|
+
- uses: actions/checkout@v4
|
|
37
|
+
- uses: astral-sh/setup-uv@v5
|
|
38
|
+
with:
|
|
39
|
+
enable-cache: true
|
|
40
|
+
- run: uv python install ${{ matrix.python-version }}
|
|
41
|
+
- run: uv sync --all-extras --dev
|
|
42
|
+
- run: uv run ruff check .
|
|
43
|
+
- run: uv run ruff format --check .
|
|
44
|
+
- run: uv run mypy
|
|
45
|
+
- run: uv run pytest
|
|
46
|
+
|
|
47
|
+
build:
|
|
48
|
+
needs: check
|
|
49
|
+
runs-on: ubuntu-latest
|
|
50
|
+
steps:
|
|
51
|
+
- uses: actions/checkout@v4
|
|
52
|
+
- uses: astral-sh/setup-uv@v5
|
|
53
|
+
- run: uv build
|
|
54
|
+
|
|
55
|
+
# Check the built files are actually uploadable before we try, so a
|
|
56
|
+
# bad description or a missing field fails here rather than half way
|
|
57
|
+
# through claiming the version number.
|
|
58
|
+
- run: uvx twine check --strict dist/*
|
|
59
|
+
|
|
60
|
+
- uses: actions/upload-artifact@v4
|
|
61
|
+
with:
|
|
62
|
+
name: packages
|
|
63
|
+
path: dist/
|
|
64
|
+
|
|
65
|
+
publish:
|
|
66
|
+
needs: build
|
|
67
|
+
runs-on: ubuntu-latest
|
|
68
|
+
environment:
|
|
69
|
+
name: pypi
|
|
70
|
+
url: https://pypi.org/p/socialchimp
|
|
71
|
+
permissions:
|
|
72
|
+
# Lets GitHub prove to PyPI that this workflow is what it says it is.
|
|
73
|
+
# This is what replaces the API token.
|
|
74
|
+
id-token: write
|
|
75
|
+
steps:
|
|
76
|
+
- uses: actions/download-artifact@v4
|
|
77
|
+
with:
|
|
78
|
+
name: packages
|
|
79
|
+
path: dist/
|
|
80
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.egg-info/
|
|
5
|
+
build/
|
|
6
|
+
dist/
|
|
7
|
+
.venv/
|
|
8
|
+
venv/
|
|
9
|
+
|
|
10
|
+
# Testing
|
|
11
|
+
.pytest_cache/
|
|
12
|
+
.coverage
|
|
13
|
+
coverage.xml
|
|
14
|
+
htmlcov/
|
|
15
|
+
.mypy_cache/
|
|
16
|
+
.ruff_cache/
|
|
17
|
+
|
|
18
|
+
# Editors
|
|
19
|
+
.vscode/
|
|
20
|
+
.idea/
|
|
21
|
+
*.swp
|
|
22
|
+
.DS_Store
|
|
23
|
+
|
|
24
|
+
# Secrets - never commit real credentials
|
|
25
|
+
.env
|
|
26
|
+
.env.*
|
|
27
|
+
!.env.example
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Checks that run before every commit and push.
|
|
2
|
+
#
|
|
3
|
+
# Install once after cloning:
|
|
4
|
+
# uv run pre-commit install --hook-type pre-commit --hook-type pre-push
|
|
5
|
+
#
|
|
6
|
+
# Fast checks (format, lint, types) run on commit.
|
|
7
|
+
# The test suite runs on push, because it is slower.
|
|
8
|
+
|
|
9
|
+
default_install_hook_types: [pre-commit, pre-push]
|
|
10
|
+
|
|
11
|
+
repos:
|
|
12
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
13
|
+
rev: v5.0.0
|
|
14
|
+
hooks:
|
|
15
|
+
- id: trailing-whitespace
|
|
16
|
+
- id: end-of-file-fixer
|
|
17
|
+
- id: check-yaml
|
|
18
|
+
- id: check-toml
|
|
19
|
+
- id: check-merge-conflict
|
|
20
|
+
- id: check-added-large-files
|
|
21
|
+
args: [--maxkb=512]
|
|
22
|
+
- id: detect-private-key
|
|
23
|
+
- id: mixed-line-ending
|
|
24
|
+
args: [--fix=lf]
|
|
25
|
+
|
|
26
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
27
|
+
rev: v0.8.6
|
|
28
|
+
hooks:
|
|
29
|
+
# Fix what can be fixed, then fail on what is left.
|
|
30
|
+
- id: ruff
|
|
31
|
+
args: [--fix]
|
|
32
|
+
- id: ruff-format
|
|
33
|
+
|
|
34
|
+
- repo: local
|
|
35
|
+
hooks:
|
|
36
|
+
- id: mypy
|
|
37
|
+
name: mypy (strict)
|
|
38
|
+
entry: uv run mypy
|
|
39
|
+
language: system
|
|
40
|
+
types: [python]
|
|
41
|
+
pass_filenames: false
|
|
42
|
+
|
|
43
|
+
- id: pytest
|
|
44
|
+
name: pytest (100% coverage required)
|
|
45
|
+
entry: uv run pytest
|
|
46
|
+
language: system
|
|
47
|
+
types: [python]
|
|
48
|
+
pass_filenames: false
|
|
49
|
+
stages: [pre-push]
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
Notable changes, newest first. Versions follow
|
|
4
|
+
[semantic versioning](https://semver.org): while this is 0.x, a change to the
|
|
5
|
+
middle number may break something.
|
|
6
|
+
|
|
7
|
+
## 0.1.0 - 2026-08-31
|
|
8
|
+
|
|
9
|
+
The first release. Nine networks work end to end.
|
|
10
|
+
|
|
11
|
+
### Networks
|
|
12
|
+
|
|
13
|
+
**Mastodon**, **Bluesky**, **Facebook Pages**, **Instagram**, **YouTube**,
|
|
14
|
+
**TikTok**, **X**, **Pinterest**, **Threads**.
|
|
15
|
+
|
|
16
|
+
Each one signs people in, keeps their token working, posts, and reports what
|
|
17
|
+
happened. What a network cannot do it says so, rather than approximating:
|
|
18
|
+
Bluesky has no scheduling, YouTube has no post of words alone, Pinterest has
|
|
19
|
+
no comments, Instagram cannot take an upload and needs a web address.
|
|
20
|
+
|
|
21
|
+
### What is in it
|
|
22
|
+
|
|
23
|
+
- **One way to work with every network**, and direct access to any of them
|
|
24
|
+
when the shared way is not enough. Direct access still renews your token,
|
|
25
|
+
retries, and respects rate limits - only the request is yours.
|
|
26
|
+
- **Your app keeps its own database.** No models, no migrations. Five methods
|
|
27
|
+
in a class you write.
|
|
28
|
+
- **Tokens renewed before they run out**, under a lock so two workers cannot
|
|
29
|
+
renew at once. That matters on Bluesky, Pinterest and TikTok, which replace
|
|
30
|
+
the refresh token every time it is used: without the lock, whichever worker
|
|
31
|
+
loses is left holding a token the network has already thrown away, and that
|
|
32
|
+
account is disconnected until the person signs in again.
|
|
33
|
+
- **Updates the same shape either way** - pushed where a network supports it,
|
|
34
|
+
found by checking on a timer where it does not.
|
|
35
|
+
- **Helpers for Django, FastAPI and Flask.** Django works on ordinary
|
|
36
|
+
synchronous views and lets you write your storage as plain Django ORM code.
|
|
37
|
+
- **A test kit** so a network you write yourself can prove it behaves like
|
|
38
|
+
the ones here. You do not need a pull request to this repository to add a
|
|
39
|
+
network; publish a package, and socialchimp finds it.
|
|
40
|
+
|
|
41
|
+
### Getting started
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
pip install socialchimp
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Then [docs/getting-started.md](docs/getting-started.md), which goes from
|
|
48
|
+
nothing to a post on Mastodon in six steps.
|
|
49
|
+
|
|
50
|
+
### Worth knowing
|
|
51
|
+
|
|
52
|
+
- **Facebook, Instagram, Threads, YouTube, TikTok, X and Pinterest all need
|
|
53
|
+
you to create the app by hand**, and several review it before it works.
|
|
54
|
+
That review is the slowest part of getting started, so begin it early.
|
|
55
|
+
[docs/platforms.md](docs/platforms.md) says what each one needs.
|
|
56
|
+
- **Three networks have a trap that makes working code look broken.** An
|
|
57
|
+
unaudited TikTok app posts everything as private. Pinterest on Trial shows
|
|
58
|
+
your pins only to you. X answers 403 when your plan does not allow
|
|
59
|
+
something. All three are called out where you will meet them.
|
|
60
|
+
- **The way platforms are written is now settled.** See
|
|
61
|
+
[the promise about changes](docs/adding-a-platform.md#what-we-promise-about-changes).
|
|
62
|
+
|
|
63
|
+
### Quality
|
|
64
|
+
|
|
65
|
+
1706 tests. 100% of lines and branches covered, enforced - the suite fails
|
|
66
|
+
below it. `mypy --strict` with no ignores anywhere. Checked on Python 3.11,
|
|
67
|
+
3.12 and 3.13.
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Thanks for helping. This page covers how to get set up and the three rules
|
|
4
|
+
that are not negotiable.
|
|
5
|
+
|
|
6
|
+
## Getting set up
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
git clone https://github.com/raghulj/socialchimp
|
|
10
|
+
cd socialchimp
|
|
11
|
+
uv sync --all-extras --dev
|
|
12
|
+
uv run pre-commit install --hook-type pre-commit --hook-type pre-push
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
The hooks check formatting, style and types before each commit, and run the
|
|
16
|
+
tests before each push. That is deliberate: it means a broken push is hard to
|
|
17
|
+
do by accident.
|
|
18
|
+
|
|
19
|
+
## The three rules
|
|
20
|
+
|
|
21
|
+
**1. Tests come first.** Write the failing test, watch it fail for the reason
|
|
22
|
+
you expect, then write the code. A test written afterwards tends to describe
|
|
23
|
+
what the code does rather than what it should do.
|
|
24
|
+
|
|
25
|
+
**2. Coverage stays at 100%.** `uv run pytest` fails below it. This is not
|
|
26
|
+
about the number - it is that a line nobody tested is a line nobody has ever
|
|
27
|
+
run, and in a library that talks to fifteen different networks those lines
|
|
28
|
+
pile up fast.
|
|
29
|
+
|
|
30
|
+
Coverage is a floor, not a finish line. A test that runs a line without
|
|
31
|
+
checking anything meaningful passes the gate and helps nobody. Worth trying
|
|
32
|
+
on anything tricky: break your own code on purpose and check a test notices.
|
|
33
|
+
|
|
34
|
+
**3. Types are strict.** `uv run mypy` passes with no `# type: ignore`. If a
|
|
35
|
+
type is hard to write, that is usually the design telling you something.
|
|
36
|
+
|
|
37
|
+
## Language
|
|
38
|
+
|
|
39
|
+
Write in plain words, in code, docs and error messages alike.
|
|
40
|
+
|
|
41
|
+
Someone reading this library is usually in the middle of a problem: a token
|
|
42
|
+
stopped working, a post did not arrive. They should not also have to decode
|
|
43
|
+
our vocabulary. Say "the shared way", not "the abstraction layer". Say
|
|
44
|
+
"checking on a timer", not "polling-based virtual webhooks". If a name needs
|
|
45
|
+
a glossary, pick a different name.
|
|
46
|
+
|
|
47
|
+
Error messages should say what went wrong **and what to do about it**.
|
|
48
|
+
|
|
49
|
+
## Comments
|
|
50
|
+
|
|
51
|
+
Comments explain *why*, not *what*. The code already says what it does.
|
|
52
|
+
|
|
53
|
+
The comments worth writing are the ones that stop someone undoing a decision
|
|
54
|
+
they do not understand - for example, why token renewal takes a lock and then
|
|
55
|
+
reads the connection a second time. Without the why, that reads like a
|
|
56
|
+
pointless extra query, and someone will remove it.
|
|
57
|
+
|
|
58
|
+
## Before you push
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
uv run ruff check . && uv run ruff format --check . && uv run mypy && uv run pytest
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Please do not push red. CI emails are nobody's idea of a good time.
|
|
65
|
+
|
|
66
|
+
## Adding a network
|
|
67
|
+
|
|
68
|
+
You do not need to add it here. Publish your own package that registers
|
|
69
|
+
itself and socialchimp will find it. See [docs/adding-a-platform.md](docs/adding-a-platform.md).
|
|
70
|
+
|
|
71
|
+
If you would like it built in, open an issue first so we can agree where it
|
|
72
|
+
goes in the order - see [docs/PLAN.md](docs/PLAN.md).
|
|
73
|
+
|
|
74
|
+
## Licence
|
|
75
|
+
|
|
76
|
+
By contributing you agree your work is released under the MIT licence.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Raghul Jagannathan
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: socialchimp
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: One simple way to connect your app to social networks.
|
|
5
|
+
Project-URL: Homepage, https://github.com/raghulj/socialchimp
|
|
6
|
+
Project-URL: Documentation, https://github.com/raghulj/socialchimp/tree/main/docs
|
|
7
|
+
Project-URL: Issues, https://github.com/raghulj/socialchimp/issues
|
|
8
|
+
Author-email: Raghul Jagannathan <raghulj@gmail.com>
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: bluesky,django,fastapi,flask,instagram,mastodon,oauth,pinterest,social,threads,tiktok,twitter,youtube
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
19
|
+
Classifier: Topic :: Internet :: WWW/HTTP
|
|
20
|
+
Classifier: Typing :: Typed
|
|
21
|
+
Requires-Python: >=3.11
|
|
22
|
+
Requires-Dist: httpx>=0.27
|
|
23
|
+
Provides-Extra: bluesky
|
|
24
|
+
Provides-Extra: django
|
|
25
|
+
Requires-Dist: django>=4.2; extra == 'django'
|
|
26
|
+
Provides-Extra: facebook
|
|
27
|
+
Provides-Extra: fastapi
|
|
28
|
+
Requires-Dist: fastapi>=0.110; extra == 'fastapi'
|
|
29
|
+
Provides-Extra: flask
|
|
30
|
+
Requires-Dist: flask>=3.0; extra == 'flask'
|
|
31
|
+
Provides-Extra: instagram
|
|
32
|
+
Provides-Extra: mastodon
|
|
33
|
+
Provides-Extra: pinterest
|
|
34
|
+
Provides-Extra: testing
|
|
35
|
+
Requires-Dist: pytest>=8.3; extra == 'testing'
|
|
36
|
+
Provides-Extra: threads
|
|
37
|
+
Provides-Extra: tiktok
|
|
38
|
+
Provides-Extra: x
|
|
39
|
+
Provides-Extra: youtube
|
|
40
|
+
Description-Content-Type: text/markdown
|
|
41
|
+
|
|
42
|
+
# socialchimp
|
|
43
|
+
|
|
44
|
+
[](https://github.com/raghulj/socialchimp/actions/workflows/ci.yml)
|
|
45
|
+
[](https://pypi.org/project/socialchimp/)
|
|
46
|
+
[](https://pypi.org/project/socialchimp/)
|
|
47
|
+
[](CONTRIBUTING.md)
|
|
48
|
+
[](pyproject.toml)
|
|
49
|
+
[](https://github.com/astral-sh/ruff)
|
|
50
|
+
[](LICENSE)
|
|
51
|
+
|
|
52
|
+
One simple way to connect your app to social networks.
|
|
53
|
+
|
|
54
|
+
> **Status: 0.1.0, the first release.** All nine networks below work. The way
|
|
55
|
+
> platforms are written is now settled - see
|
|
56
|
+
> [the promise about changes](docs/adding-a-platform.md#what-we-promise-about-changes)
|
|
57
|
+
> before you write your own.
|
|
58
|
+
|
|
59
|
+
**Mastodon · Bluesky · Facebook Pages · Instagram · YouTube · TikTok · X · Pinterest · Threads**
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## What it does
|
|
64
|
+
|
|
65
|
+
Your app needs to let people connect their social accounts, then post for
|
|
66
|
+
them and read what happens. Every network does this differently. socialchimp
|
|
67
|
+
gives you one way to do it, and gets out of the way when you need the network's
|
|
68
|
+
own features.
|
|
69
|
+
|
|
70
|
+
- **Connect accounts.** Sign in with Mastodon, Bluesky, Facebook, Instagram,
|
|
71
|
+
YouTube, TikTok, X, Pinterest, Threads and more.
|
|
72
|
+
- **Keep tokens working.** Refresh them before they expire, safely, even when
|
|
73
|
+
several workers run at once.
|
|
74
|
+
- **Post and read.** Text, pictures, video. Read posts and their numbers back.
|
|
75
|
+
- **Know what happened.** Comments and likes reach you the same way whether the
|
|
76
|
+
network pushes them to you or we have to check on a timer.
|
|
77
|
+
|
|
78
|
+
## What it does not do
|
|
79
|
+
|
|
80
|
+
- **It does not touch your database.** No models, no migrations. You write a
|
|
81
|
+
small storage class, socialchimp hands you data to save. Your schema stays
|
|
82
|
+
yours, and it works the same on Django, FastAPI, Flask, or nothing at all.
|
|
83
|
+
- **It does not pretend networks are the same.** Pinterest needs a board.
|
|
84
|
+
Bluesky cannot schedule. YouTube has no text-only post. Where networks
|
|
85
|
+
differ, the API says so instead of guessing for you.
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## Install
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
pip install socialchimp
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Add your framework if you want the ready-made routes:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
pip install "socialchimp[django]" # or [fastapi], or [flask]
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## A first look
|
|
102
|
+
|
|
103
|
+
```python
|
|
104
|
+
from socialchimp import SocialChimp, Post
|
|
105
|
+
|
|
106
|
+
sc = SocialChimp(storage=MyStorage())
|
|
107
|
+
|
|
108
|
+
# Post to a connected account.
|
|
109
|
+
account = sc.account(connection_id)
|
|
110
|
+
result = await account.post(Post(text="Hello from socialchimp"))
|
|
111
|
+
print(result.url)
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Need something only that network can do? Same connection, direct access:
|
|
115
|
+
|
|
116
|
+
```python
|
|
117
|
+
await account.direct.post(
|
|
118
|
+
"/api/v1/statuses",
|
|
119
|
+
json={"status": "Hello", "visibility": "unlisted"},
|
|
120
|
+
)
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Tokens, retries and rate limits are still handled for you. Only the request
|
|
124
|
+
is yours.
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## Documentation
|
|
129
|
+
|
|
130
|
+
- [Getting started](docs/getting-started.md) - from nothing to a post
|
|
131
|
+
- [Networks](docs/platforms.md) - what each one can do, and what it needs
|
|
132
|
+
- [Frameworks](docs/frameworks.md) - ready-made routes for Django,
|
|
133
|
+
FastAPI and Flask
|
|
134
|
+
- [Adding a platform](docs/adding-a-platform.md) - a network we do not
|
|
135
|
+
support yet
|
|
136
|
+
- [Plan](docs/PLAN.md) - what is built and what is coming
|
|
137
|
+
- [Changelog](CHANGELOG.md) - what changed, and what it means for you
|
|
138
|
+
- [Releasing](docs/releasing.md) - how a release goes out
|
|
139
|
+
- [Examples](examples/) - runnable programs
|
|
140
|
+
|
|
141
|
+
## Contributing
|
|
142
|
+
|
|
143
|
+
Contributions are welcome. A few things to know first:
|
|
144
|
+
|
|
145
|
+
- **Tests come first.** Write the failing test, then make it pass.
|
|
146
|
+
- **Coverage must stay at 100%.** CI fails below it.
|
|
147
|
+
- **Types must be strict.** `mypy --strict` with no ignores.
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
git clone https://github.com/raghulj/socialchimp
|
|
151
|
+
cd socialchimp
|
|
152
|
+
uv sync --all-extras --dev
|
|
153
|
+
uv run pre-commit install --hook-type pre-commit --hook-type pre-push
|
|
154
|
+
uv run pytest
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Licence
|
|
158
|
+
|
|
159
|
+
MIT. See [LICENSE](LICENSE).
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# socialchimp
|
|
2
|
+
|
|
3
|
+
[](https://github.com/raghulj/socialchimp/actions/workflows/ci.yml)
|
|
4
|
+
[](https://pypi.org/project/socialchimp/)
|
|
5
|
+
[](https://pypi.org/project/socialchimp/)
|
|
6
|
+
[](CONTRIBUTING.md)
|
|
7
|
+
[](pyproject.toml)
|
|
8
|
+
[](https://github.com/astral-sh/ruff)
|
|
9
|
+
[](LICENSE)
|
|
10
|
+
|
|
11
|
+
One simple way to connect your app to social networks.
|
|
12
|
+
|
|
13
|
+
> **Status: 0.1.0, the first release.** All nine networks below work. The way
|
|
14
|
+
> platforms are written is now settled - see
|
|
15
|
+
> [the promise about changes](docs/adding-a-platform.md#what-we-promise-about-changes)
|
|
16
|
+
> before you write your own.
|
|
17
|
+
|
|
18
|
+
**Mastodon · Bluesky · Facebook Pages · Instagram · YouTube · TikTok · X · Pinterest · Threads**
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## What it does
|
|
23
|
+
|
|
24
|
+
Your app needs to let people connect their social accounts, then post for
|
|
25
|
+
them and read what happens. Every network does this differently. socialchimp
|
|
26
|
+
gives you one way to do it, and gets out of the way when you need the network's
|
|
27
|
+
own features.
|
|
28
|
+
|
|
29
|
+
- **Connect accounts.** Sign in with Mastodon, Bluesky, Facebook, Instagram,
|
|
30
|
+
YouTube, TikTok, X, Pinterest, Threads and more.
|
|
31
|
+
- **Keep tokens working.** Refresh them before they expire, safely, even when
|
|
32
|
+
several workers run at once.
|
|
33
|
+
- **Post and read.** Text, pictures, video. Read posts and their numbers back.
|
|
34
|
+
- **Know what happened.** Comments and likes reach you the same way whether the
|
|
35
|
+
network pushes them to you or we have to check on a timer.
|
|
36
|
+
|
|
37
|
+
## What it does not do
|
|
38
|
+
|
|
39
|
+
- **It does not touch your database.** No models, no migrations. You write a
|
|
40
|
+
small storage class, socialchimp hands you data to save. Your schema stays
|
|
41
|
+
yours, and it works the same on Django, FastAPI, Flask, or nothing at all.
|
|
42
|
+
- **It does not pretend networks are the same.** Pinterest needs a board.
|
|
43
|
+
Bluesky cannot schedule. YouTube has no text-only post. Where networks
|
|
44
|
+
differ, the API says so instead of guessing for you.
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Install
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
pip install socialchimp
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Add your framework if you want the ready-made routes:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
pip install "socialchimp[django]" # or [fastapi], or [flask]
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## A first look
|
|
61
|
+
|
|
62
|
+
```python
|
|
63
|
+
from socialchimp import SocialChimp, Post
|
|
64
|
+
|
|
65
|
+
sc = SocialChimp(storage=MyStorage())
|
|
66
|
+
|
|
67
|
+
# Post to a connected account.
|
|
68
|
+
account = sc.account(connection_id)
|
|
69
|
+
result = await account.post(Post(text="Hello from socialchimp"))
|
|
70
|
+
print(result.url)
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Need something only that network can do? Same connection, direct access:
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
await account.direct.post(
|
|
77
|
+
"/api/v1/statuses",
|
|
78
|
+
json={"status": "Hello", "visibility": "unlisted"},
|
|
79
|
+
)
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Tokens, retries and rate limits are still handled for you. Only the request
|
|
83
|
+
is yours.
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## Documentation
|
|
88
|
+
|
|
89
|
+
- [Getting started](docs/getting-started.md) - from nothing to a post
|
|
90
|
+
- [Networks](docs/platforms.md) - what each one can do, and what it needs
|
|
91
|
+
- [Frameworks](docs/frameworks.md) - ready-made routes for Django,
|
|
92
|
+
FastAPI and Flask
|
|
93
|
+
- [Adding a platform](docs/adding-a-platform.md) - a network we do not
|
|
94
|
+
support yet
|
|
95
|
+
- [Plan](docs/PLAN.md) - what is built and what is coming
|
|
96
|
+
- [Changelog](CHANGELOG.md) - what changed, and what it means for you
|
|
97
|
+
- [Releasing](docs/releasing.md) - how a release goes out
|
|
98
|
+
- [Examples](examples/) - runnable programs
|
|
99
|
+
|
|
100
|
+
## Contributing
|
|
101
|
+
|
|
102
|
+
Contributions are welcome. A few things to know first:
|
|
103
|
+
|
|
104
|
+
- **Tests come first.** Write the failing test, then make it pass.
|
|
105
|
+
- **Coverage must stay at 100%.** CI fails below it.
|
|
106
|
+
- **Types must be strict.** `mypy --strict` with no ignores.
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
git clone https://github.com/raghulj/socialchimp
|
|
110
|
+
cd socialchimp
|
|
111
|
+
uv sync --all-extras --dev
|
|
112
|
+
uv run pre-commit install --hook-type pre-commit --hook-type pre-push
|
|
113
|
+
uv run pytest
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Licence
|
|
117
|
+
|
|
118
|
+
MIT. See [LICENSE](LICENSE).
|