Giter Club home page Giter Club logo

psychonaut's Introduction

Tests Docs

Psychonaut helmet

PROGRESS REPORT

  • Finish pydantic validation for reference types

What is this?

An async python sdk for Bluesky.

I used to do a pretty absurd amount of experiments with twitter's api. But musk has decided to turn that platform into a pay-for-play version of LinkedIn and banished all the tinkerers. So, now I'm here.

It has a bit of a weird structure. You basically do things like,

async with get_simple_client_session() as sess:
    posts: GetPostsResp = await GetPostsReq(uris=[...]).do_xrpc(sess)
    ...

which feels backwards from the expected,

async with get_simple_client_session() as sess:
    posts: GetPostsResp = await sess.do_xrpc(GetPostsReq(uris=[...]))

or even,

async with get_simple_client_session() as sess:
    posts: GetPostsResp = await sess.get_posts(uris=[...])

It's kinda an artifact of the way I did code generation but I kinda like it and fuck it S-expressions worked so there is a (completely nonsensical) precedence.

And, just to clarify, every request and response gets validated against the lexicon schema, which is nice (although reference types are still a WIP). Moreover, the generated code is auto-complete/copilot friendly. And, in theory, you could override do_xrpc to do clever things like caching, instead of hacking each particular api call.

But mostly I'm lazy so this is how it is.

Should I use this?

Almost certainly not. Right now it's a bucket of slop. I offer no guarantees about the stability of the API, the correctness of the implementation, or the quality of the documentation.

If you want to use it, go ahead.

Every single api call exists with Pydantic models for requests and responses (but with a few outstanding validations missing).

It's still unstable but I've been using it pretty regularly.

# In your venv or mamba env or whatever
pip install psychonaut

to use it as a library. This also installs the psychonaut command line tool.

psychonaut --help

# Temporary login
export BSKY_USERNAME=yourusername
export BSKY_PASSWORD=yourpassword

# Permanent login (~/.psychonaut.json)
psychonaut save-login yourusername 

psychonaut poast "hey look, an annoying cron job"

But definitely be mindful of the version because I'm going to break your code.

Alternatively, just use pipx

pipx install psychonaut

export BSKY_USERNAME=yourusername
export BSKY_PASSWORD=yourpassword

psychonaut poast "hell yea, pipx"

Firehose

EXTREMELY EXPERIMENTAL AND STILL NOT FINISHED

repos-firehose-stream saves the raw messages for subsequent replay so you can at least collect now and i'll get the json emit / validation working later.

# Stream the firehose
psychonaut repos-firehose-stream stream_dir

# Stream the firehose but print to stdout too
psychonaut repos-firehose-stream --tee stream_dir

# Replay serialized
psychonaut repos-firehose-replay stream_dir

# Replay serialized file
psychonaut repos-firehose-replay stream_dir/your_stream.b64-lines

How is this made?

Initially, this was a collaboration between the atproto repo, me, and my friend ChatGPT (using GPT-4). I had been toying around with this automatic langa<->langb transpiler in langchain. My original goal was to jointly build that while making my python client from the atproto repo. However, the fine folks at OpenAI didn't give me GPT-4 API access, and GPT-3 isn't quite good enough to do the job. So instead, this was me testing the fences "manually" (with ChatGPT). And now it's just me.

This also means this project was a bit...like theft? IDK.

Question of the generative hour: where is the boundary?

See Also (for pythonistas)

psychonaut's People

Contributors

abegong avatar jbn avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

Forkers

abegong wakamex

psychonaut's Issues

`get-` and `resolve-` commands don't work yet?

Cool project and kudos for jumping on it so fast! I ignored your "bucket of slop" warning and tried out psychonaut anyway.

poast worked liked a charm.

Nothing else did. Command line output is below.

I'm guessing that these don't work b/c they just aren't built yet. But it's also possible that it's just user error.

In that case, you might be able to score some quick wins (e.g. by providing a few examples in docstrings).

> psychonaut resolve-handle abegong            
Traceback (most recent call last):
  File "/usr/local/bin/psychonaut", line 8, in <module>
    sys.exit(cli())
  File "/usr/local/lib/python3.10/site-packages/click/core.py", line 1130, in __call__
    return self.main(*args, **kwargs)
  File "/usr/local/lib/python3.10/site-packages/click/core.py", line 1055, in main
    rv = self.invoke(ctx)
  File "/usr/local/lib/python3.10/site-packages/click/core.py", line 1657, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/local/lib/python3.10/site-packages/click/core.py", line 1404, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/local/lib/python3.10/site-packages/click/core.py", line 760, in invoke
    return __callback(*args, **kwargs)
  File "/usr/local/lib/python3.10/site-packages/psychonaut/cli/util.py", line 9, in wrapper
    return asyncio.run(func(*args, **kwargs))
  File "/usr/local/Cellar/[email protected]/3.10.6_2/Frameworks/Python.framework/Versions/3.10/lib/python3.10/asyncio/runners.py", line 44, in run
    return loop.run_until_complete(main)
  File "/usr/local/Cellar/[email protected]/3.10.6_2/Frameworks/Python.framework/Versions/3.10/lib/python3.10/asyncio/base_events.py", line 646, in run_until_complete
    return future.result()
  File "/usr/local/lib/python3.10/site-packages/psychonaut/cli/useful_queries.py", line 34, in resolve_handle
    resp = await resolve_handle_f(sess, req)
  File "/usr/local/lib/python3.10/site-packages/psychonaut/api/lexicons/com/atproto/identity/resolve_handle.py", line 27, in resolve_handle
    resp = await sess.query(req)
  File "/usr/local/lib/python3.10/site-packages/psychonaut/api/session.py", line 43, in query
    resp.raise_for_status()
  File "/usr/local/lib/python3.10/site-packages/aiohttp/client_reqrep.py", line 1005, in raise_for_status
    raise ClientResponseError(
aiohttp.client_exceptions.ClientResponseError: 400, message='Bad Request', url=URL('https://bsky.social/xrpc/com.atproto.identity.resolveHandle?handle=abegong')

> psychonaut resolve-handle [email protected]
Traceback (most recent call last):
  File "/usr/local/bin/psychonaut", line 8, in <module>
    sys.exit(cli())
  File "/usr/local/lib/python3.10/site-packages/click/core.py", line 1130, in __call__
    return self.main(*args, **kwargs)
  File "/usr/local/lib/python3.10/site-packages/click/core.py", line 1055, in main
    rv = self.invoke(ctx)
  File "/usr/local/lib/python3.10/site-packages/click/core.py", line 1657, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/local/lib/python3.10/site-packages/click/core.py", line 1404, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/local/lib/python3.10/site-packages/click/core.py", line 760, in invoke
    return __callback(*args, **kwargs)
  File "/usr/local/lib/python3.10/site-packages/psychonaut/cli/util.py", line 9, in wrapper
    return asyncio.run(func(*args, **kwargs))
  File "/usr/local/Cellar/[email protected]/3.10.6_2/Frameworks/Python.framework/Versions/3.10/lib/python3.10/asyncio/runners.py", line 44, in run
    return loop.run_until_complete(main)
  File "/usr/local/Cellar/[email protected]/3.10.6_2/Frameworks/Python.framework/Versions/3.10/lib/python3.10/asyncio/base_events.py", line 646, in run_until_complete
    return future.result()
  File "/usr/local/lib/python3.10/site-packages/psychonaut/cli/useful_queries.py", line 34, in resolve_handle
    resp = await resolve_handle_f(sess, req)
  File "/usr/local/lib/python3.10/site-packages/psychonaut/api/lexicons/com/atproto/identity/resolve_handle.py", line 27, in resolve_handle
    resp = await sess.query(req)
  File "/usr/local/lib/python3.10/site-packages/psychonaut/api/session.py", line 43, in query
    resp.raise_for_status()
  File "/usr/local/lib/python3.10/site-packages/aiohttp/client_reqrep.py", line 1005, in raise_for_status
    raise ClientResponseError(
aiohttp.client_exceptions.ClientResponseError: 400, message='Bad Request', url=URL('https://bsky.social/xrpc/[email protected]')

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.