How to install Osintgram in 2026
Six commands: clone, cd, create a virtualenv, activate it, pip install -r requirements.txt, then fill in config/credentials.ini. That sequence installs cleanly in a fresh Python 3.11 environment; what breaks is pip running outside a virtualenv on Debian-based distros, and pyreadline on native Windows.
Osintgram installs in six commands: git clone, cd Osintgram, python3 -m venv venv, activate it, pip install -r requirements.txt, then fill in config/credentials.ini. Installing requirements.txt into a clean Python 3.11 virtualenv on current pip succeeds with no errors. The install failures people report cluster into four things: pip running system-wide on Debian, Ubuntu or Kali; an OS-packaged prettytable or urllib3 in the way; gnureadline failing to compile; or pyreadline crashing on native Windows.
Before you start
You need a Python 3 interpreter, git, and a decision about how Osintgram is going to authenticate. The third one is the part people skip, and it is why the install appears to succeed and then the tool exits one line into the first run.
The README never states a minimum Python version; it carries a Python3 badge and nothing else. The only version pin committed to the repo is the Dockerfile's first line, FROM python:3.9.2-alpine3.13, and the newest dependency, hikerapi 1.7.1, declares requires_python >=3.8. Installing requirements.txt into a fresh Python 3.11 virtualenv works on current pip: prettytable 0.7.2, pyreadline 2.1 and hikerapi 1.7.1 ship as source distributions only, and all three build without complaint. Treat 3.9-3.11 as a sweet spot rather than a requirement.
- Python 3.9 to 3.11. 3.12 and 3.13 are where the reported breakage clusters, and it is almost always a packaging collision rather than a language incompatibility.
- git, or a ZIP of the master branch. There is no PyPI package and no installer script: the repo contains no
setup.sh. - A compiler and ncurses headers on Linux, but only if pip has to build
gnureadline. On mainstream glibc distros it finds a manylinux wheel and skips the compile. - Credentials. Either an Instagram account you are willing to lose, or a HikerAPI token. Decide before step six: they lead to two different code paths.
One platform gets its own page, because its default interpreter and its pip both behave differently from a stock Debian or Ubuntu box: Osintgram on Kali Linux.
The six commands
This is the README's own sequence, unchanged. Run all of it from one shell: the virtualenv and the working directory both matter later.
- 1
Clone the repo
The default branch is
master. There are alsodevelopmentandv2branches; ignore both unless you know why you want them.git clone https://github.com/Datalux/Osintgram.git - 2
Move into the directory
Not just for this step. Osintgram reads its config through the relative path
config/credentials.ini, so the repo root is the only directory it runs correctly from.cd Osintgram - 3
Create a virtualenv
On Debian, Ubuntu and Kali you may need
sudo apt install python3-venvfirst. Skipping it is what produces the first three errors in the table further down.python3 -m venv venv - 4
Activate it
Your prompt should now be prefixed with
(venv). If it is not, the next command installs into the wrong interpreter.# Linux, macOS, Git Bash source venv/bin/activate # Windows PowerShell .\venv\Scripts\activate.ps1 - 5
Install the dependencies
The flag is
-r. Typing-tinstead gets youERROR: Target path exists but is not a directory, will not continue., because-tmeans--target.pip install -r requirements.txt - 6
Fill in your credentials
Edit the INI file by hand, or let the Makefile prompt you. They are not equivalent. The next section covers why.
nano config/credentials.ini # or, with GNU make and bash available: make setup
requests-toolbelt==0.9.1
geopy>=2.0.0
prettytable==0.7.2
instagram-private-api==1.6.0
gnureadline>=8.0.0; platform_system != "Windows"
pyreadline==2.1; platform_system == "Windows"
hikerapi==1.7.1Two absences in that file will confuse you later. requests is not listed; it arrives transitively. Neither is httpx, which src/Osintgram.py imports on line 9. It only resolves because hikerapi depends on it.
Configuring credentials
The repo ships config/credentials.ini pre-created and blank. Three fields, one section:
[Credentials]
username =
password =
hikerapi_token =src/config.py loads it with configparser and the literal call config.read("config/credentials.ini"). That relative path is why step two exists: launch python3 ~/Osintgram/main.py sometarget from your home directory and configparser silently reads nothing.
Leave the file as it ships and the first run stops immediately. With the blank credentials.ini from a fresh clone, main.py prints one line and nothing else: Error: "username" field cannot be blank in "config/credentials.ini". Hardcoded alongside it are the same message for password, plus Error: missing "username" field in "config/credentials.ini" and Error: file "config/credentials.ini" not found!.
It prints an error and then exits 0
Every credential check in src/config.py calls sys.exit(0), the success status. If you drive Osintgram from a shell script or from CI, a misconfigured credentials file looks exactly like a clean run to anything inspecting the exit code. Check for output, not for status.
What `make setup` actually writes
The Makefile's setup target is short and does more than it advertises. It prompts Instagram Username: with read -p and Instagram Password: with read -sp, so only the password is hidden, then writes the file itself. Three undocumented consequences. It overwrites credentials.ini with only [Credentials], username and password, so any hikerapi_token you had is gone. It runs echo -n "{}" > config/settings.json first, wiping any cached session. And it declares SHELL := /bin/bash and uses read -sp, so it needs GNU make and bash. It will not run in cmd or PowerShell.
The hikerapi_token field
That third field changes which program you are running. src/config.py exposes getHikerToken(), which returns the hikerapi_token value or the HIKERAPI_TOKEN environment variable. main.py branches on it: with a token it constructs HikerCLI, and only otherwise the classic Osintgram client. With a token set, the tool never builds an Instagram client and never sends a password anywhere. You do not need an Instagram account at all. The startup line becomes Connect to HikerAPI... instead of Attempt to login....
HIKERAPI_TOKEN=<hikerapi token> python3 main.py <target> -c infoThe README points at hikerapi.com/tokens and says the "first 100 requests are free after registration and confirmation of your tg". After that it is a paid third-party API, and every username you look up passes through it. That is the trade. It is the path still designed to work, and users report it working, but open issue #2664 (21 June 2026) exists specifically to handle alternate HikerAPI response formats.
| Credential path | What lands in credentials.ini | Instagram account needed |
|---|---|---|
| Edit the file by hand | Whichever of the three fields you fill in | Only if you fill in username and password |
make setup | username and password; the token line is dropped | Yes, and it resets config/settings.json |
hikerapi_token or env var | One token; username and password are never read | No: main.py builds HikerCLI |
Use a burner account, and keep it out of git
The README carries this in red: "It is advisable to not use your own/primary account when using this tool." A second red warning tells you not to upload your credentials to GitHub if you fork the project. That one matters more than it looks: config/credentials.ini is committed to the repo, so although .gitignore names it, Git ignores nothing it is already tracking. Check git status before you push a fork. Osintgram authenticates as you and behaves like an automated client; whatever Instagram decides about that lands on the account in that file.
Check that it worked
Two checks, in order: the first proves the dependency tree resolved, the second proves the tool can read your config. Run both from the repo root with the venv active.
cd Osintgram
source venv/bin/activate
# 1. does the package tree import?
python -c "from src.Osintgram import Osintgram; print('ok')"
# 2. does it read your credentials and reach login?
python3 main.py <target username> --command infoIf the first prints ok, your install is finished. If the second prints a blank-field error, go back to the credentials section. If it prints Attempt to login... or Connect to HikerAPI..., the install is done and everything after that line is Instagram's problem.
One more to pre-empt: ModuleNotFoundError: No module named 'src.Osintgram' means you launched main.py from somewhere other than the repo root. That is issue #105, and the fix is cd Osintgram, every time.
Install errors and what they actually mean
Every string in the left column comes from the project's issue tracker or was reproduced locally on a clean clone. None of them are Instagram-side; they all happen before a single request leaves your machine.
| Error text | What it actually means | Fix |
|---|---|---|
error: externally-managed-environment | PEP 668. Debian 12+, Ubuntu 23.04+ and Kali refuse system-wide pip installs. | Do the venv step. Kali documents this; sudo apt install python3-venv if venv is missing. |
ModuleNotFoundError: No module named 'urllib3.packages.six.moves' | apt's python3-requests mixed with pip's urllib3 2.x. The giveaway is a path under ~/.local/lib/python3.12/site-packages/, which means --break-system-packages. | Delete the user-site packages, reinstall in a clean venv (#1766). |
Cannot uninstall prettytable 3.10.1 / no RECORD file was found for prettytable | pip trying to remove apt's python3-prettytable to satisfy the prettytable==0.7.2 pin. | A venv without --system-site-packages avoids it (#1126). |
/usr/bin/ld: cannot find -lncurses | gnureadline compiling from source with no ncurses headers present. | sudo apt install -y build-essential libncurses-dev (#183). |
ModuleNotFoundError: No module named 'pyreadline' on Linux | Misleading. main.py catches a failed import gnureadline with a bare except and falls back to pyreadline, which requirements.txt installs only on Windows. | Ignore pyreadline; fix the gnureadline build above. |
AttributeError: module 'collections' has no attribute 'Callable' | pyreadline 2.1 on Python 3.10+ on native Windows. Crashes at main.py line 108. | See the Windows section: pip install pyreadline3 is not the fix (#2668). |
AttributeError: 'HTMLParser' object has no attribute 'unescape' | prettytable 0.7.2 building against an old setuptools; HTMLParser.unescape() went away in Python 3.9. | pip install --upgrade pip setuptools wheel first (issue #334). |
ModuleNotFoundError: No module named 'src.Osintgram' | main.py launched from outside the repo root. | cd Osintgram first. |
ERROR: Target path exists but is not a directory, will not continue. | pip install -t requirements.txt; -t is --target, an install destination. | The flag is -r (#2666). |
The first three rows only ever happen when pip runs against the system interpreter, so they vanish the moment you actually use the venv. That is why step three is not ceremony.
Windows and WSL
On native Windows the dependency install is fine. Cloning master and installing requirements.txt in a Python 3.11 venv succeeds, and the Windows-only pyreadline 2.1 builds from source without an error. What fails is the very next thing, before argparse has even read your arguments:
File "...\Osintgram\main.py", line 108, in <module>
pyreadline.Readline().parse_and_bind("tab: complete")
File "...\pyreadline\py3k_compat.py", line 8, in callable
return isinstance(x, collections.Callable)
AttributeError: module 'collections' has no attribute 'Callable'collections.Callable was removed in Python 3.10 and moved to collections.abc; pyreadline 2.1 last shipped in 2020. main.py reaches that line because its readline import is a try: import gnureadline / except: import pyreadline, and requirements.txt installs pyreadline only on Windows. Windows is therefore the only path that touches the broken module.
pyreadline3 is not a drop-in replacement
This is the advice on every forum thread, and it does not work here. In a clean venv, after pip install pyreadline3, python -c "import pyreadline" still raises ModuleNotFoundError: No module named 'pyreadline' while import pyreadline3 succeeds. The package installs under a different module name, and main.py hardcodes import pyreadline.
Four things that do work:
- Patch pyreadline. In
venv\Lib\site-packages\pyreadline\py3k_compat.py, changecollections.Callableon line 8 tocollections.abc.Callable. Verified: main.py then runs through to the credentials check. - Patch main.py instead. Change the fallback to
import pyreadline3 as pyreadline. Same result, but it is a change to tracked code thatgit pullwill fight you over. - Use WSL. Inside a WSL Ubuntu or Debian shell you are on the Linux path: the environment marker selects gnureadline, pyreadline is never installed, and the same six commands apply verbatim. PEP 668 applies there too, so keep the venv.
- Use Python 3.9 on Windows, where
collections.Callablestill exists. Works, ages badly.
WSL is the honest recommendation: every code path, every traceback in the tracker and the project's own container assume Linux. Git Bash is a partial middle ground (the README documents source venv/bin/activate for it), but it still runs the Windows interpreter, so it still hits line 108.
Docker
The repo ships a Dockerfile, a docker-compose.yml and a Makefile. Docker is the one path that sidesteps the Python-version question entirely, because the image pins its own interpreter.
make setup
docker build -t osintgram .
docker run --rm -it \
-v "$PWD/output:/home/osintgram/output" osintgram <target>The image contains your Instagram password
The Dockerfile's third COPY is COPY --chown=osintgram:osintgram config/ /home/osintgram/config, so credentials.ini is baked into the image layers at build time. That is what the README means by "Your container will fail if you do not do step #3 and configure your credentials". Treat the build as a credential-bearing artifact: never push it to a registry, never share the exported tar.
Two more Docker facts. The base image is python:3.9.2-alpine3.13, a March 2021 build, which is exactly why the container dodges the 3.12 and 3.13 collisions, and also why it is the least-patched thing on your machine. And the Makefile's run, build-run-testing and cleanup-testing targets all call docker-compose, the hyphenated v1 binary that modern Docker installs no longer provide.
Myths that waste your time
Four claims turn up repeatedly in Osintgram install guides. All four are checkable against the source, and all four are wrong.
- "Python 3.12 removed distutils, so Osintgram cannot install." prettytable 0.7.2's setup.py opens with
from setuptools import setup. There is no distutils import anywhere in it, and pip's default build isolation provisions its own setuptools. The whole issue tracker contains one mention of distutils, and that issue's actual traceback is a cookie-expiry error. - "You need geckodriver, Selenium or Pillow." Grepping
src/Osintgram.py(the entire engine, all 60,586 bytes of it) forselenium,geckodriver,webdriver,PilloworPILreturns zero matches. There is no browser automation layer: the tool speaks HTTP to Instagram's private mobile API, and to HikerAPI via httpx. Downloads useurllib.request.urlretrieve. - "Just run
sudo apt install osintgram." Debian does not package Osintgram, and neither does the Kali tools catalogue. There is no PyPI package either, so cloning the repo is the only distribution channel. - "Edit config.py and put your credentials there." There is no
config.pyat the repo root. There issrc/config.py, which is code you do not edit; credentials live inconfig/credentials.ini.
A fifth: python3 main.py on its own starts nothing. argparse declares id as a required positional, so you get usage: main.py [-h] [-C] [-j] [-f] [-c COMMAND] [-o OUTPUT] id and an exit. Osintgram cannot be launched without a target username.
It installed, but login fails
Login failure is the biggest practical blocker in 2026, and it is not an install problem. Your install finished the moment pip completed and the import check passed. Everything printed after Attempt to login... belongs to Instagram.
Issue #2627, filed 4 March 2026, reports ClientError checkpoint_required with a checkpoint_url of https://i.instagram.com/web/unsupported_version/: Instagram is rejecting the library's API version, not your password. Issue #2630 (2 April 2026) reports ClientError Bad Request: block_eu_user_login_in_old_app. The author of PR #2660 describes the bad_password response as "actually a bot detection, not wrong password". No pip command fixes any of this; the full picture is in Does Osintgram still work in 2026?.
If you got a working shell instead, the next thing you want is the command reference: what each command returns, where output lands, and which ones get you throttled. That is how to use Osintgram. If your target is private, read what Osintgram can and cannot do there first.