| instakit | remove pil as it is unnecessary + fix invalid username raising ChallengeRequired instead of InvalidCredentials at login | |
| .gitignore | initial commit | |
| LICENSE | initial commit | |
| pyproject.toml | remove pil as it is unnecessary + fix invalid username raising ChallengeRequired instead of InvalidCredentials at login | |
| README.md | initial commit | |
instakit
an async python client for instagram's private api. think twikit but for instagram.
this is alpha software (0.1.0a1). it works, but the api might change.
install
pip install git+https://codeberg.org/phin/instakit.git
requires python 3.10+
quick start
import asyncio
from instakit import Client
async def main():
client = Client()
await client.login("username", "password")
client.save_session("session.json") # save for next time
user = await client.profile("instagram")
print(f"{user.username} has {user.follower_count} followers")
await client.close()
asyncio.run(main())
once you have a session saved, you can skip login:
client = Client()
client.load_session("session.json")
# ready to use
what you can do
users
user = await client.profile("username") # get by username
user = await client.user("12345") # get by id
me = await client.me() # get yourself
followers = await client.followers(user.id) # paginated
following = await client.following(user.id)
await client.follow(user.id)
await client.unfollow(user.id)
await client.block(user.id)
await client.unblock(user.id)
await client.mute(user.id)
await client.restrict(user.id)
posts
posts = await client.posts(user.id) # user's posts
feed = await client.feed() # your home feed
saved = await client.saved() # your saved posts
liked = await client.liked() # posts you liked
post = await client.media(media_id) # single post
comments = await client.comments(media_id)
likers = await client.likers(media_id)
await client.like(media_id)
await client.unlike(media_id)
await client.save(media_id)
await client.comment(media_id, "nice!")
await client.delete_comment(media_id, comment_id)
stories
tray = await client.story_tray() # stories from people you follow
stories = await client.stories(user.id) # specific user's stories
highlights = await client.highlights(user.id)
archive = await client.story_archive() # your archived stories
await client.mark_story_seen(story_id)
reels
reels = await client.reels() # discover reels
user_reels = await client.user_reels(user.id)
clips = await client.clips_discover()
# reels using specific audio
await client.reels_by_audio(audio_id)
direct messages
inbox = await client.inbox()
thread = await client.thread(thread_id)
# send messages
await client.send_text(user_id, "hello")
await client.send_photo(user_id, "photo.jpg")
await client.send_video(user_id, "video.mp4")
await client.send_voice(user_id, "voice.m4a")
await client.send_link(user_id, "https://example.com")
await client.send_profile(user_id, profile_user_id)
# reactions
await client.react_to_message(thread_id, item_id, "❤️")
search
users = await client.search("query")
tags = await client.search_tags("travel")
places = await client.search_places("new york")
music = await client.search_music("pop")
explore
explore = await client.explore()
discover = await client.clips_discover()
trending = await client.trending_music()
upload
# photos
await client.upload_photo("photo.jpg", caption="my photo")
# videos
await client.upload_video("video.mp4", caption="my video")
# stories
await client.upload_story("image.jpg")
await client.upload_video_story("video.mp4")
# reels
await client.upload_reel("reel.mp4", caption="check this out")
collections
collections = await client.collections()
items = await client.collection(collection_id)
await client.create_collection("name")
await client.add_to_collection(collection_id, media_id)
await client.delete_collection(collection_id)
account
profile = await client.edit_profile() # get current profile
activity = await client.activity() # notifications
logins = await client.login_activity() # login history
blocked = await client.blocked() # blocked users
close_friends = await client.close_friends()
await client.set_presence_disabled(True) # hide activity status
pagination
methods that return lists support pagination:
# first page
result = await client.followers(user_id)
for user in result.items:
print(user.username)
# next page
if result.cursor:
result = await client.followers(user_id, cursor=result.cursor)
error handling
from instakit import (
Client,
LoginRequired,
ChallengeRequired,
TwoFactorRequired,
RateLimited,
NotFound,
)
try:
await client.login(username, password)
except TwoFactorRequired:
code = input("enter 2fa code: ")
await client.two_factor_login(username, code)
except ChallengeRequired as e:
# handle verification challenge
pass
except RateLimited:
# too many requests
pass
all exceptions inherit from InstagramException.
2fa login
from instakit import Client, TwoFactorRequired
client = Client()
try:
await client.login(username, password)
except TwoFactorRequired:
code = input("2fa code: ")
await client.two_factor_login(username, code)
for totp (authenticator app):
from instakit import generate_totp
code = generate_totp(seed) # your totp seed
await client.two_factor_login(username, code)
proxy
client = Client(proxy="http://user:pass@host:port")
device emulation
by default, instakit emulates a pixel 9a. you can change this:
client = Client(device="pixel9") # pixel 9
client = Client(device="pixel8") # pixel 8
client = Client(device="samsung_s24") # samsung s24
or use custom device info:
client = Client(device={
"manufacturer": "Google",
"model": "Pixel 9",
"device": "tokay",
"cpu": "google",
"dpi": "420dpi",
"resolution": "1080x2424",
})
how it works
instakit uses instagram's private android api (the same one the app uses). requests are made to i.instagram.com/api/v1/ with appropriate headers and signatures.
the library handles:
- session management and persistence
- device fingerprinting
- request signing
- challenge/2fa flows
- rate limiting delays
- pagination
warnings
this uses instagram's private api which isn't officially supported. a few things to keep in mind:
- instagram can change their api without notice, which could break things
- using automation is against instagram's terms of service
- aggressive usage might get your account rate limited or banned
- this is alpha software, expect bugs
don't use this for anything critical.
support
i don't provide free support. i may answer simple questions and i respond to bug reports, but don't expect help with your specific use case. if you need dedicated support, contact me about paid consulting.
credits
thx gil for the idea
license
0BSD