stanvanrooy / instauto Goto Github PK
View Code? Open in Web Editor NEWSimple to use wrapper around the private Instagram API, written in Python.
Home Page: https://instauto.readthedocs.io
License: MIT License
Simple to use wrapper around the private Instagram API, written in Python.
Home Page: https://instauto.readthedocs.io
License: MIT License
I installed all the requirements and the library and when I try importing it I get this error:
Traceback (most recent call last): File "insta.py", line 13, in <module> from instauto import ApiClient File "/home/pi/.local/lib/python3.7/site-packages/instauto/__init__.py", line 2, in <module> from .api.client import ApiClient File "/home/pi/.local/lib/python3.7/site-packages/instauto/api/client.py", line 16, in <module> from .actions import AuthenticationMixIn, PostMixin, RequestMixIn, ProfileMixin, FriendshipsMixin, SearchMixin File "/home/pi/.local/lib/python3.7/site-packages/instauto/api/actions/__init__.py", line 3, in <module> from .request import RequestMixIn File "/home/pi/.local/lib/python3.7/site-packages/instauto/api/actions/request.py", line 93 if www_claim := headers.get('ig-set-www-claim'): self.state.www_claim = www_claim ^ SyntaxError: invalid syntax
See original_requests/friendships
for reference. Needed for tests.
See https://github.com/stanvanrooy/instauto/blob/master/docs/dev_environment.md for setting up an environment where you can listen to requests.
Fails with {'message': 'Missing info.', 'status': 'fail'}
. To reproduce:
obj = pst.Post.create(path='./to_upload.png', source_type=WhereToPost.Feed, caption="Hey!")
resp = self._client.post_post(obj, quality=100)
resp_as_json = resp.json()
self.assertTrue(resp_as_json['status'] == 'ok')
Write a few lines on which tools to use, where to download, how to install and which versions to use.
PostGetCommenters
. Add in pagination functionality, like PostRetrieveByUserDEPENDS ON #15
i can really share a post
this is my code
client = ApiClient(user_name=os.environ.get("INSTAUTO_USER") or "your_username", password=os.environ.get("INSTAUTO_PASS") or "your_password")
client.login()
client.save_to_disk('./.instauto.save')
post = ps.Post.create(
path='./black_square.jpg',
source_type=st.WhereToPost.Feed,
caption='This is an example. Follow me!'
)
resp = client.post_post(post, 80)
print("Success: ", resp.ok)
Output:
{"message": "Missing info.", "status": "fail"}
Someone opened an issue where they could not upload an image as they were using a png and some other image format. De you believe it is worth it to create a method which simply converts the image to a jpeg format? Or is it possible to upload it as a png/other formats (Not really sure how Instagram handles images"
Instagram uses 3 different endpoints for updating a profile:
accounts/set_biography/
Just updates the biography.
accounts/set_gender/
Just updates the gender
accounts/edit_profile/
Updates profile name, username, email, phone number and url.
Where possible, the requests should be combined.
This is a very cool project, I'm glad I found you. I have a couple of questions:
1. What method should you use to get information about a post from a short link?
How to get this information, including media files.
2. What method should you use to post a comment and how to use it correctly?
3. How to correctly compose a request for uploading a photo with geolocation ?
I would be very grateful if I get an answer.
Hello, i use your code from examples (https://github.com/stanvanrooy/instauto/blob/master/examples/post/upload_image.py)
I got error AttributeError: module 'instauto.api.actions.structs.post' has no attribute 'Post'
Make sure we have the original requests and responses received, stored in a JSON file for later reference. See original_requests/friendships
for examples.
This can be done in two ways:
The requests & responses should be added to the JSON files in original_requests/
. All the logged information should be in a consistent format across all files.
Information that should be stored:
I try to upload a photo without specifying the location, I get an error:
KeyError: 'location'
Currently, some structs are implemented as normal classes, some as dataclasses, and all friendship
structs inherit from the custom common.Base
. We want to update all structs to the last one.
The common.Base
class works as follows:
self._custom_data['surface'] = self.State.optional
or self.State.required
or self.State.default
.__init__
for all custom data points, store these arguments in self._data
.ApiClient
, i.e. CSRFToken, user_id, etc. For example: self._enable_datapoint_from_client('_csrftoken')
. Currently, _csrftoken
, device_id
, _uuid
, and _uid
are supported, please add any that are missing.self._defaults
, i.e. self._defaults["surface"] = "example"
For an example of this implementation, see instauto.api.actions.structs.friendships
.
For some reason I get this error when trying to get the number of posts by an instagram user:
{'message': 'Please wait a few minutes before you try again.', 'status': 'fail'} Traceback (most recent call last): File "insta.py", line 170, in <module> main() File "insta.py", line 40, in main numbr = getsubnums() File "insta.py", line 63, in getsubnums user = resp['users'][0] KeyError: 'users' None
I tried waiting 1-2 hours and I still get this error. If this is an issue with the number of requests, wouldn't it be easier to just extract that data from the users page (Where is says Posts: number)?
PostGetLikes
. Add in pagination functionality, like PostRetrieveByUserI get the following error when trying to run the login code flow:
Traceback (most recent call last): File "insta.py", line 158, in <module> main() File "insta.py", line 48, in main getsubnums() File "insta.py", line 55, in getsubnums client.login() File "/home/user/anaconda3/lib/python3.8/site-packages/instauto/api/actions/authentication.py", line 64, in login self.state.logged_in_account_data = LoggedInAccountData(**resp.json()['logged_in_user']) KeyError: 'logged_in_user'
Update all imports where single classes/functions are being imported, instead of the complete module. For example:
from structs.friendships import Create
-> from structs import friendships as fs
and then use Create
like fs.Create
.
Instagram only accepts jpeg images and automatically converts other formats. Converting images is out of scope for instauto
.
Instead, we should just raise an exception when someone tries constructing a 'Post` object with a non-jpeg image.
from instauto import ApiClient
client = ApiClient(user_name=username, password=password)
client.login()
trace:
---------------------------------------------------------------------------
.../python3.8/site-packages/instauto/api/actions/authentication.py in login(self)
62 # does the actual login
63 resp = self._request('accounts/login/', Method.POST, data=data2, signed=True)
---> 64 self.state.logged_in_account_data = LoggedInAccountData(**resp.json()['logged_in_user'])
65
66 def _build_initial_headers(self) -> Dict[str, str]:
KeyError: 'logged_in_user'
This might be due to a challenge request (where Instagram asks for a phone/email text message code verification). Could you add this feature to handle that?
Some tips for this: dilame/instagram-private-api#1068 (comment)
First I want to thank all the devs working on this great library. Furthermore, seems like Instagram will stop supporting their private API on September 30th (Link: https://www.instagram.com/developer/).
"Legacy API user identifier available on Basic Display API until September 30, 2020"
Seems this means the end of this library usability? Or we can change and adapt which is also not doable from what I have read in their new Instagram Graph API docs... The APIs are very limited and almost only regarding the owner of a page's information (Due to data security concerns). Any thoughts or corrections on my assumption?
Hi, @stanvanrooy )
Do you plan to implement video uploading?
Describe the bug
Tested with both file types (.jpg and .mp4) and using the latest version of Instauto, I cannot get a post to upload from my account.
from
final_post = ps.Post.create(
path=post,
source_type=st.WhereToPost.Feed,
caption=my_caption
)
resp = client.post_post(final_post)
print("Success: ", resp.ok)
I get
Success: False
path='PATH TO POSTS/posts/post.jpg'
caption='test'
(for clarity)
I get no errors of any kind, but I've tried multiple different files--each either .jpg or .mp4--but still the same result. Is there anyway to know what I'm doing wrong?
Expected behavior
Successul post
Creat method upload image for story
pre-commit should be used to add pre-commit hooks to enforce and achieve a consistent style across the project.
Enabled hooks should be tested carefully on a few files at a time, then run on the complete project.
Not sure yet which hooks will be used.
PostRetrieveByFeed
. Add in pagination functionality, like PostRetrieveByUserInstauto currently returns the complete Response
object. That's good, I want to offer that kind of flexibility, but users should have the option to let Instauto parse the response and just return the most commonly used data.
Could either be added as helper functions or as param in the function call. Not sure yet what would be best.
On the one hand, I want to keep the library as flexible as possible and give users full control. On the other hand, the largest portion of the possible users isn't looking for flexibility, but for ease of use.
I think the middle ground, is keeping all methods that are currently available but implementing some sort of helper class/helper functions that does implement some common use cases, for example, to iterate of followers, the feed, following, etc.
Will have to think through implementation a bit more.
Currently, we store the complete ig_profile, device_profile, state, and session_cookies.
Most likely, not all values from these attributes need to be stored, and we can get away with simply recreating/using the same default value if possible.
This will reduce file size of the save. Not that important, but nice to have.
See original_requests/friendships
for reference. Needed for tests.
See https://github.com/stanvanrooy/instauto/blob/master/docs/dev_environment.md for setting up an environment where you can listen to requests.
Some structs aren't dataclasses. They should be.
Hi
`POST /api/v1/media/231529815458455678_174613709/like/
SIGNATURE
{
"delivery_class": "organic",
"media_id": "23154581568_174613709",
"_csrftoken": "LGYsuPoltfgnjLLgT",
"radio_type": "wifi-none",
"_uid": "6780958545",
"_uuid": "ghjuokt5-d78-d5tghjkihgde",
"is_carousel_bumped_post": "false",
"container_module": "feed_contextual_profile",
"feed_position": "34"
}
{
"d": "0"
}`
Are all parameters being sent ?
I think we missing feed_position.
I see some functions/classes where I used the wrong naming.
All names should look like this:
profile_set_gender
post_like
search_username
post_comment
So the namespace followed by the action that will be taken.
api.actions.profile:60, missing method.
Is there a way to get the total number of posts by a user?
Here is the error I get when trying to post an image:
images/1600543191-conf.jpeg Traceback (most recent call last): File "insta.py", line 154, in <module> main() File "insta.py", line 39, in main postinsta(image1) File "insta.py", line 113, in postinsta resp = client.post_post(post, 80) File "/home/pi/.local/lib/python3.8/site-packages/instauto/api/actions/post.py", line 133, in post_post as_dict.pop('location') KeyError: 'location' None
The image name is image1 and it is what I printed in the very first line.
Hello again, I tried to compose a request myself, but I didn't succeed, you can help me
I'm trying to compose a post request for uploading a photo to Instagram, but the third request returns a 403 error to "instagram.com/create/configure/"
My code:
`import re
import requests
import urllib.request
from datetime import datetime
link = 'https://www.instagram.com/accounts/login/'
login_url = 'https://www.instagram.com/accounts/login/ajax/'
login = 'username'
password = 'password '
time = int(datetime.now().timestamp())
print(time)
payload = {
'username': login,
'enc_password': f'#PWD_INSTAGRAM_BROWSER:0:{time}:{password}',
'queryParams': {},
'optIntoOneTap': 'false'
}
with requests.Session() as s:
r = s.get(link)
a = r.cookies['csrftoken']
print(r.cookies)
print(a)
csrf = re.findall(r"csrf_token":"(.*?)"", r.text)[0]
print(csrf)
r = s.post(login_url, data=payload, headers={
"User-Agent": "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36",
"X-Requested-With": "XMLHttpRequest",
"Referer": "https://www.instagram.com/accounts/login/",
"x-csrftoken": csrf
})
print(r.status_code)
print(r.url)
print(r.text)
print(s.cookies)
r = s.get('https://www.instagram.com/accounts/edit/')
print(login in r.text)
microtime = int(datetime.now().timestamp())
headers = {
"content-type": "image / jpg",
"X-Entity-Name" : f"fb_uploader_{microtime}",
"Offset": "0",
"User-Agent": "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36",
"x-entity-length": "299255",
"X-Instagram-Rupload-Params": f'{{"media_type": 1, "upload_id": {microtime}, "upload_media_height": 1080, "upload_media_width": 1080}}',
"x-csrftoken": csrf,
"x-ig-app-id": "1217981644879628"
}
img = urllib.request.urlopen('https://sun9-64.userapi.com/RVgUHSq9fXrDr8YBJ4a4h9xwN4EQA_8BXuQ5Vg/Mdx3LwawEmY.jpg')
photo = img.read()
r = s.post(f'https://www.instagram.com/rupload_igphoto/fb_uploader_{microtime}', data=open("4.jpg", "rb"), headers=headers)
print(r.text)
headers = {
'Content-Length': '104',
'content-type': 'application/x-www-form-urlencoded',
"origin": "https://www.instagram.com",
"referer": "https://www.instagram.com/create/details/",
'user-agent': "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36",
"x-csrftoken": csrf,
"x-ig-app-id": "1217981644879628",
"X-Requested-With": "XMLHttpRequest"
}
body = {
'upload_id': f'{microtime}',
"caption":'00000000000000000000',
'usertags':'',
'custom_accessibility_caption': '',
'retry_timeout':''
}
r = s.post('https://www.instagram.com/create/configure/', data=body, headers=headers)
print(r.status_code)
print(r.text)`
Process:
First authorization, everything is okay with that
The second request is to upload a photo, everything is ok too
The third request, with the parameters of the photo, there is an error ... error 403 is returned
Rename to GetFollowing & GetFollowers.
The _create
method is repeated everywhere. Should just be in a common class which the base classes inherit from.
So you'll have:
Base
_BaseFriendship(Base)
_BasePost(Base)
My code:
import os
from instauto import ApiClient
from instauto import post as ps
if __name__ == '__main__':
if os.path.isfile('./.instauto.save'):
client = ApiClient.initiate_from_file('./.instauto.save')
else:
client = ApiClient(user_name="your_username", password="your_password")
client.login()
client.save_to_disk('./.instauto.save')
like = ps.Comment.create(
media_id="1734612737423614055_6400760974",
comment_text="Such great!"
)
resp = client.post_comment(like)
print("Success: ", resp.ok)
return "Success: False"
no comment is sent
How to get media ID from a normal link? example https://www.instagram.com/p/CEukJmYgQxD/
Should be as simple as removing walrus operators.
client.followers_get(f) now throws an exception because "GetFollowers" doesn't have "max_id" attribute anymore.
f = fs.GetFollowers(user_id="2283025667")
obj, result = client.followers_get(f)
AttributeError Traceback (most recent call last)
in
1 f = fs.GetFollowers(user_id=user_id)
----> 2 obj, result = client.followers_get(f)
/opt/anaconda2/envs/Instabot2/lib/python3.8/site-packages/instauto/api/actions/friendships.py in followers_get(self, obj)
65 ```
66 """
---> 67 if obj.max_id is None and obj.page > 0:
68 return obj, False
69 query_params = {
AttributeError: 'GetBase' object has no attribute 'max_id'
due to changes in #54
468302a#r42655264
Not sure what's wrong atm. To reproduce:
obj = pr.SetGender(gender=WhichGender.female)
resp = self._client.profile_set_gender(obj)
resp_as_json = resp.json()
print(resp_as_json) # {'message': '', 'status': 'fail'}
PostRetrieveByHashtag
. Add in pagination functionality, like PostRetrieveByUserA declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.