Python wrapper for asynchronous interaction with Directus
Project description
py-directus
Disclaimer: Under development
This is very early in development and the API is subject to change.
If you intend to use this library in a production environment, expect undocumented changes and bugs until the first stable release.
If you find any issues or have any suggestions, please open an issue or a pull request.
Documentation here
py-directus is a Python wrapper for asynchronous interaction with the Directus headless CMS API. It provides a convenient and easy-to-use interface for performing CRUD operations, querying data, and managing resources in Directus.
Features
- Asynchronous
- Login and authentication handling
- Reading and writing data from Directus collections
- Filtering, sorting, and searching data
- Aggregating data using aggregation operators
- Creating, updating, and deleting items in Directus collections
- Handling multiple users in the same session
Dependencies:
- Pydantic: This library leverages Pydantic for data validation and parsing. Pydantic is a powerful tool in Python for ensuring data integrity and handling data validation with ease.
- HTTPX: The library utilizes HTTPX, a fully featured HTTP client for Python 3, which provides sync and async APIs, and support for both HTTP/1.1 and HTTP/2.
- python-magic: Wrapper for libmagic library for detecting media types.
Directus API: This library interacts with the Directus API.
To make the most of this library, it is highly recommended to familiarize yourself with the Directus API documentation. Understanding the API's capabilities and endpoints will help you effectively utilize this library for seamless integration with Directus.
Installation
You can install the library directly from pypi using pip:
$ pip install py-directus2
FastAPI support requires additional dependencies installation. You can install them along others like this:
$ pip install py-directus2[FastAPI]
To detect media types when uploading files, you'll need to have python-magic and libmagic installed in your system.
python-magic can be installed with "magic" extra:
$ pip install py-directus2[magic]
Authentication and Session Handling
Login
Create a Directus instance using email and password
from py_directus import Directus
directus = await Directus("https://example.com", email="user@example.com", password="secret")
Alternatively create a Directus instance using the static token
from py_directus import Directus
directus = await Directus("https://example.com", token="static_token")
Another way is to use the with statement to automatically logout when the session ends
async with Directus(url, email, password) as directus:
# Manually login
await directus.login()
# Manually start cache
await directus.start_cache()
# do stuff
# OR
async with await Directus(url, email, password) as directus:
# do stuff
Refresh Token
If you want to refresh the token you can use the refresh method
await directus.refresh()
Logout
Logout from Directus
await directus.logout()
Multiple Users in the Same Session
You can use multiple users in the same session by creating a new Directus instance by passing the client object
connection = httpx.AsyncClient()
directus1 = await Directus(url, token=token, connection=connection)
directus2 = await Directus(url, email=email, password=password, connection=connection)
Collections
There are two ways to set a collection, either by passing the collection name as a string or by passing the collection as a Pydantic model.
Using the collection method you can pass the collection name as a string
directus.collection("directus_users")
Or you can pass the collection as a Pydantic model
from typing import Optional
from pydantic import ConfigDict
from py_directus.models import DirectusModel
class User(DirectusModel):
id: Optional[str]
first_name: Optional[str]
last_name: Optional[str]
avatar: Optional[str]
description: Optional[str]
email: Optional[str]
role: Optional[str] | Optional[Role]
status: Optional[str]
title: Optional[str]
token: Optional[str]
model_config = ConfigDict(collection="directus_users")
directus.collection(User)
Don't forget to set the
collectionattribute in themodel_configattribute
If you go with the second option, you will get the responses as Pydantic models (auto parsing)
The
collectionmethod returns aDirectusRequestobject which is used to perform READ, CREATE, UPDATE and DELETE operations
Reading Data
When you have the DirectusRequest object you can use the read method to get the data.
This will return a DirectusResponse object which contains the data.
Imporatnt note: The
readmethod must be awaited
await directus.collection("directus_users").read()
Filtering
For an easy equality filter you can pass the field name and the value
await directus.collection("directus_users").filter(first_name="John").read()
To add multiple equality filters you can chain the filter method
await directus.collection("directus_users")
.filter(first_name="John")
.filter(last_name="Doe").read()
Using it like this you chain the filters with AND operator
F objects
To define complex logic in filters, use the F object
from py_directus import F
await directus.collection("directus_users")
.filter(
(F(first_name="John") | F(first_name="Jane"))
& F(last_name="Doe")
).read()
Important note: The
Fobject does not support negation
Sorting
You can sort the data by passing the field name to the sort method
await directus.collection("directus_users").sort("first_name", asc=True).read()
To add multiple sorting fields you can chain the sort method
await directus.collection("directus_users")
.sort("first_name", asc=True)
.sort("last_name", asc=False).read()
Limiting
You can limit the data by passing the limit to the limit method
await directus.collection("directus_users").limit(10).read()
Aggregation
Aggregate the number of records in the query
await directus.collection("directus_users").aggregate().read()
# OR
await directus.collection("directus_users").aggregate(count="*").read()
To add multiple aggregates you can chain the aggregate method
await directus.collection("products")
.aggregate(countDistinct="id")
.aggregate(sum="price").read()
Agg objects
You can aggregate the data by defining the needed aggregation with the Agg class and passing it to the aggregate method
from py_directus.aggregator import Agg
agg_obj = Agg(operator=AggregationOperators.Count)
await directus.collection("directus_users").aggregate(agg_obj).read()
In case you need only certain fields
from py_directus.aggregator import Agg
amount_agg = Agg(operator=AggregationOperators.Sum, fields="amount")
await directus.collection("transactions").aggregate(amount_agg).read()
The available aggregation operators are:
- Count
- CountDistinct
- CountAll (Only in GraphQL)
- Sum
- SumDistinct
- Average
- AverageDistinct
- Minimum
- Maximum
Grouping
You can group the data by passing the field names to the group_by method
await directus.collection("directus_users").group_by("first_name", "last_name").read()
Searching
You can search the data by passing the search term to the search method
await directus.collection("directus_users").search("John").read()
Selecting Fields
You can select the fields you want to get by passing the field names to the fields method
await directus.collection("directus_users").fields("first_name", "last_name").read()
Getting the Count Metadata
You can get the count of the data (total count and filtered count) calling include_count
await directus.collection("directus_users").include_count().read()
CRUD
Retrieving items
After you call read() you get a DirectusResponse object which contains the data.
itemfor single itemitemsfor multiple items
Getting the data as a dictionary or a list of dictionaries
response = await directus.collection("directus_users").read()
print(response.item["first_name"])
print(response.items)
If you provide the collection method a Pydantic model you will get the data as a Pydantic object or a list of Pydantic objects
response = await directus.collection(User).read()
print(response.item.first_name)
print(response.items)
Converting to Models (pydantic) or to Dictionary
Apart from the auto parsing, you can manually convert the data to a Pydantic model instance or to a dictionary using:
item_as(User)oritems_as(User)item_as_dict()oritems_as_dict()
response = await directus.collection("directus_users").read()
print(response.item_as(User))
response = await directus.collection(User).read()
print(response.item_as_dict())
Creating Items
The library does not support Pydantic models for creation, you have to pass a dictionary
- create(items: dict|List[dict])
await directus.collection("directus_users").create({
"first_name": "John", "last_name": "Doe"
})
# OR
await directus.collection("directus_users").create(
[
{"first_name": "John", "last_name": "Doe"},
{"first_name": "Jane", "last_name": "Doe"}
]
)
Updating Items
The library do not support Pydantic models for updating, you have to pass a dictionary
update(ids: str|int, items: dict)update(ids: List[str|int], items: List[dict])
await directus.collection("directus_users").update(1, {
"first_name": "Red",
"last_name": "John"
})
# OR
await directus.collection("directus_users").update(
[1, 2],
[
{"first_name": "Jean-Luc"},
{"first_name": "Jane", "last_name": "Doe"}
]
)
Deleting Items
delete(ids: str|int|List[str|int])
await directus.collection("directus_users").delete(1)
# OR
await directus.collection("directus_users").delete([1, 2])
Supporting
Pydanticmodels forcreate/update/deleteitem operations is shortly coming.
Examples
Examples are not included with the
pypipackage, so you will have to download them separately and execute in a virtual environment.
Run individual examples as such:
python -m examples.<example_file_name>
Tests
Run tests as such:
# All unit tests
python -m unittest discover -s tests/unit
# All integration tests
python -m unittest discover -s tests/integration
Acknowledgments
This is a fork of py-directus
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file py_directus2-0.1.0.tar.gz.
File metadata
- Download URL: py_directus2-0.1.0.tar.gz
- Upload date:
- Size: 23.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.9.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
08b778aa7c37e385efd730890bce9dba1dbf774f1379d2ff5221a2575ead71b8
|
|
| MD5 |
1f13bcbe163720a4075ecff539954f10
|
|
| BLAKE2b-256 |
da30b8492152e68a2e5c7b96bce3dc24c9b5434c7f14b81ba6588c39e19db888
|
File details
Details for the file py_directus2-0.1.0-py3-none-any.whl.
File metadata
- Download URL: py_directus2-0.1.0-py3-none-any.whl
- Upload date:
- Size: 30.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.9.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
eeb895468c18d37583b3e09eab8c82e16be3815e1ef92eca315dd518e873ff03
|
|
| MD5 |
7302e8a32614992ed60a5e74953d56d1
|
|
| BLAKE2b-256 |
4726d2a24229621c9036be37f2a145638608ee5936b1091849f247978119c854
|