How to use safe_client_libs in python?

I’m trying to login to the safe network using python.

I’ve compiled safe_authenticator using cargo build --release

Using the ctypes python module I can import the .so file into python:

authenticator = cdll.LoadLibrary("/path/to/libsafe_authenticator.so")

But I can’t call authenticator.login without the app crashing (segfault).

When I look at the input arguments for login I start having trouble.

The first two arguments are simple enough: secret_1 and secret_2 (presumably corresponding to ‘secret’ and ‘password’ in the UI?) which are just normal strings.

The third fourth and fifth arguments seem impossible to satisfy.

Third arg is type tokio_core::reactor::Handle which doesn’t seem to be exported

Fourth arg is type event_loop::CoreMsgTx also not exported

Fifth arg is type event::NetworkTx also not exported

I feel I must be lacking some crucial understanding, but searching the safe_browser javascript didn’t reveal anything useful to me.

Are these arguments possible to supply in python? Is it possible to login to the network using python? Am I even approaching this the right way?

5 Likes

You can imagine our API and libraries as a stack or an “onion” with several layers: the underlying library, SAFE Core, doesn’t have any notion of apps, Authenticator, or a browser. It’s just an abstract way to talk to the network, putting and getting structures like Immutable Data or Mutable Data. On top of that library we have a higher-level interfaces: SAFE App, the API to build apps, and SAFE Authenticator, the API for the “app centre”, for dealing with the users’ accounts, etc. And on the higher level we have the FFI interface: the functions that we expose to the world from Rust, and these functions can be used from any language, including Python.

So the problem on your side is that you’re looking at the lower-level Rust API; you’d want to use this API if you want to write your own libraries and layers like safe_authenticator or safe_app on top of safe_core. Instead, if you want to just write apps in Python, you’ll want to use the safe_app FFI layer, which is currently documented here: safe_app::ffi - Rust

Unfortunately though, we don’t provide any official Python bindings yet, so for now you’ll have to write your own or use an automatic generator. I’d suggest trying to look into the CFFI library in Python: this library allows you to import function and type definitions from C headers, which we automatically generate and provide in safe_client_libs (just look inside the auto-gen/c-include directory after you manually build the libs).

Please let me know if this explanation doesn’t make much sense to you or if you have further questions :slight_smile:

12 Likes

Thanks very much for this explanation, it helps a lot.

To add some context to my initial question (ie not looking for a response):

My main motivation is to be able to use safe via a scripting / non-gui interface with login and permissions etc all managed automatically. This goes against the canonical ‘safe app’ way of doing things (ie everything approved by the user via the browser / authenticator and developers using apps as the gateway to the network - from the getting started doc “When the user approves the request…” is the part I want to automate).

I can understand the desire to wrap everything around the app concept, but I find the way this a pretty unempowering interface. For now it’s fine, I’ll just write my code in rust so I can still do things at the very lowest level, but I think maybe in the future cleanly exposing the lowest level network interfaces will be useful (despite the security implications for end-users).

I prefer to be able to set permissions and authentication in $HOME/.safe_config file and let my safe apps run in the background with no gui or input needed.

But all the same I’m having a blast working with alpha2 so thanks for all the work so far :mage:

6 Likes

I too would like to be able to run scripts against an account. IoT stuff has so many methods, procedures etc that having something that I can script will make an easy path to integration in some cases.

2 Likes

Nothing prevents you from doing that now, actually. You can create your own minimal headless Authenticator on top of the safe_authenticator lib: the SAFE Browser and its Authenticator plugin aren’t magical, they’re too just apps that use the SAFE Client Libs underneath. And the Authenticator API is exposed and documented too, so you might want to experiment with it and build a terminal/non-GUI Authenticator that approves every request that it gets :slight_smile:

So what I want to say is that it’s more a question of security/user interface rather than the technical ability. But yes, for now we don’t provide a native headless mode in the SAFE Browser, as @joshuef answered here.

3 Likes

I’d like to be able to do this too. Much as I’m enjoying (re) learning JavaScript, interacting with SN using scripts and cli utilities opens up a whole new world. @cretz wrote a simple set of cli programs that talked directly to the old SAFE Launcher API, and they were a really helpful option. Similarly, when we had the cli for SAFE-VFS it was mind-blowing!

3 Likes

Where are these located?

Not sure, try user cretz on github, but they are for the old API, so not much use IMO.

Thanks for the tip. I found these on github:


I know they’re outdated, but I’m just trying to find some examples on how to work directly with safe_client_libs via native rust in order to make some simple/basic command line programs. It seemed like safe_core/examples/self_authentication.rs is was going to be a good start but it gives me build errors.

I’m looking forward to the ~30 page guide from @polpolrene that was slated to be released soon…

2 Likes

And @JPL :wink: I’m also looking forward to this.

Examples are there mainly for this purpose: to help you understand the native Rust API better, and they should work without requiring any changes. However, if you want to run them on the real network (i.e. not mock-routing), you’ll have to provide your credentials through environment variables.

Could you please provide more details about the build errors you’ve encountered?

My off-hand comment above was not a criticism, but rather a cry for help. Also, it wasn’t fair because the code example in the repo has been commented out and I was playing around trying to resurrect it in order to see if I could directly authenticate with alpha 2 using my credentials from the command line. (https://github.com/maidsafe/safe_client_libs/blob/master/safe_core/examples/self_authentication.rs)

The build errors look to be from api changes related to error messages being moved to private implementations and also from changes w.r.t. tokio connections. Example:

error[E0432]: unresolved import tokio_core::channel
→ src/main.rs:51:5
|
51 | use tokio_core::channel;
| ^^^^^^^^^^^^^^^^^^^ no channel in the root

There are plenty of other examples for me to play with, and I’ve moved on. In the future I’ll try to be much more specific if I run into any issues. I’m trying to conceptualize how all the pieces fit together and get some basic things working via text input rather than going the browser/javascript route. I’m not exactly sure where my entry point to the api should be, whether or not I should be dealing directly with safe_core, or sticking to safe_app. I’m very eager to learn more and will take all the advice you can offer. Any suggestions that you could give will help me get up to speed faster when trying to implement some terminal/CLI apps, but I also understand how busy you folks at MaidSafe are so don’t feel like you need to offer anything.

2 Likes

@jlpell saw this and thought of you, for anyone who fancies writing command line apps using Rust:

1 Like

Thanks. I’ll consider this along with getopts and docopt.

1 Like

If it helps I have found clap (this lib uses that) is much simpler and more powerful than getopts or docopts.

2 Likes

Ah sure, that’s why I am asking for details, wanting to help :slight_smile:

You’re right, some of the examples haven’t yet been ported from the previous version of the SAFE Client Libs API (the pre-authenticator one). Others can be a bit complicated but you can check e.g. client_stress_test and gen_invites for working examples.

You should also bear in mind that the Rust Client Libs API is built upon the foundation of futures (which quickly became idiomatic in Rust). So you might want to read more on the futures API and examples too.

Most of the operations go through the Client interface which is defined and implemented in safe_core. That way you can talk to the network directly; but it can be rather overwhelming if you want to go to the territory of SAFE Authenticator and apps. That’s why we have a multitude of helper functions in safe_app and safe_authenticator.

If you just want to create an app, you’ll need to go through the App interface, providing your credentials. It will connect to the network, create the event loop, etc., and then you can use the App.send method to obtain a Client instance and perform network operations. You can also find multiple usage examples in safe_app tests.

It’s unfortunate that currently Rust examples are scattered around numerous places. This is caused by the API itself being very unstable at the time. Now that it’s been stabilised, we intend to improve the documentation in the foreseeable future.

If you have any other questions or if my description wasn’t clear enough, please don’t hesitate to ask!

1 Like

I’m looking forward to the java bindings for the same reason. I moth balled my java fuse project as the rest API was being removed. I haven’t had much spare time to pursue this anyway, but I don’t think the java client libs are at a point where I could easily use them yet.

I am looking forward to working on this again though, especially when I may be out of contract in the summer.

Hello, @mav. Is your work available somewhere as a source code? I’m working on a Red bindings to libsafe_app. Perhaps sharing thoughts would be beneficient :slight_smile:

No, I discarded my work since it was all exploratory. I never had anything that would be considered ‘working’.

Heyhey,

i have been trying to get some more insight about python and safe and the C API
First of all: nope - i’m far away from our goal to utilize the C API from python and i would appreciate others helping and finding ways to make this happen :smiley:

… but i thought if i share my experiences here maybe others do have hints or get motivated to help out =D …

As I understand the API all exposed functions are functions “without return values” - i call the functions and hand over a couple of data structures and those functions modify my structures (please correct me if i’m completely on the wrong train here)
like this i don’t need to care about return values/data types there … i just read the current status in those data structures and if i need to do something i ask the library nicely to do that for me and will see the result in the structures.

here we go… what i got running: i just added a very simple function to the library and a struct containing numeric data types:

those sturctures are being built in python too so our program knows what it’s dealing with:

and finally i call the library from python and get the expected results

…now the tiny problem i have is that as soon as i try to connect to something string-like everything stops working :smiley:

there seem to be differences between c-strings and rust strings, and i would assume that a C-API expects char-arrays … so the “standard-c-strings” that are being created as char[] containing a byte-structure … if i’m not mistaken …

…i know this really is not much … but it’s more knowledge about how this is supposed to work before this weekend xD so maybe it helps someone else …

oh - and i pushed the modified client-libs + jupyter notebook to https://github.com/rid-dim/safe_client_libs >>> branch pythonTests … maybe it helps someone (or someone helps me :smiley: )

ps: and the final goal ofc will be to use some help from the c header files to auto-generate most of the code for the declarations in python:

…but i’m afraid that for doing this the one doing it first needs to understand what exactly needs to be generated …

6 Likes