lukhed-x 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.
- lukhed_x-0.1.0/LICENSE +21 -0
- lukhed_x-0.1.0/PKG-INFO +135 -0
- lukhed_x-0.1.0/README.md +121 -0
- lukhed_x-0.1.0/lukhed_x/__init__.py +3 -0
- lukhed_x-0.1.0/lukhed_x/x_api.py +267 -0
- lukhed_x-0.1.0/lukhed_x.egg-info/PKG-INFO +135 -0
- lukhed_x-0.1.0/lukhed_x.egg-info/SOURCES.txt +10 -0
- lukhed_x-0.1.0/lukhed_x.egg-info/dependency_links.txt +1 -0
- lukhed_x-0.1.0/lukhed_x.egg-info/requires.txt +2 -0
- lukhed_x-0.1.0/lukhed_x.egg-info/top_level.txt +1 -0
- lukhed_x-0.1.0/setup.cfg +4 -0
- lukhed_x-0.1.0/setup.py +24 -0
lukhed_x-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 lukhed
|
|
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.
|
lukhed_x-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: lukhed_x
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Custom tweepy wrapper for posting on X. Used by @grindSunday and @popPunkpoets Bots
|
|
5
|
+
Home-page: https://github.com/lukhed/lukhed_x
|
|
6
|
+
Author: lukhed
|
|
7
|
+
Author-email: lukhed.mail@gmail.com
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Requires-Python: >=3.9
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
|
|
15
|
+
# lukhed_x
|
|
16
|
+
|
|
17
|
+
A custom tweepy wrapper for posting on X (formerly Twitter) with built-in key management and enhanced functionality.
|
|
18
|
+
Used by @grindSunday and @popPunkPoets bots.
|
|
19
|
+
|
|
20
|
+
## Features
|
|
21
|
+
|
|
22
|
+
- **Easy X API Integration**: Simplified interface for X API v1 and v2 endpoints
|
|
23
|
+
- **Flexible Key Management**: Store API credentials locally or in GitHub repositories
|
|
24
|
+
- **Post Management**: Create, delete, and manage posts with media support
|
|
25
|
+
- **Image Upload Support**: Easy media attachment for posts
|
|
26
|
+
|
|
27
|
+
## Installation
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
pip install lukhed_x
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Quick Start
|
|
34
|
+
|
|
35
|
+
### Initial Setup
|
|
36
|
+
|
|
37
|
+
```python
|
|
38
|
+
from lukhed_x import X
|
|
39
|
+
|
|
40
|
+
# First-time setup - this will prompt for your X API credentials
|
|
41
|
+
x_client = X(handle="your_handle", x_api_setup=True)
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Basic Usage
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
from lukhed_x import X
|
|
48
|
+
|
|
49
|
+
# Initialize client (after initial setup)
|
|
50
|
+
x_client = X(handle="your_handle")
|
|
51
|
+
|
|
52
|
+
# Create a simple tweet
|
|
53
|
+
result = x_client.create_tweet("Hello, world!")
|
|
54
|
+
if not result["error"]:
|
|
55
|
+
print(f"Tweet posted: {result['url']}")
|
|
56
|
+
print(f"Tweet ID: {result['tweetID']}")
|
|
57
|
+
|
|
58
|
+
# Create tweet with image
|
|
59
|
+
result = x_client.create_tweet(
|
|
60
|
+
"Check out this image!",
|
|
61
|
+
image_data="path/to/image.jpg"
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
# Reply to a tweet
|
|
65
|
+
result = x_client.create_tweet(
|
|
66
|
+
".@username Thanks for the great post!",
|
|
67
|
+
reply_to_tweet_id="1234567890"
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
# Quote tweet
|
|
71
|
+
result = x_client.create_tweet(
|
|
72
|
+
"Great point!",
|
|
73
|
+
quote_tweet_id="1234567890"
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
# Delete a tweet
|
|
77
|
+
result = x_client.delete_tweet("your_tweet_id")
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## X API Setup
|
|
81
|
+
|
|
82
|
+
Before using lukhed_x, you need to set up an X Developer account:
|
|
83
|
+
|
|
84
|
+
1. Create a free developer account at [developer.x.com](https://developer.x.com/en)
|
|
85
|
+
2. Create a new app and generate your API credentials
|
|
86
|
+
3. You'll need:
|
|
87
|
+
- **API Key**
|
|
88
|
+
- **API Secret**
|
|
89
|
+
- **Access Token**
|
|
90
|
+
- **Access Token Secret**
|
|
91
|
+
|
|
92
|
+
For detailed instructions, visit: [X API Getting Started Guide](https://docs.x.com/x-api/getting-started/getting-access)
|
|
93
|
+
|
|
94
|
+
## Key Management Options
|
|
95
|
+
|
|
96
|
+
lukhed_x supports two key management strategies:
|
|
97
|
+
|
|
98
|
+
### Local Storage
|
|
99
|
+
```python
|
|
100
|
+
x_client = X(handle="your_handle", key_management="local")
|
|
101
|
+
```
|
|
102
|
+
Stores API credentials in your local file system.
|
|
103
|
+
|
|
104
|
+
### GitHub Storage (Default)
|
|
105
|
+
```python
|
|
106
|
+
x_client = X(handle="your_handle", key_management="github")
|
|
107
|
+
```
|
|
108
|
+
Stores API credentials in a private GitHub repository, allowing access across different devices. You will need a
|
|
109
|
+
github access token:
|
|
110
|
+
[Managing your personal access tokens](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens)
|
|
111
|
+
|
|
112
|
+
## Error Handling
|
|
113
|
+
|
|
114
|
+
All API methods return a consistent error structure:
|
|
115
|
+
|
|
116
|
+
```python
|
|
117
|
+
result = x_client.create_tweet("Hello!")
|
|
118
|
+
if result["error"]:
|
|
119
|
+
print("Function Error:", result["errorData"]["functionError"])
|
|
120
|
+
print("Tweepy Error:", result["errorData"]["tweepyError"])
|
|
121
|
+
else:
|
|
122
|
+
print("Success:", result["url"])
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## License
|
|
126
|
+
|
|
127
|
+
This project is licensed under the MIT License.
|
|
128
|
+
|
|
129
|
+
## Support
|
|
130
|
+
|
|
131
|
+
For issues and questions, please open an issue on the GitHub repository.
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
**Note**: This wrapper is designed for legitimate bot usage and follows X's Terms of Service.
|
|
135
|
+
Please ensure your bot complies with X's automation rules and rate limits.
|
lukhed_x-0.1.0/README.md
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# lukhed_x
|
|
2
|
+
|
|
3
|
+
A custom tweepy wrapper for posting on X (formerly Twitter) with built-in key management and enhanced functionality.
|
|
4
|
+
Used by @grindSunday and @popPunkPoets bots.
|
|
5
|
+
|
|
6
|
+
## Features
|
|
7
|
+
|
|
8
|
+
- **Easy X API Integration**: Simplified interface for X API v1 and v2 endpoints
|
|
9
|
+
- **Flexible Key Management**: Store API credentials locally or in GitHub repositories
|
|
10
|
+
- **Post Management**: Create, delete, and manage posts with media support
|
|
11
|
+
- **Image Upload Support**: Easy media attachment for posts
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pip install lukhed_x
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Quick Start
|
|
20
|
+
|
|
21
|
+
### Initial Setup
|
|
22
|
+
|
|
23
|
+
```python
|
|
24
|
+
from lukhed_x import X
|
|
25
|
+
|
|
26
|
+
# First-time setup - this will prompt for your X API credentials
|
|
27
|
+
x_client = X(handle="your_handle", x_api_setup=True)
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Basic Usage
|
|
31
|
+
|
|
32
|
+
```python
|
|
33
|
+
from lukhed_x import X
|
|
34
|
+
|
|
35
|
+
# Initialize client (after initial setup)
|
|
36
|
+
x_client = X(handle="your_handle")
|
|
37
|
+
|
|
38
|
+
# Create a simple tweet
|
|
39
|
+
result = x_client.create_tweet("Hello, world!")
|
|
40
|
+
if not result["error"]:
|
|
41
|
+
print(f"Tweet posted: {result['url']}")
|
|
42
|
+
print(f"Tweet ID: {result['tweetID']}")
|
|
43
|
+
|
|
44
|
+
# Create tweet with image
|
|
45
|
+
result = x_client.create_tweet(
|
|
46
|
+
"Check out this image!",
|
|
47
|
+
image_data="path/to/image.jpg"
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
# Reply to a tweet
|
|
51
|
+
result = x_client.create_tweet(
|
|
52
|
+
".@username Thanks for the great post!",
|
|
53
|
+
reply_to_tweet_id="1234567890"
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
# Quote tweet
|
|
57
|
+
result = x_client.create_tweet(
|
|
58
|
+
"Great point!",
|
|
59
|
+
quote_tweet_id="1234567890"
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
# Delete a tweet
|
|
63
|
+
result = x_client.delete_tweet("your_tweet_id")
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## X API Setup
|
|
67
|
+
|
|
68
|
+
Before using lukhed_x, you need to set up an X Developer account:
|
|
69
|
+
|
|
70
|
+
1. Create a free developer account at [developer.x.com](https://developer.x.com/en)
|
|
71
|
+
2. Create a new app and generate your API credentials
|
|
72
|
+
3. You'll need:
|
|
73
|
+
- **API Key**
|
|
74
|
+
- **API Secret**
|
|
75
|
+
- **Access Token**
|
|
76
|
+
- **Access Token Secret**
|
|
77
|
+
|
|
78
|
+
For detailed instructions, visit: [X API Getting Started Guide](https://docs.x.com/x-api/getting-started/getting-access)
|
|
79
|
+
|
|
80
|
+
## Key Management Options
|
|
81
|
+
|
|
82
|
+
lukhed_x supports two key management strategies:
|
|
83
|
+
|
|
84
|
+
### Local Storage
|
|
85
|
+
```python
|
|
86
|
+
x_client = X(handle="your_handle", key_management="local")
|
|
87
|
+
```
|
|
88
|
+
Stores API credentials in your local file system.
|
|
89
|
+
|
|
90
|
+
### GitHub Storage (Default)
|
|
91
|
+
```python
|
|
92
|
+
x_client = X(handle="your_handle", key_management="github")
|
|
93
|
+
```
|
|
94
|
+
Stores API credentials in a private GitHub repository, allowing access across different devices. You will need a
|
|
95
|
+
github access token:
|
|
96
|
+
[Managing your personal access tokens](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens)
|
|
97
|
+
|
|
98
|
+
## Error Handling
|
|
99
|
+
|
|
100
|
+
All API methods return a consistent error structure:
|
|
101
|
+
|
|
102
|
+
```python
|
|
103
|
+
result = x_client.create_tweet("Hello!")
|
|
104
|
+
if result["error"]:
|
|
105
|
+
print("Function Error:", result["errorData"]["functionError"])
|
|
106
|
+
print("Tweepy Error:", result["errorData"]["tweepyError"])
|
|
107
|
+
else:
|
|
108
|
+
print("Success:", result["url"])
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## License
|
|
112
|
+
|
|
113
|
+
This project is licensed under the MIT License.
|
|
114
|
+
|
|
115
|
+
## Support
|
|
116
|
+
|
|
117
|
+
For issues and questions, please open an issue on the GitHub repository.
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
**Note**: This wrapper is designed for legitimate bot usage and follows X's Terms of Service.
|
|
121
|
+
Please ensure your bot complies with X's automation rules and rate limits.
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
from lukhed_basic_utils.githubCommon import KeyManager
|
|
3
|
+
from lukhed_basic_utils import osCommon as osC
|
|
4
|
+
import tweepy
|
|
5
|
+
import time
|
|
6
|
+
import re
|
|
7
|
+
|
|
8
|
+
# https://docs.tweepy.org/en/v3.10.0/api.html
|
|
9
|
+
# https://developer.twitter.com/en/docs/twitter-api/v1/rate-limits
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class X():
|
|
14
|
+
def __init__(self, handle, key_management='github', x_api_setup=False):
|
|
15
|
+
"""
|
|
16
|
+
This class is a custom tweepy wrapper for posting on X (formerly Twitter). It includes key management and
|
|
17
|
+
basic endpoints.
|
|
18
|
+
|
|
19
|
+
Parameters
|
|
20
|
+
----------
|
|
21
|
+
handle : str
|
|
22
|
+
The Twitter handle to use for API requests.
|
|
23
|
+
key_management : str, optional
|
|
24
|
+
The strategy key management strategy to use. Options are:
|
|
25
|
+
'local' - stores/retrieve your api key on your local hard drive (working directory)
|
|
26
|
+
'github' - stores/retrieves your api key in a private repo (helpful to allow access across different hardware)
|
|
27
|
+
Default is 'github'.
|
|
28
|
+
x_api_setup : bool, optional
|
|
29
|
+
Set this to true for initial setup of the X API credentials. You will be prompted to enter your
|
|
30
|
+
API information from https://developer.x.com/en.
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
# class variables
|
|
34
|
+
osC.check_create_dir_structure(['lukhedConfig'])
|
|
35
|
+
self.key_management = key_management.lower()
|
|
36
|
+
self._token_file_path = osC.create_file_path_string(['lukhedConfig', 'localTokenFile.json'])
|
|
37
|
+
self.current_handle = handle
|
|
38
|
+
self._parse_handle()
|
|
39
|
+
self._key_data = {}
|
|
40
|
+
self.current_version = 2
|
|
41
|
+
|
|
42
|
+
# Objects used
|
|
43
|
+
self.tweepy_api: Optional[tweepy.Client] = None
|
|
44
|
+
self._kM: Optional[KeyManager] = None
|
|
45
|
+
|
|
46
|
+
# One time setup option
|
|
47
|
+
if x_api_setup:
|
|
48
|
+
self._x_api_setup()
|
|
49
|
+
|
|
50
|
+
# Load access data
|
|
51
|
+
self._check_create_km()
|
|
52
|
+
|
|
53
|
+
self._tweepy_generate_api(self.current_version)
|
|
54
|
+
|
|
55
|
+
def _x_api_setup(self):
|
|
56
|
+
print("This is the lukhed setup for the X API. If you haven't already, you first need to setup an"
|
|
57
|
+
" X api developer acccount (free here: https://developer.x.com/en). To continue, you need the following"
|
|
58
|
+
" from the setup:\n"
|
|
59
|
+
"1. Access Token\n"
|
|
60
|
+
"2. Access Token Secret\n"
|
|
61
|
+
"3. Api Key\n"
|
|
62
|
+
"4. Api Secret\n"
|
|
63
|
+
"If you don't know how to get these, you can find instructions here:\n"
|
|
64
|
+
"https://docs.x.com/x-api/getting-started/getting-access")
|
|
65
|
+
|
|
66
|
+
if input("\n\nAre you ready to continue (y/n)?") == 'n':
|
|
67
|
+
print("OK, come back when you have setup your developer account")
|
|
68
|
+
quit()
|
|
69
|
+
|
|
70
|
+
access_token = input("Paste your access token then press enter:\n").replace(" ", "")
|
|
71
|
+
access_token_secret = input("Paste your access token secret then press enter:\n").replace(" ", "")
|
|
72
|
+
api_key = input("Paste your API key here:\n").replace(" ", "")
|
|
73
|
+
api_secret = input("Paste your API secret here:\n").replace(" ", "")
|
|
74
|
+
|
|
75
|
+
self._key_data[self.current_handle] = dict()
|
|
76
|
+
self._key_data[self.current_handle]['accessToken'] = access_token
|
|
77
|
+
self._key_data[self.current_handle]['accessTokenSecret'] = access_token_secret
|
|
78
|
+
self._key_data[self.current_handle]['apiKey'] = api_key
|
|
79
|
+
self._key_data[self.current_handle]['apiSecret'] = api_secret
|
|
80
|
+
|
|
81
|
+
print("\n\nThe X portion is complete! Now setting up key management with lukhed library...")
|
|
82
|
+
self._kM = KeyManager('xApi', config_file_preference=self.key_management,
|
|
83
|
+
provide_key_data=self._key_data)
|
|
84
|
+
|
|
85
|
+
def _check_create_km(self):
|
|
86
|
+
if self._kM is None:
|
|
87
|
+
# get the key data previously setup
|
|
88
|
+
self._kM = KeyManager('xApi', config_file_preference=self.key_management)
|
|
89
|
+
self._key_data = self._kM.key_data
|
|
90
|
+
|
|
91
|
+
def _parse_handle(self):
|
|
92
|
+
# accept a handle with or without the @symbol
|
|
93
|
+
if "@" not in self.current_handle:
|
|
94
|
+
self.current_handle = "@" + self.current_handle
|
|
95
|
+
|
|
96
|
+
def _tweepy_generate_api(self, version):
|
|
97
|
+
self.current_version = version
|
|
98
|
+
key_data = self._key_data[self.current_handle]
|
|
99
|
+
if version == 2:
|
|
100
|
+
"""
|
|
101
|
+
https://docs.tweepy.org/en/stable/authentication.html#id3
|
|
102
|
+
need user context to unlock all methods
|
|
103
|
+
"""
|
|
104
|
+
return tweepy.Client(consumer_key=key_data["apiKey"],
|
|
105
|
+
consumer_secret=key_data["apiSecret"],
|
|
106
|
+
access_token=key_data["accessToken"],
|
|
107
|
+
access_token_secret=key_data["accessTokenSecret"])
|
|
108
|
+
elif version == 1:
|
|
109
|
+
auth = tweepy.OAuthHandler(key_data['apiKey'], key_data['apiSecret'])
|
|
110
|
+
auth.set_access_token(key_data['accessToken'], key_data['accessTokenSecret'])
|
|
111
|
+
|
|
112
|
+
return tweepy.API(auth)
|
|
113
|
+
else:
|
|
114
|
+
return None
|
|
115
|
+
|
|
116
|
+
def _check_create_tweepy_api(self, version_int):
|
|
117
|
+
"""
|
|
118
|
+
This function creates the tweepy api based on the twitter API version requested.
|
|
119
|
+
The free twitter API currently supports v2 endpoints but allows access to some v1 endpoints still
|
|
120
|
+
|
|
121
|
+
:param version_int: int(), 1 or 2
|
|
122
|
+
:return:
|
|
123
|
+
"""
|
|
124
|
+
# Create a twitter API if one does not exist or if the current api version is not correct for the method
|
|
125
|
+
if self.tweepy_api is None or version_int != self.current_version:
|
|
126
|
+
self.tweepy_api = self._tweepy_generate_api(version_int)
|
|
127
|
+
|
|
128
|
+
def _try_print_tweepy_exception(self, tweepy_exception):
|
|
129
|
+
"""
|
|
130
|
+
:param tweepy_exception:
|
|
131
|
+
:return:
|
|
132
|
+
"""
|
|
133
|
+
print("Trying to print exception:")
|
|
134
|
+
|
|
135
|
+
try:
|
|
136
|
+
print(tweepy_exception)
|
|
137
|
+
tweepy_defined_error_message = tweepy_exception
|
|
138
|
+
except:
|
|
139
|
+
tweepy_defined_error_message = "failed getting the tweepy defined error message"
|
|
140
|
+
print(tweepy_defined_error_message)
|
|
141
|
+
|
|
142
|
+
return tweepy_defined_error_message
|
|
143
|
+
|
|
144
|
+
def _parse_image_data(self, image_data):
|
|
145
|
+
media_ids = []
|
|
146
|
+
if type(image_data) is list:
|
|
147
|
+
for i in image_data:
|
|
148
|
+
media = self.tweepy_api.media_upload(i)
|
|
149
|
+
media_ids.append(media.media_id)
|
|
150
|
+
else:
|
|
151
|
+
media = self.tweepy_api.media_upload(image_data)
|
|
152
|
+
media_ids.append(media.media_id)
|
|
153
|
+
|
|
154
|
+
return media_ids
|
|
155
|
+
|
|
156
|
+
#######################
|
|
157
|
+
# Free with API
|
|
158
|
+
def create_tweet(self, tweet_message_str, reply_to_tweet_id=None, image_data=None, quote_tweet_id=None):
|
|
159
|
+
"""
|
|
160
|
+
This function creates a tweet. It uses v2 twitter endpoints and comes with the Basic (free) plan. All accounts
|
|
161
|
+
can use this functionality.
|
|
162
|
+
|
|
163
|
+
Tweepy doc is here:
|
|
164
|
+
https://docs.tweepy.org/en/stable/client.html#tweepy.Client.create_tweet
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
:param tweet_message_str: text you want to tweet
|
|
168
|
+
|
|
169
|
+
:param reply_to_tweet_id: tweet ID you want to reply to. Note: if this is supplied,
|
|
170
|
+
@[handle_replying_to] must be in tweet text for it to show up in the
|
|
171
|
+
replies
|
|
172
|
+
|
|
173
|
+
:param image_data: list or image. Image can be path to image or actual image
|
|
174
|
+
|
|
175
|
+
:param quote_tweet_id: to quote tweet, put the id here
|
|
176
|
+
|
|
177
|
+
:return: success bool and tweepy response if applicable
|
|
178
|
+
"""
|
|
179
|
+
|
|
180
|
+
try:
|
|
181
|
+
if image_data is not None:
|
|
182
|
+
self._check_create_tweepy_api(1)
|
|
183
|
+
media_ids = self._parse_image_data(image_data)
|
|
184
|
+
else:
|
|
185
|
+
media_ids = None
|
|
186
|
+
|
|
187
|
+
self._check_create_tweepy_api(2)
|
|
188
|
+
status_update = self.tweepy_api.create_tweet(text=tweet_message_str, in_reply_to_tweet_id=reply_to_tweet_id,
|
|
189
|
+
media_ids=media_ids, quote_tweet_id=quote_tweet_id)
|
|
190
|
+
|
|
191
|
+
tweet_url = "https://twitter.com/" + self.current_handle.replace("@", "") + "/status/" + \
|
|
192
|
+
status_update.data['id']
|
|
193
|
+
tweet_id = status_update.data['id']
|
|
194
|
+
except Exception as e:
|
|
195
|
+
function_defined_error_message = "Failed while trying to tweet. self.tweepy_api.create_tweet"
|
|
196
|
+
print(function_defined_error_message)
|
|
197
|
+
|
|
198
|
+
tweepy_defined_error_message = self._try_print_tweepy_exception(e)
|
|
199
|
+
|
|
200
|
+
return {"error": True,
|
|
201
|
+
"twitterResponse": None,
|
|
202
|
+
"errorData": {"functionError": function_defined_error_message,
|
|
203
|
+
"tweepyError": tweepy_defined_error_message}}
|
|
204
|
+
|
|
205
|
+
return {"error": False,
|
|
206
|
+
"twitterResponse": status_update,
|
|
207
|
+
"errorData": None,
|
|
208
|
+
"url": tweet_url,
|
|
209
|
+
"tweetID": tweet_id,
|
|
210
|
+
"tweetHandle": self.current_handle}
|
|
211
|
+
|
|
212
|
+
def delete_tweet(self, tweet_id):
|
|
213
|
+
"""
|
|
214
|
+
This function deletes a tweet. It uses v2 twitter endpoints and comes with the Basic (free) plan. All accounts
|
|
215
|
+
can use this functionality.
|
|
216
|
+
|
|
217
|
+
Tweepy doc is here:
|
|
218
|
+
https://docs.tweepy.org/en/stable/client.html#tweepy.Client.delete_tweet
|
|
219
|
+
|
|
220
|
+
:param tweet_id:
|
|
221
|
+
:return:
|
|
222
|
+
"""
|
|
223
|
+
|
|
224
|
+
self._check_create_tweepy_api(2)
|
|
225
|
+
try:
|
|
226
|
+
twitter_response = self.tweepy_api.delete_tweet(tweet_id)
|
|
227
|
+
except Exception as e:
|
|
228
|
+
function_defined_error_message = "Failed while trying to delete tweet. self.tweepy_api.delete_tweet"
|
|
229
|
+
print(function_defined_error_message)
|
|
230
|
+
tweepy_defined_error_message = self._try_print_tweepy_exception(e)
|
|
231
|
+
|
|
232
|
+
return {"error": True,
|
|
233
|
+
"twitterResponse": None,
|
|
234
|
+
"errorData": {"functionError": function_defined_error_message,
|
|
235
|
+
"tweepyError": tweepy_defined_error_message}}
|
|
236
|
+
|
|
237
|
+
return {"error": False,
|
|
238
|
+
"twitterResponse": twitter_response,
|
|
239
|
+
"errorData": None}
|
|
240
|
+
|
|
241
|
+
def get_my_user_info(self):
|
|
242
|
+
"""
|
|
243
|
+
This function gets a variety of information about the current authorized user.
|
|
244
|
+
It uses v2 twitter endpoints and comes with the Basic (free) plan. All accounts can use this functionality.
|
|
245
|
+
|
|
246
|
+
Tweepy doc is here:
|
|
247
|
+
https://docs.tweepy.org/en/stable/client.html#tweepy.Client.get_me
|
|
248
|
+
|
|
249
|
+
:return:
|
|
250
|
+
"""
|
|
251
|
+
|
|
252
|
+
self._check_create_tweepy_api(2)
|
|
253
|
+
try:
|
|
254
|
+
twitter_response = self.tweepy_api.get_me()
|
|
255
|
+
except Exception as e:
|
|
256
|
+
function_defined_error_message = "Failed while trying lookup user. self.tweepy_api.get_user"
|
|
257
|
+
print(function_defined_error_message)
|
|
258
|
+
tweepy_defined_error_message = self._try_print_tweepy_exception(e)
|
|
259
|
+
|
|
260
|
+
return {"error": True,
|
|
261
|
+
"twitterResponse": None,
|
|
262
|
+
"errorData": {"functionError": function_defined_error_message,
|
|
263
|
+
"tweepyError": tweepy_defined_error_message}}
|
|
264
|
+
|
|
265
|
+
return {"error": False,
|
|
266
|
+
"twitterResponse": twitter_response,
|
|
267
|
+
"errorData": None}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: lukhed-x
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Custom tweepy wrapper for posting on X. Used by @grindSunday and @popPunkpoets Bots
|
|
5
|
+
Home-page: https://github.com/lukhed/lukhed_x
|
|
6
|
+
Author: lukhed
|
|
7
|
+
Author-email: lukhed.mail@gmail.com
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Requires-Python: >=3.9
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
|
|
15
|
+
# lukhed_x
|
|
16
|
+
|
|
17
|
+
A custom tweepy wrapper for posting on X (formerly Twitter) with built-in key management and enhanced functionality.
|
|
18
|
+
Used by @grindSunday and @popPunkPoets bots.
|
|
19
|
+
|
|
20
|
+
## Features
|
|
21
|
+
|
|
22
|
+
- **Easy X API Integration**: Simplified interface for X API v1 and v2 endpoints
|
|
23
|
+
- **Flexible Key Management**: Store API credentials locally or in GitHub repositories
|
|
24
|
+
- **Post Management**: Create, delete, and manage posts with media support
|
|
25
|
+
- **Image Upload Support**: Easy media attachment for posts
|
|
26
|
+
|
|
27
|
+
## Installation
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
pip install lukhed_x
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Quick Start
|
|
34
|
+
|
|
35
|
+
### Initial Setup
|
|
36
|
+
|
|
37
|
+
```python
|
|
38
|
+
from lukhed_x import X
|
|
39
|
+
|
|
40
|
+
# First-time setup - this will prompt for your X API credentials
|
|
41
|
+
x_client = X(handle="your_handle", x_api_setup=True)
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Basic Usage
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
from lukhed_x import X
|
|
48
|
+
|
|
49
|
+
# Initialize client (after initial setup)
|
|
50
|
+
x_client = X(handle="your_handle")
|
|
51
|
+
|
|
52
|
+
# Create a simple tweet
|
|
53
|
+
result = x_client.create_tweet("Hello, world!")
|
|
54
|
+
if not result["error"]:
|
|
55
|
+
print(f"Tweet posted: {result['url']}")
|
|
56
|
+
print(f"Tweet ID: {result['tweetID']}")
|
|
57
|
+
|
|
58
|
+
# Create tweet with image
|
|
59
|
+
result = x_client.create_tweet(
|
|
60
|
+
"Check out this image!",
|
|
61
|
+
image_data="path/to/image.jpg"
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
# Reply to a tweet
|
|
65
|
+
result = x_client.create_tweet(
|
|
66
|
+
".@username Thanks for the great post!",
|
|
67
|
+
reply_to_tweet_id="1234567890"
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
# Quote tweet
|
|
71
|
+
result = x_client.create_tweet(
|
|
72
|
+
"Great point!",
|
|
73
|
+
quote_tweet_id="1234567890"
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
# Delete a tweet
|
|
77
|
+
result = x_client.delete_tweet("your_tweet_id")
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## X API Setup
|
|
81
|
+
|
|
82
|
+
Before using lukhed_x, you need to set up an X Developer account:
|
|
83
|
+
|
|
84
|
+
1. Create a free developer account at [developer.x.com](https://developer.x.com/en)
|
|
85
|
+
2. Create a new app and generate your API credentials
|
|
86
|
+
3. You'll need:
|
|
87
|
+
- **API Key**
|
|
88
|
+
- **API Secret**
|
|
89
|
+
- **Access Token**
|
|
90
|
+
- **Access Token Secret**
|
|
91
|
+
|
|
92
|
+
For detailed instructions, visit: [X API Getting Started Guide](https://docs.x.com/x-api/getting-started/getting-access)
|
|
93
|
+
|
|
94
|
+
## Key Management Options
|
|
95
|
+
|
|
96
|
+
lukhed_x supports two key management strategies:
|
|
97
|
+
|
|
98
|
+
### Local Storage
|
|
99
|
+
```python
|
|
100
|
+
x_client = X(handle="your_handle", key_management="local")
|
|
101
|
+
```
|
|
102
|
+
Stores API credentials in your local file system.
|
|
103
|
+
|
|
104
|
+
### GitHub Storage (Default)
|
|
105
|
+
```python
|
|
106
|
+
x_client = X(handle="your_handle", key_management="github")
|
|
107
|
+
```
|
|
108
|
+
Stores API credentials in a private GitHub repository, allowing access across different devices. You will need a
|
|
109
|
+
github access token:
|
|
110
|
+
[Managing your personal access tokens](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens)
|
|
111
|
+
|
|
112
|
+
## Error Handling
|
|
113
|
+
|
|
114
|
+
All API methods return a consistent error structure:
|
|
115
|
+
|
|
116
|
+
```python
|
|
117
|
+
result = x_client.create_tweet("Hello!")
|
|
118
|
+
if result["error"]:
|
|
119
|
+
print("Function Error:", result["errorData"]["functionError"])
|
|
120
|
+
print("Tweepy Error:", result["errorData"]["tweepyError"])
|
|
121
|
+
else:
|
|
122
|
+
print("Success:", result["url"])
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## License
|
|
126
|
+
|
|
127
|
+
This project is licensed under the MIT License.
|
|
128
|
+
|
|
129
|
+
## Support
|
|
130
|
+
|
|
131
|
+
For issues and questions, please open an issue on the GitHub repository.
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
**Note**: This wrapper is designed for legitimate bot usage and follows X's Terms of Service.
|
|
135
|
+
Please ensure your bot complies with X's automation rules and rate limits.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
lukhed_x
|
lukhed_x-0.1.0/setup.cfg
ADDED
lukhed_x-0.1.0/setup.py
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
from setuptools import setup, find_packages
|
|
2
|
+
|
|
3
|
+
setup(
|
|
4
|
+
name="lukhed_x",
|
|
5
|
+
version="0.1.0",
|
|
6
|
+
description="Custom tweepy wrapper for posting on X. Used by @grindSunday and @popPunkpoets Bots",
|
|
7
|
+
long_description=open("README.md").read(),
|
|
8
|
+
long_description_content_type="text/markdown",
|
|
9
|
+
author="lukhed",
|
|
10
|
+
author_email="lukhed.mail@gmail.com",
|
|
11
|
+
url="https://github.com/lukhed/lukhed_x",
|
|
12
|
+
packages=find_packages(),
|
|
13
|
+
include_package_data=True, # Ensures MANIFEST.in is used
|
|
14
|
+
python_requires=">=3.9",
|
|
15
|
+
classifiers=[
|
|
16
|
+
"Programming Language :: Python :: 3",
|
|
17
|
+
"License :: OSI Approved :: MIT License",
|
|
18
|
+
"Operating System :: OS Independent",
|
|
19
|
+
],
|
|
20
|
+
install_requires=[
|
|
21
|
+
"lukhed-basic-utils>=1.6.4",
|
|
22
|
+
"tweepy>=4.16.0",
|
|
23
|
+
],
|
|
24
|
+
)
|