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
6 changes: 3 additions & 3 deletions .github/workflows/docs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: 3.8
python-version: 3.12
- run: pip install mkdocs-material
- run: mkdocs gh-deploy -f docs/mkdocs.yml --force
6 changes: 3 additions & 3 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Build and publish to pypi
uses: JRubics/poetry-publish@v1.17
uses: JRubics/poetry-publish@v2.1
with:
pypi_token: ${{ secrets.PYPI_TOKEN }}

Expand All @@ -19,7 +19,7 @@ jobs:
.github/hack/changelog.sh $VERSION > NEW-VERSION-CHANGELOG.md

- name: Publish
uses: softprops/action-gh-release@v1
uses: softprops/action-gh-release@v2
with:
body_path: NEW-VERSION-CHANGELOG.md
files: 'python-twitter-*'
Expand Down
20 changes: 10 additions & 10 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,19 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.7', '3.8', '3.9', '3.10', '3.11', '3.12']
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12']
include:
- python-version: '3.10'
- python-version: '3.12'
update-coverage: true

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Cache pip
uses: actions/cache@v2
uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ matrix.python-version }}-poetry-${{ hashFiles('pyproject.toml') }}
Expand All @@ -48,15 +48,15 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.10'
python-version: '3.8'
- name: Cache pip
uses: actions/cache@v2
uses: actions/cache@v4
with:
path: ~/.cache/pip
key: lintenv-v2
key: lintenv-v2-38
- name: Install dependencies
run: python -m pip install --upgrade pip black
- name: Black test
Expand Down
91 changes: 91 additions & 0 deletions docs/docs/usage/media-upload-v2/chunked-upload.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
This guide will help you make your first requests to upload media using the X API v2 media upload endpoint(s).

You can get more information for this at [docs](https://docs.x.com/x-api/media/quickstart/media-upload-chunked)

For video or chunked uploads, you must:

1. Initialize the upload using the `INIT` command
2. Upload each chunk of bytes using the `APPEND` command
3. Complete the upload using the `FINALIZE` command

let's do it, Now we need to upload a big video with a filename `/path/to/video.mp4`

### Step 1: Initialize the upload

As first step, you need to initialize the upload.

```python

import os

filename = "/path/to/video.mp4"

init_resp = myapi.upload_media_chunked_init_v2(
total_bytes=os.path.getsize(filename),
media_type="video/mp4",
media_category="tweet_video",
)
print(init_resp)
# Response(data=MediaUpload(id='1912334964932374529', media_key='7_1912334964932374529', processing_info=None, image=None, video=None))
```

### Step 2: Append the file by chunks

Once we have the media identifiers `id` from the `init_resp`, we can start uploading the file by chunks.

```python

media_id = init_resp.data.id

chunk_size = 2 * 1024 * 1024
segment_index = 0
with open(filename, "rb") as f:
while True:
chunk = f.read(chunk_size)
if not chunk:
break

chunk_resp = myapi.upload_media_chunked_append_v2(
media_id=media_id,
media=chunk,
segment_index=segment_index,
)
print(chunk_resp)
segment_index += 1

# True
```

### Step 3: Finalize the upload

Everything is ok, we need finalize the upload.

```python
finalize_resp = myapi.upload_media_chunked_finalize_v2(media_id=media_id)
print(finalize_resp)
# Response(data=MediaUpload(id='1912090619981471744', media_key='7_1912090619981471744', processing_info=MediaUploadResponseProcessingInfo(state='succeeded', check_after_secs=None, progress_percent=None, error=None), image=None, video=None))
```

### Step 4 (Optional): Check the processing status

Once you have finalized the upload, you can check the processing status.

```python
status_resp = myapi.upload_media_chunked_status_v2(media_id=media_id)
print(status_resp)
# Response(data=MediaUpload(id='1912090619981471744', media_key='7_1912090619981471744', processing_info=MediaUploadResponseProcessingInfo(state='succeeded', check_after_secs=None, progress_percent=100, error=None), image=None, video=None))
```

### Step 5: Create tweet with media

Congratulations, you have uploaded a video using the X API v2 media upload endpoint(s).

Now we can create a tweet with this video.

```python
tweet_resp = myapi.create_tweet(text="My first tweet with a video", media_media_ids=[media_id])

# Tweet(id=1912338879258194343, text=My first tweet with a video...)
```

Enjoy it!
13 changes: 13 additions & 0 deletions docs/docs/usage/media-upload-v2/simple-upload.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
You can use media upload endpoint to upload simple media, images(gifs).

You can get more information for this at [docs](https://docs.x.com/x-api/media/media-upload)

## upload simple

```python

with open("path/to/image", "rb") as media:
resp = my_api.upload_media_simple_v2(media=media)
print(resp)
```

4 changes: 4 additions & 0 deletions docs/mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ nav:
- Media Upload:
- Simple Upload: usage/media-upload/simple-upload.md
- Chunked Upload: usage/media-upload/chunked-upload.md

- Media Upload V2:
- Simple Upload: usage/media-upload-v2/simple-upload.md
- Chunked Upload: usage/media-upload-v2/chunked-upload.md
- Tweets:
- Tweet Lookup: usage/tweets/tweet-lookup.md
- Manage Tweets: usage/tweets/tweet-manage.md
Expand Down
64 changes: 64 additions & 0 deletions examples/media_upload_v2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
"""
Upload a video with media upload v2
"""

import os

from pytwitter import Api

consumer_key = "your app consumer key"
consumer_secret = "your app consumer secret"
access_token = "your access token"
access_secret = "your access token secret"

# init api with OAuth1.0
api = Api(
consumer_key=consumer_key,
consumer_secret=consumer_secret,
access_token=access_token,
access_secret=access_secret,
)

video_path = "path/to/video.mp4"

# init media upload

init_resp = api.upload_media_chunked_init_v2(
total_bytes=os.path.getsize(video_path),
media_type="video/mp4",
media_category="tweet_video",
)

print(f"Init response: {init_resp}")

# upload by chunk
chunk_size = 1024 * 1024 * 1
segment_index = 0

with open(video_path, "rb") as f:
while True:
chunk = f.read(chunk_size)
if not chunk:
break

chunk_resp = api.upload_media_chunked_append_v2(
media_id=init_resp.data.id,
segment_index=segment_index,
media=chunk,
)
print(f"Chunk response: {chunk_resp}")

print("Finished chunk upload")

# finalize upload
finalize_resp = api.upload_media_chunked_finalize_v2(
media_id=init_resp.data.id,
)
print(f"Finalize response: {finalize_resp}")

# Now you can use the media to create tweet
tweet_resp = api.create_tweet(
text="Tweet with video", media_media_ids=[init_resp.data.id]
)

print(f"Tweet response: {tweet_resp}")
Loading