ipfs-node 0.1.6__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ipfs_node/__init__.py +4 -0
- ipfs_node/ipfs_files.py +233 -0
- ipfs_node/ipfs_node.py +230 -0
- ipfs_node/ipfs_peers.py +71 -0
- ipfs_node/ipfs_pubsub.py +474 -0
- ipfs_node/ipfs_tunnels.py +263 -0
- ipfs_node/libkubo/libkubo_linux_x86_64.h +237 -0
- ipfs_node/libkubo/libkubo_linux_x86_64.so +0 -0
- ipfs_node/utils/__init__.py +3 -0
- ipfs_node/utils/cid_utils.py +55 -0
- ipfs_node/utils/peer_utils.py +62 -0
- ipfs_node-0.1.6.dist-info/LICENSE +21 -0
- ipfs_node-0.1.6.dist-info/METADATA +134 -0
- ipfs_node-0.1.6.dist-info/RECORD +18 -0
- ipfs_node-0.1.6.dist-info/WHEEL +5 -0
- ipfs_node-0.1.6.dist-info/top_level.txt +2 -0
- libkubo/__init__.py +1 -0
- libkubo/libkubo_loader.py +45 -0
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: ipfs_node
|
|
3
|
+
Version: 0.1.6
|
|
4
|
+
Summary: Run an IPFS node inside of python using kubo as a library.
|
|
5
|
+
Home-page: https://github.com/emendir/py_ipfs_node
|
|
6
|
+
Author: Emendir
|
|
7
|
+
Author-email:
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Requires-Python: >=3.7
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
Requires-Dist: cffi >=1.15.0
|
|
15
|
+
|
|
16
|
+
# Kubo Python Library
|
|
17
|
+
|
|
18
|
+
A Python wrapper for the Kubo (Go-IPFS) library.
|
|
19
|
+
|
|
20
|
+
## Overview
|
|
21
|
+
|
|
22
|
+
This library provides Python bindings for [Kubo](https://github.com/ipfs/kubo), the Go implementation of IPFS, allowing you to:
|
|
23
|
+
|
|
24
|
+
- Spawn an in-process IPFS node
|
|
25
|
+
- Add and retrieve files/directories from IPFS
|
|
26
|
+
- Connect to the IPFS network
|
|
27
|
+
- Manage IPFS repositories
|
|
28
|
+
- Publish and subscribe to IPFS PubSub topics
|
|
29
|
+
- Mount and connect to remote TCP services via libp2p
|
|
30
|
+
|
|
31
|
+
## Project Status
|
|
32
|
+
|
|
33
|
+
This library is very early in its development, and is published as a proof-of-concept that it is feasible to write a python wrapper around kubo (Go-IPFS) to run IPFS nodes from within python.
|
|
34
|
+
Much of the code is LLM-generated, and code coverage is poor.
|
|
35
|
+
|
|
36
|
+
The API structure of this library WILL CHANGE in the near future!
|
|
37
|
+
|
|
38
|
+
So far this library has been tested on Linux x86 64-bit and Android ARM 64-bit (in Termux & in Kivy).
|
|
39
|
+
Assuming that it proves to be a reliable way of working in python, this library will be developed to maturity and maintained.
|
|
40
|
+
|
|
41
|
+
## Installation
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
pip install ipfs_node
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Dev Requirements
|
|
48
|
+
|
|
49
|
+
- Go 1.19
|
|
50
|
+
- Python 3.7+
|
|
51
|
+
- IPFS Kubo dependencies
|
|
52
|
+
|
|
53
|
+
## Basic Usage
|
|
54
|
+
|
|
55
|
+
### Working with Files
|
|
56
|
+
|
|
57
|
+
```python
|
|
58
|
+
from ipfs_node import IpfsNode
|
|
59
|
+
|
|
60
|
+
# Create a new node with a temporary repository
|
|
61
|
+
with IpfsNode.ephemeral() as node:
|
|
62
|
+
# Add a file to IPFS
|
|
63
|
+
cid = node.files.publish("README.md")
|
|
64
|
+
print(f"Added file with CID: {cid}")
|
|
65
|
+
|
|
66
|
+
# Retrieve a file from IPFS
|
|
67
|
+
node.files.download(cid, "download.md")
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Using PubSub
|
|
71
|
+
|
|
72
|
+
```python
|
|
73
|
+
from ipfs_node import IpfsNode
|
|
74
|
+
|
|
75
|
+
with IpfsNode.ephemeral() as node:
|
|
76
|
+
# Subscribe to a topic
|
|
77
|
+
with node.pubsub.subscribe("my-topic") as subscription:
|
|
78
|
+
# Publish a message
|
|
79
|
+
node.pubsub.publish("my-topic", "Hello, IPFS world!")
|
|
80
|
+
|
|
81
|
+
# Receive messages
|
|
82
|
+
message = subscription.next_message(timeout=2.0)
|
|
83
|
+
if message:
|
|
84
|
+
print(f"Received: {message.data.decode('utf-8')}")
|
|
85
|
+
|
|
86
|
+
# Or use a callback
|
|
87
|
+
def on_message(msg):
|
|
88
|
+
print(f"Received via callback: {msg.data.decode('utf-8')}")
|
|
89
|
+
|
|
90
|
+
subscription.subscribe(on_message)
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Using TCP Tunnels (LibP2P Stream Mounting)
|
|
94
|
+
|
|
95
|
+
```python
|
|
96
|
+
from ipfs_node import IpfsNode
|
|
97
|
+
|
|
98
|
+
# Create an IPFS node
|
|
99
|
+
with IpfsNode.ephemeral() as node:
|
|
100
|
+
|
|
101
|
+
# Example 1: Listen for connections on a protocol and forward them to a local service
|
|
102
|
+
node.tunnels.open_listener("my-service", 8888)
|
|
103
|
+
|
|
104
|
+
# Example 2: Forward local connections to a remote peer
|
|
105
|
+
node.tunnels.open_sender("their-service", 8889, node.peer_id)
|
|
106
|
+
|
|
107
|
+
# List active listeners and streams
|
|
108
|
+
tunnels = node.tunnels.get_tunnels()
|
|
109
|
+
print(tunnels.listeners)
|
|
110
|
+
print(tunnels.senders)
|
|
111
|
+
|
|
112
|
+
# Close specific connections when done
|
|
113
|
+
node.tunnels.close_listener("my-service")
|
|
114
|
+
node.tunnels.close_sender("their-service")
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Documentation
|
|
118
|
+
|
|
119
|
+
- [Installation Instructions](INSTALL.md)
|
|
120
|
+
- [PubSub Documentation](docs/pubsub.md)
|
|
121
|
+
- [P2P Stream Mounting](docs/p2p.md)
|
|
122
|
+
|
|
123
|
+
## Examples
|
|
124
|
+
|
|
125
|
+
- [Basic Usage](examples/basic_usage.py)
|
|
126
|
+
- [File Sharing](examples/file_sharing.py)
|
|
127
|
+
- [PubSub Example](examples/pubsub_example.py)
|
|
128
|
+
- [Chat Application](examples/chat_app.py)
|
|
129
|
+
- [P2P Stream Mounting](examples/p2p_example.py)
|
|
130
|
+
- [P2P Socket Communication](examples/p2p_socket_example.py)
|
|
131
|
+
|
|
132
|
+
## License
|
|
133
|
+
|
|
134
|
+
MIT License
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
ipfs_node/__init__.py,sha256=hYyXSpnmMQLeaX2ssUVZl5ghbiVp-W2Ri_Dbdu9e1Jo,197
|
|
2
|
+
ipfs_node/ipfs_files.py,sha256=uM2u74VBRWwGGlSJNq_3A4_bYb7RdfIHXP5YVDDL43I,7985
|
|
3
|
+
ipfs_node/ipfs_node.py,sha256=E88bXvUjycwlPXAAa2pvRpQCANHGSFBWx9GQTIxRqsg,7287
|
|
4
|
+
ipfs_node/ipfs_peers.py,sha256=yp56fI9OpyzGg8JHt9o89lT2nWI4YpzMrRvUfETlPZc,2216
|
|
5
|
+
ipfs_node/ipfs_pubsub.py,sha256=g3mSV45BonYXZASgtWVGsi3VVSkZmOkBRldSRys6mlI,14439
|
|
6
|
+
ipfs_node/ipfs_tunnels.py,sha256=__681B9UzHXi7r1CP32uVEeMYlV8-O4JPc6yUKZwQ4M,9018
|
|
7
|
+
ipfs_node/libkubo/libkubo_linux_x86_64.h,sha256=OVfQ74CEPn8M6nDWkDQluwDgSeRJOV0wOyBAvBMGJqM,5743
|
|
8
|
+
ipfs_node/libkubo/libkubo_linux_x86_64.so,sha256=JTnr5s0vdrUTYWQNKiUSR6fGXjtRH7wKaQygiCqSwQI,82524080
|
|
9
|
+
ipfs_node/utils/__init__.py,sha256=gskzZJEh_l3vsWbpgQII732lYNfqA835YXvMlxKiDkA,91
|
|
10
|
+
ipfs_node/utils/cid_utils.py,sha256=K5g8VIueJDS0zsbkJV8ZccFa6rdOA9ShwsYJlyX-REU,1457
|
|
11
|
+
ipfs_node/utils/peer_utils.py,sha256=ynZKbg2L26r0DfRUNYcVQQP_eguK6xENTFUhxHpHGmE,1848
|
|
12
|
+
libkubo/__init__.py,sha256=vg0PGjCRNyMadI3bRYtTjfxoaA6XMO7klgZuR2vQ2nU,67
|
|
13
|
+
libkubo/libkubo_loader.py,sha256=a691BPSD_VRC8AdFCB7ihKEypDXrmtMXtpC5gjTxljM,1257
|
|
14
|
+
ipfs_node-0.1.6.dist-info/LICENSE,sha256=O-0zMbcEi6wXz1DiSdVgzMlQjJcNqNe5KDv08uYzqR0,1055
|
|
15
|
+
ipfs_node-0.1.6.dist-info/METADATA,sha256=gnaQYxi9bMy5FTa_5p1TziulfQjR0fuQG7tRrC2Cuo4,3784
|
|
16
|
+
ipfs_node-0.1.6.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
|
|
17
|
+
ipfs_node-0.1.6.dist-info/top_level.txt,sha256=JqYMx6doRQgowycGRhKqc0zfikahqizuG9128CZcF3Y,18
|
|
18
|
+
ipfs_node-0.1.6.dist-info/RECORD,,
|
libkubo/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .libkubo_loader import libkubo, c_str, from_c_str, ffi, c_bool
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
from cffi import FFI
|
|
2
|
+
import platform
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
ffi = FFI()
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
# Determine library name based on platform
|
|
8
|
+
if platform.system() == 'Windows':
|
|
9
|
+
lib_name = 'libkubo.dll'
|
|
10
|
+
header_name = 'libkubo.h'
|
|
11
|
+
elif platform.system() == 'Darwin':
|
|
12
|
+
lib_name = 'libkubo.dylib'
|
|
13
|
+
header_name = 'libkubo.h'
|
|
14
|
+
else:
|
|
15
|
+
if "aarch64" == platform.machine():
|
|
16
|
+
lib_name = "libkubo_android_arm64.so"
|
|
17
|
+
header_name = "libkubo_android_arm64.h"
|
|
18
|
+
else:
|
|
19
|
+
lib_name = 'libkubo_linux_x86_64.so'
|
|
20
|
+
header_name = 'libkubo_linux_x86_64.h'
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
# Get the absolute path to the library
|
|
25
|
+
lib_path = str(Path(__file__).parent / lib_name)
|
|
26
|
+
header_path = str(Path(__file__).parent / header_name)
|
|
27
|
+
|
|
28
|
+
with open(header_path) as file:
|
|
29
|
+
lines = [line.strip() for line in file.readlines()]
|
|
30
|
+
func_declarations = [
|
|
31
|
+
line for line in lines if line.startswith("extern ") and line.endswith(";")
|
|
32
|
+
]
|
|
33
|
+
ffi.cdef("\n".join(func_declarations))
|
|
34
|
+
ffi.set_source("libkubo", None)
|
|
35
|
+
libkubo = ffi.dlopen(lib_path)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def c_str(data:str|bytes):
|
|
39
|
+
if isinstance(data, str):
|
|
40
|
+
data = data.encode()
|
|
41
|
+
return ffi.new("char[]", data)
|
|
42
|
+
def from_c_str(string_ptr):
|
|
43
|
+
return ffi.string(string_ptr).decode('utf-8')
|
|
44
|
+
def c_bool(value: bool):
|
|
45
|
+
return ffi.new("bool *", value)[0]
|