
[](https://psychonaut.readthedocs.io/en/latest/?badge=latest)

# 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,
```python
async with get_simple_client_session() as sess:
posts: GetPostsResp = await GetPostsReq(uris=[...]).do_xrpc(sess)
...
```
which feels backwards from the expected,
```python
async with get_simple_client_session() as sess:
posts: GetPostsResp = await sess.do_xrpc(GetPostsReq(uris=[...]))
```
or even,
```python
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.
```bash
# 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.
```bash
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](https://pypa.github.io/pipx/)
```bash
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.
```bash
# 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](https://github.com/bluesky-social/atproto),
me, and my friend ChatGPT (using GPT-4). I had been toying around with this
automatic `langa`<->`langb` transpiler in [langchain](https://github.com/hwchase17/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)
- [arroba](https://github.com/snarfed/arroba)
- [lexrpc](https://github.com/snarfed/lexrpc)
- [atprotools](https://github.com/ianklatzco/atprototools)
Raw data
{
"_id": null,
"home_page": "https://github.com/jbn/psychonaut",
"name": "psychonaut",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.10,<4.0",
"maintainer_email": "",
"keywords": "",
"author": "generativist",
"author_email": "jbn@abreka.com",
"download_url": "https://files.pythonhosted.org/packages/67/17/f013eef671b60b145880b665ab7388db7538c99ca90aa565f1f8d1f2e1e7/psychonaut-0.0.16.tar.gz",
"platform": null,
"description": "\n[](https://psychonaut.readthedocs.io/en/latest/?badge=latest)\n\n\n\n\n# PROGRESS REPORT\n\n- [ ] Finish pydantic validation for reference types\n\n# What is this?\n\nAn async python sdk for Bluesky.\n\nI used to do a pretty absurd amount of experiments with twitter's api. But musk\nhas decided to turn that platform into a pay-for-play version of LinkedIn\nand banished all the tinkerers. So, now I'm here.\n\nIt has a bit of a weird structure. You basically do things like,\n\n```python\nasync with get_simple_client_session() as sess:\n posts: GetPostsResp = await GetPostsReq(uris=[...]).do_xrpc(sess)\n ...\n```\n\nwhich feels backwards from the expected,\n\n```python\nasync with get_simple_client_session() as sess:\n posts: GetPostsResp = await sess.do_xrpc(GetPostsReq(uris=[...]))\n```\n\nor even,\n\n```python\nasync with get_simple_client_session() as sess:\n posts: GetPostsResp = await sess.get_posts(uris=[...])\n```\n\nIt's kinda an artifact of the way I did code generation but I kinda like it\nand fuck it S-expressions worked so there is a (completely nonsensical)\nprecedence. \n\n**And, just to clarify, every request and response gets validated against the lexicon schema**, \nwhich is nice (although reference types are still a WIP). Moreover, the \ngenerated code is auto-complete/copilot friendly. And, in theory, you could override\n`do_xrpc` to do clever things like caching, instead of hacking each particular api call.\n\nBut mostly I'm lazy so this is how it is.\n\n# Should I use this?\n\n~~Almost certainly not. Right now it's a bucket of slop. I offer no \nguarantees about the stability of the API, the correctness of the\nimplementation, or the quality of the documentation.~~\n\nIf you want to use it, go ahead.\n\nEvery single api call exists with Pydantic models for requests and responses\n(but with a few outstanding validations missing).\n\nIt's still unstable but I've been using it pretty regularly.\n\n```bash\n# In your venv or mamba env or whatever\npip install psychonaut\n```\n\nto use it as a library. This also installs the `psychonaut` command line tool.\n\n```bash\npsychonaut --help\n\n# Temporary login\nexport BSKY_USERNAME=yourusername\nexport BSKY_PASSWORD=yourpassword\n\n# Permanent login (~/.psychonaut.json)\npsychonaut save-login yourusername \n\npsychonaut poast \"hey look, an annoying cron job\"\n```\n\nBut definitely be mindful of the version because I'm going to break your code.\n\nAlternatively, just use [pipx](https://pypa.github.io/pipx/)\n\n```bash\npipx install psychonaut\n\nexport BSKY_USERNAME=yourusername\nexport BSKY_PASSWORD=yourpassword\n\npsychonaut poast \"hell yea, pipx\"\n```\n\n### Firehose\n\n**EXTREMELY EXPERIMENTAL AND STILL NOT FINISHED**\n\n`repos-firehose-stream` saves the raw messages for subsequent replay so you\ncan at least collect now and i'll get the json emit / validation working\nlater.\n\n```bash\n# Stream the firehose\npsychonaut repos-firehose-stream stream_dir\n\n# Stream the firehose but print to stdout too\npsychonaut repos-firehose-stream --tee stream_dir\n\n# Replay serialized\npsychonaut repos-firehose-replay stream_dir\n\n# Replay serialized file\npsychonaut repos-firehose-replay stream_dir/your_stream.b64-lines\n```\n\n# How is this made?\n\nInitially, this was a collaboration between the [atproto repo](https://github.com/bluesky-social/atproto),\nme, and my friend ChatGPT (using GPT-4). I had been toying around with this \nautomatic `langa`<->`langb` transpiler in [langchain](https://github.com/hwchase17/langchain).\nMy original goal was to jointly build that while making my python client from the `atproto`\nrepo. However, the fine folks at OpenAI didn't give me \nGPT-4 API access, and GPT-3 isn't quite good enough to do the job. So instead, \nthis was me testing the fences \"manually\" (with ChatGPT). And now it's *just*\nme.\n\nThis also means this project was a bit...like theft? IDK. \n\nQuestion of the generative hour: where is the boundary?\n\n# See Also (for pythonistas)\n\n- [arroba](https://github.com/snarfed/arroba) \n- [lexrpc](https://github.com/snarfed/lexrpc) \n- [atprotools](https://github.com/ianklatzco/atprototools) ",
"bugtrack_url": null,
"license": "MIT",
"summary": "Python async client and TUI for bsky",
"version": "0.0.16",
"project_urls": {
"Documentation": "https://github.com/jbn/psychonaut",
"Homepage": "https://github.com/jbn/psychonaut",
"Repository": "https://github.com/jbn/psychonaut"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "42a2a834b10b897ae2a2e79546f26f20717fc5d8d96e525826f91ec9540629d2",
"md5": "91830670aba7db2ba043355ba781058f",
"sha256": "3960fa5fdce43f4e9f9d8398c5b175e7db36fe71c673d0c983a506a83ad84cc1"
},
"downloads": -1,
"filename": "psychonaut-0.0.16-py3-none-any.whl",
"has_sig": false,
"md5_digest": "91830670aba7db2ba043355ba781058f",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.10,<4.0",
"size": 123231,
"upload_time": "2023-05-14T17:56:03",
"upload_time_iso_8601": "2023-05-14T17:56:03.705964Z",
"url": "https://files.pythonhosted.org/packages/42/a2/a834b10b897ae2a2e79546f26f20717fc5d8d96e525826f91ec9540629d2/psychonaut-0.0.16-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "6717f013eef671b60b145880b665ab7388db7538c99ca90aa565f1f8d1f2e1e7",
"md5": "81acfd7e6807522ab1f80ba2ffddd183",
"sha256": "28f776646d04856735ffa331c6353f666941709c6551e9152e2246a112b1f1d3"
},
"downloads": -1,
"filename": "psychonaut-0.0.16.tar.gz",
"has_sig": false,
"md5_digest": "81acfd7e6807522ab1f80ba2ffddd183",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10,<4.0",
"size": 64340,
"upload_time": "2023-05-14T17:56:05",
"upload_time_iso_8601": "2023-05-14T17:56:05.988702Z",
"url": "https://files.pythonhosted.org/packages/67/17/f013eef671b60b145880b665ab7388db7538c99ca90aa565f1f8d1f2e1e7/psychonaut-0.0.16.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-05-14 17:56:05",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "jbn",
"github_project": "psychonaut",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "psychonaut"
}