Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update examples, readme and remove old version #92

Merged
merged 4 commits into from
Apr 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
160 changes: 34 additions & 126 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,177 +62,85 @@

# surrealdb.py

The official SurrealDB library for Python.
The official SurrealDB SDK for Python.

[See the documentation here](https://surrealdb.com/docs/integration/libraries/python)
[See the documentation here](https://surrealdb.com/docs/surrealdb/integration/sdks/python)

## Getting Started
Below is a quick guide on how to get started with SurrealDB in Python.

### Running SurrealDB
Before we can do anything, we need to download SurrealDB and start the server. The easiest, cleanest way to do this
is with [Docker](https://www.docker.com/) abd [docker-compose](https://docs.docker.com/compose/) with the following
docker-compose file:

```yaml
version: '3'
services:
surrealdb:
image: surrealdb/surrealdb
command: start
environment:
- SURREAL_USER=root
- SURREAL_PASS=root
- SURREAL_LOG=trace
ports:
- 8000:8000
```
Here we are pulling the offical SurrealDB image from Docker Hub and starting it with the `start` command. We are also
setting the environment variables `SURREAL_USER` and `SURREAL_PASS` to `root` and `SURREAL_LOG` to `trace`. This will
allow us to connect to the database with the username `root` and password `root` and will set the log level to `trace`.
Finally, we are exposing port `8000` so we can connect to the database.

Now that we have everything up and running, we can move onto installing the Python library.
Before we can do anything, we need to download SurrealDB and start the server.
[See how to do that here](https://surrealdb.com/docs/surrealdb/installation/)

### Installing the Python Library
After we have everything up and running, we can install the Python SDK.

Right now the library is in beta, so you will need to install it from GitHub with Rust installed on your machine
as Rust will be needed to compile part of the library. Installation for Rust can be found
[here](https://www.rust-lang.org/tools/install). Once Rust is installed, you can install this library with the
following command:
### Installing the Python SDK

```bash
pip install git+https://github.com/surrealdb/surrealdb.py@rust-no-runtime
```

Installation can take a while as it needs to compile the Rust code. If you want to use the python client in a Docker
build in production you can use a two layered build which will use Rust to compile the library and then copy the
compiled library into a new python image so your production image doesn't need to have Rust installed. Below is an
example of a Dockerfile that will do this for a Flask application:

```dockerfile
FROM rust:latest as builder

RUN apt-get update
RUN apt install python3.9 -y
RUN apt-get install -y python3-dev -y
RUN apt-get install -y python3-pip -y
RUN pip install --upgrade pip setuptools wheel

RUN apt-get install libclang-dev -y

# Set the working directory to /app
WORKDIR /app

# Copy the current directory contents into the container at /app
ADD . /app

# install the python library locally
RUN pip install ./surreal.py/

# or install the python library from github
RUN pip install git+https://github.com/surrealdb/surrealdb.py@rust-no-runtime

# server build
FROM python:3.9

RUN apt-get update \
&& apt-get install -y python3-dev python3-pip \
&& pip install --upgrade pip setuptools wheel \
&& pip install flask gunicorn

WORKDIR /app

# copy the built python packages from the previous stage to the new image
COPY --from=builder /usr/local/lib/python3.9/dist-packages /usr/local/lib/python3.9/site-packages

# copy the python server app code to the new image
COPY --from=builder /app /app

# Run the python server using gunicorn
CMD ["gunicorn", "-w", "4", "-b", "0.0.0.0:5002", "--timeout", "900", "main:app"]
pip install surrealdb
```

You can change the python version and the `CMD` could change depending on your application. Now that we have our
python application installing and running with SurrealDB, we can move onto using the python library.
### Using the (synchronous) Python methods

### Using the blocking Python Library

We can then import the library and create the connection with the following code:
Import the SDK and create the database connection:

```python
from surrealdb import SurrealDB

connection = SurrealDB("ws://localhost:8000/database/namespace")
db = SurrealDB("ws://localhost:8000/database/namespace")
```
Here, we can see that we defined the connection protocol as websocket using `ws://`. We then defined the host as
`localhost` and the port as `8000`. Finally, we defined the database and namespace as `database` and `namespace`.

Here, we can see that we defined the connection protocol as WebSocket using `ws://`. We then defined the host as `localhost` and the port as `8000`.

Finally, we defined the database and namespace as `database` and `namespace`.
We need a database and namespace to connect to SurrealDB.

Now that we have our connection we need to signin using with the following code:
Now that we have our connection we need to signin:

```python
connection.signin({
db.signin({
"username": "root",
"password": "root",
})
```
For our getting started example we are now going to run some simple raw SurrealQL queries to create some users and
then select them. We can then print the outcome of the query with the following code:
We can now run our queries to create some users, select them and print the outcome.

```python
connection.query("CREATE user:tobie SET name = 'Tobie';")
connection.query("CREATE user:jaime SET name = 'Jaime';")
outcome = connection.query("SELECT * FROM user;")
db.query("CREATE user:tobie SET name = 'Tobie';")
db.query("CREATE user:jaime SET name = 'Jaime';")
outcome = db.query("SELECT * FROM user;")
print(outcome)
```

This will give you the following JSON output:

```json
[
{
"id": "user:jaime",
"name": "Jaime"
},
{
"id": "user:tobie",
"name": "Tobie"
}
]
```

### Using the async Python Library
### Using the async Python methods

We can then import the library and create the connection with the following code:

```python
from surrealdb import AsyncSurrealDB

connection = AsyncSurrealDB("ws://localhost:8000/database/namespace")
await connection.connect()
```

Essentially the interface is exactly the same however, the functions are async. Below is a way to run the async code:
The async methods work in the same way, with two main differences:
- Inclusion of `async def / await`.
- You need to call the connect method before signing in.

```python
import asyncio
from surrealdb import AsyncSurrealDB


async def main():
connection = AsyncSurrealDB("ws://localhost:8000/database/namespace")
await connection.connect()
await connection.signin({
db = AsyncSurrealDB("ws://localhost:8000/database/namespace")
await db.connect()
await db.signin({
"username": "root",
"password": "root",
})
await connection.query("CREATE user:tobie SET name = 'Tobie';")
await connection.query("CREATE user:jaime SET name = 'Jaime';")
outcome = await connection.query("SELECT * FROM user;")
await db.query("CREATE user:tobie SET name = 'Tobie';")
await db.query("CREATE user:jaime SET name = 'Jaime';")
outcome = await db.query("SELECT * FROM user;")
print(outcome)


# Run the main function
asyncio.run(main())
```

### Using Jupyter Notebooks

The Python SDK currently only supports the `AsyncSurrealDB` methods.
62 changes: 62 additions & 0 deletions examples/basic_async_example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
from surrealdb import AsyncSurrealDB

async def main():
"""Example of how to use the SurrealDB client."""
db = AsyncSurrealDB("ws://localhost:8000/database/namespace")

await db.connect()

await db.signin({
"username": "root",
"password": "root",
})

print("Using methods")
print("create: " ,await db.create(
"person",
{
"user": "me",
"pass": "safe",
"marketing": True,
"tags": ["python", "documentation"],
},
))
print("read: ", await db.select("person"))
print("update: ", await db.update("person", {
"user":"you",
"pass":"very_safe",
"marketing": False,
"tags": ["Awesome"]
}))
print("delete: ", await db.delete("person"))

# You can also use the query method
# doing all of the above and more in SurrealQl

# In SurrealQL you can do a direct insert
# and the table will be created if it doesn't exist
print("Using justawait db.query")
print("create: ", await db.query("""
insert into person {
user: 'me',
pass: 'very_safe',
tags: ['python', 'documentation']
};

"""))
print("read: ", await db.query("select * from person"))

print("update: ", await db.query("""
update person content {
user: 'you',
pass: 'more_safe',
tags: ['awesome']
};

"""))
print( "delete: ", await db.query("delete person"))

if __name__ == "__main__":
import asyncio

asyncio.run(main())
108 changes: 53 additions & 55 deletions examples/basic_example.py
Original file line number Diff line number Diff line change
@@ -1,55 +1,53 @@
from surrealdb import Surreal


async def main():
"""Example of how to use the SurrealDB client."""
async with Surreal("ws://localhost:8000/rpc") as db:
await db.signin({"user": "root", "pass": "root"})
await db.use("test", "test")
await db.create(
"person",
{
"user": "me",
"pass": "safe",
"marketing": True,
"tags": ["python", "documentation"],
},
)
print(await db.select("person"))
print(await db.update("person", {
"user":"you",
"pass":"very_safe",
"marketing": False,
"tags": ["Awesome"]
}))
print(await db.delete("person"))

# You can also use the query method
# doing all of the above and more in SurrealQl

# In SurrealQL you can do a direct insert
# and the table will be created if it doesn't exist
await db.query("""
insert into person {
user: 'me',
pass: 'very_safe',
tags: ['python', 'documentation']
};

""")
print(await db.query("select * from person"))

print(await db.query("""
update person content {
user: 'you',
pass: 'more_safe',
tags: ['awesome']
};

"""))
print(await db.query("delete person"))

if __name__ == "__main__":
import asyncio

asyncio.run(main())
from surrealdb import SurrealDB

db = SurrealDB("ws://localhost:8000/database/namespace")

db.signin({
"username": "root",
"password": "root",
})

print("Using methods")
print("create: ", db.create(
"person",
{
"user": "me",
"pass": "safe",
"marketing": True,
"tags": ["python", "documentation"],
},
))
print("read: ", db.select("person"))
print("update: ", db.update("person", {
"user":"you",
"pass":"very_safe",
"marketing": False,
"tags": ["Awesome"]
}))
print("delete: ", db.delete("person"))

# You can also use the query method
# doing all of the above and more in SurrealQl

# In SurrealQL you can do a direct insert
# and the table will be created if it doesn't exist
print("Using just db.query")
print("create: ", db.query("""
insert into person {
user: 'me',
pass: 'very_safe',
tags: ['python', 'documentation']
};

"""))
print("read: ", db.query("select * from person"))

print("update: ", db.query("""
update person content {
user: 'you',
pass: 'more_safe',
tags: ['awesome']
};

"""))
print( "delete: ", db.query("delete person"))
Loading
Loading