insta_sophia_sdk
SDK oficial da API Nornir para coleta pública de perfis, posts e comentários do Instagram.
O SDK fala apenas com a API. Toda a parte frágil (fingerprint TLS, descoberta de doc_id,
proxy, autorização) vive lá e pode mudar sem quebrar o seu código.
Instalação
pip install insta-sophia-sdk
Ou, enquanto o pacote for privado:
pip install git+https://github.com/SophiaLab/insta_sophia_sdk.git
Uso em três linhas
from insta_sophia_sdk import SophiaClient
with SophiaClient(main_key="SUA_MAIN_KEY", client_key="SUA_CLIENT_KEY",
base_url="https://api.seudominio.com") as client:
perfil = client.profile("nubank")
print(perfil.followers) # 1893011
As duas chaves vêm da sua ativação no Moneto: main_key é a que você recebe, client_key é
emitida quando a chave é ativada.
Paginação sem cursor
Posts e comentários são iteradores — o SDK busca as páginas sob demanda e você nunca vê cursor:
for post in client.posts("nubank", limit=100):
print(post.shortcode, post.url)
for comentario in client.comments("DW6kgl6Dhs1", limit=500):
print(f"@{comentario.username}: {comentario.text}")
A busca é preguiçosa: limit=100 com 12 itens por página faz 9 requisições, e sair do laço
depois de 3 itens faz uma. Nada é baixado à toa.
limit é teto, não garantia — se o conteúdo acabar antes, você recebe menos.
Quando você quer o cursor
Para persistir o progresso e retomar depois:
pagina = client.posts_page("nubank")
while True:
for post in pagina.posts:
processar(post)
if not pagina.has_more:
break
pagina = client.posts_page("nubank", cursor=pagina.next_cursor)
Tratando erros
from insta_sophia_sdk import (
SophiaClient, AuthenticationError, ActivationError,
NotFoundError, RateLimitError, TransportError, SophiaError,
)
try:
perfil = client.profile("perfil_que_talvez_nao_exista")
except NotFoundError:
print("perfil não existe ou está indisponível")
except AuthenticationError:
print("chaves inválidas")
except ActivationError:
print("chave expirada ou bloqueada — verifique no Moneto")
except RateLimitError as e:
print(f"limite atingido; tente em {e.retry_after}s")
except TransportError:
print("a API não respondeu")
except SophiaError:
print("qualquer outra falha do SDK")
SophiaError é a base — capturá-la pega tudo que o SDK levanta.
Verificando pelo terminal
O pacote instala o comando sophia, que serve para conferir credenciais e conectividade sem
escrever código:
export SOPHIA_MAIN_KEY=...
export SOPHIA_CLIENT_KEY=...
export SOPHIA_BASE_URL=https://api.seudominio.com
sophia health
sophia profile nubank
sophia posts nubank --limit 50
sophia comments DW6kgl6Dhs1 --limit 100
sophia profile nubank --json
Ler as chaves do ambiente evita que elas fiquem no histórico do shell. O comando sai com
código 1 em erro, então dá para encadear em script.
Proxy — você contrata, você passa
A API sai para o Instagram pelo seu proxy. O IP é seu, o custo é seu, e o isolamento também: se um IP seu for bloqueado, isso não afeta outros clientes.
client = SophiaClient(
main_key="...", client_key="...", base_url="https://api.seudominio.com",
proxy="http://usuario:senha@geo.iproyal.com:12321",
)
Formato: esquema://usuario:senha@host:porta (http ou https).
Para paralelizar, abra clientes com proxies diferentes:
clientes = [
SophiaClient(main_key=K, client_key=C, base_url=URL, proxy=p)
for p in meus_proxies
]
Endereços internos são recusados. A API rejeita proxy apontando para
127.0.0.1,localhost, redes privadas (10.x,192.168.x) ou metadata de cloud (169.254.169.254), respondendo422. É proteção contra SSRF — sem ela, a API poderia ser usada para varrer a rede interna do servidor.
Omitir proxy faz a API usar o proxy dela, se houver — útil só em desenvolvimento.
Limite de coletas simultâneas
Cada chave tem um teto de coletas em paralelo (padrão 4). Acima dele a API responde
429 e o SDK levanta RateLimitError:
from insta_sophia_sdk import RateLimitError
try:
perfil = client.profile("fulano")
except RateLimitError as e:
print(f"muitas coletas ao mesmo tempo; aguarde {e.retry_after}s")
O teto não é arbitrário: acima de ~4 requisições simultâneas saindo do mesmo IP, o próprio Instagram começa a recusar — com HTTP 200 e corpo vazio. Recusar na entrada evita gastar seu proxy numa requisição que falharia adiante.
Para volume maior, use mais proxies, não mais threads no mesmo proxy.
Controlando o ritmo
Duas coisas diferentes, e vale não confundir:
client = SophiaClient(
main_key="...", client_key="...", base_url="...",
timeout=120.0, # quanto ESPERAR uma requisição antes de desistir
page_delay=1.5, # quanto PAUSAR entre páginas ao iterar
)
timeout é o limite de paciência com uma requisição. Aumente se a API demorar — a primeira
coleta de um perfil pode passar pela descoberta de doc_id, que é lenta.
page_delay é a pausa entre páginas na iteração. Padrão 0 (sem pausa). Vale usar em
coleta longa: 500 comentários são ~35 requisições, e dispará-las em rajada pressiona a API
e o Instagram atrás dela.
# coleta longa e comportada: uma página a cada 2 segundos
for comentario in client.comments("DW6kgl6Dhs1", limit=500):
processar(comentario)
A pausa só acontece quando há próxima página a buscar — nunca depois da última, nem depois
de o limit ter sido atingido.
Resiliência
Timeout em toda requisição (30s por padrão) e retry com backoff exponencial:
| Situação | Retenta? |
|---|---|
| Timeout, falha de rede | sim |
| 5xx | sim |
| 429 | sim, respeitando o Retry-After que o servidor mandar |
| 401, 403, 404, 422 | não |
Erro de autenticação nunca é retentado: repetir uma chave inválida não a torna válida, só
multiplica latência e ruído. Ajuste com timeout= e max_retries= no construtor.
Campos que vêm nulos
Post.like_count, Post.comment_count e Profile.posts_count são int | None e chegam
nulos — a rota pública do Instagram não os expõe.
None significa "não sabemos", nunca "zero". Converter para zero faria você confundir um
post sem curtidas com um post cuja contagem é desconhecida.
Comentários têm métrica: Comment.like_count vem preenchido.
Referência
| Método | Devolve |
|---|---|
profile(username) |
Profile |
posts(username, limit=None) |
Iterator[Post] |
comments(shortcode, limit=None) |
Iterator[Comment] |
posts_page(username, cursor=None) |
PostsPage |
comments_page(shortcode, cursor=None) |
CommentsPage |
health() |
bool — não levanta |
close() |
fecha a conexão (automático no with) |
Profile.url e Post.url são propriedades calculadas; Comment.is_reply diz se o
comentário responde a outro.
Segurança
As chaves são mascaradas em repr e str, e não aparecem em mensagem de erro — o repr de
um objeto de configuração costuma acabar em issue de GitHub e log de terceiro.
Prefira variáveis de ambiente a chaves literais no código.
Desenvolvimento
poetry install
poetry run pytest tests/ -v
poetry run ruff check . && poetry run ruff format --check .
poetry run mypy insta_sophia_sdk/ --ignore-missing-imports
A suíte não usa rede: o MockTransport nativo do httpx responde no lugar do servidor.
Metadata
Release files for insta-sophia-sdk 0.1.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| insta_sophia_sdk-0.1.3.tar.gz | 18.3 kB | Without provenance | Details for insta_sophia_sdk-0.1.3.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| insta_sophia_sdk-0.1.3-py3-none-any.whl | Python 3 | none | any | Details for insta_sophia_sdk-0.1.3-py3-none-any.whl |
Total release size: 40.8 kB
Release files / insta_sophia_sdk-0.1.3.tar.gz
| Download URL | insta_sophia_sdk-0.1.3.tar.gz |
|---|---|
| Size | 18.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7609024967cff862938da624690226511b59b38b524ce16c73cdb9fa1dec1cc8
|
|
BLAKE2b-256 checksum How to use checksums |
1d6372f74db3eaf1e09dc4210034c903dc8c8f74c46cb557d243b689bd6a1ba1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/2.2.1 CPython/3.12.7 Windows/11
|
Release files / insta_sophia_sdk-0.1.3-py3-none-any.whl
| Download URL | insta_sophia_sdk-0.1.3-py3-none-any.whl |
|---|---|
| Size | 22.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7a7b7797011dec0d54ba2d21f9d2b1d53319119652efcdabad7374d866acef87
|
|
BLAKE2b-256 checksum How to use checksums |
8b7ebdbd1e0ce959a5da4d273c4a24b953c78931541091c8f30392f814f72469
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/2.2.1 CPython/3.12.7 Windows/11
|
Security for insta-sophia-sdk 0.1.3
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.