First Steps with PyLinkAhead#
In this tutorial, you will connect to a LinkAhead server using the Python client, run queries, work with the returned data, and extract property values for analysis. The web interface is convenient for interactive browsing, while PyLinkAhead is designed for scripting, automation, and data analysis workflows.
Concept |
PyLinkAhead |
|---|---|
Connect to a server |
|
Run a query |
|
Access a record |
|
Read a property |
|
Read a property’s value |
|
Record id |
|
Single-result queries |
|
Download a file |
|
Prerequisites#
Before starting, make sure that:
PyLinkAhead is installed: see the setup guide.
A connection is configured for your instance: see How to Configure PyLinkAhead. For this tutorial you can skip this and use the public demo instead.
You have access to a LinkAhead instance: you can use the public demo.
You are familiar with basic LinkAhead concepts such as Records, RecordTypes, and Properties: see the LinkAhead Web Interface Tutorial.
You know the basics of the LinkAhead query language: see the LinkAhead Query Tutorial.
The examples below use the public demo instance hosted by IndiScale.
Setup#
Connecting to a LinkAhead Server#
In regular use, PyLinkAhead reads connection settings from ~/.pylinkahead.ini automatically when
you import the library, no extra code needed. This tutorial uses configure_connection() instead to
keep the examples self-contained and work with the public demo out of the box.
Open a Python interactive session (python3 in your terminal) or create a new .py script file.
All code examples on this page are Python, not shell commands.
First, import the Python client:
import linkahead as db
Then configure the connection to the demo instance:
db.configure_connection(
url="https://demo.indiscale.com/",
username="admin",
password="caosdb",
password_method="plain",
)
Note
password_method="plain" is suitable only for the public demo instance and should not be used for
production systems.
Querying Data#
Running Your First Query#
Queries in PyLinkAhead use the same query language as the web interface. The demo instance contains a small music dataset with guitar records and musical analyses.
response = db.execute_query("FIND Guitar")
print(type(response))
The result is returned as a Container object:
<class 'linkahead.common.models.Container'>
A Container behaves similarly to a Python list and contains the matching LinkAhead entities. You
can check how many results were returned:
print(len(response))
6
Working with Records#
You can access individual records using normal list indexing and print them to see their full representation including parent and properties:
first_guitar = response[0]
print(first_guitar)
<Record id="115" name="My first guitar">
<Version id="cf205bfafd852c1aba3a6eee8b502feeff89e320" head="true">
<Predecessor id="595403aae4bb593712b0aa653f70f6a8be0e0a42"/>
</Version>
<Parent id="110" name="Guitar" flag="inheritance:NONE,"/>
<Property id="100" name="price" datatype="DOUBLE" unit="€" ...>48.0</Property>
<Property id="106" name="electric" datatype="BOOLEAN" ...>False</Property>
<Property id="131" name="Photograph" datatype="Photograph" ...>132</Property>
</Record>
The ... in the output above is an abbreviation; the actual output includes additional attributes
on each property.
A Record contains metadata and properties that can be accessed programmatically.
Accessing Properties#
Properties can be accessed by name:
price_property = first_guitar.get_property("price")
print(price_property)
<Property id="100" name="price" datatype="DOUBLE" unit="€">48.0</Property>
To access only the value:
price_value = first_guitar.get_property("price").value
print(price_value)
48.0
Properties can also be accessed by their numeric id:
price_by_id = first_guitar.get_property(100)
print(price_by_id)
<Property id="100" name="price" datatype="DOUBLE" unit="€">48.0</Property>
Using ids can be useful when names are not guaranteed to be unique across a data model.
Querying for a Single Record#
Pass unique=True when you know a query returns exactly one record. It is useful as a safety check:
instead of silently returning the first item from a list, it raises an error if zero or more than
one result is found, so unexpected data does not go unnoticed. The call also returns a Record
directly instead of a Container, so you do not need to index into a list. The demo contains one
MusicalAnalysis record with quality_factor=0.08:
record = db.execute_query(
"FIND MusicalAnalysis with quality_factor=0.08",
unique=True,
)
You can then access the record type and id directly:
record_type = type(record)
record_id = record.id
print(record_type)
print(record_id)
<class 'linkahead.common.models.Record'>
123
Record ids are useful for constructing follow-up queries:
query = (
"FIND Guitar WHICH IS REFERENCED BY {id}"
.format(id=record.id)
)
guitar = db.execute_query(query, unique=True)
print(guitar)
<Record id="115" ...
Analyzing Data#
Extracting Values from Multiple Records#
The demo contains MusicalAnalysis records with a quality_factor property. Query them:
analyses = db.execute_query("FIND MusicalAnalysis WITH quality_factor")
Iterate over the container to collect all values:
qfs = [a.get_property("quality_factor").value for a in analyses]
print(qfs)
[0.08]
You can use these values with standard Python libraries, for example to create a histogram:
import matplotlib.pyplot as plt
plt.hist(qfs)
plt.xlabel("quality factor")
plt.ylabel("count")
plt.show()
Note
This example is illustrative and not backed by an automated test.
Working with Files#
Downloading Files#
File records can be downloaded directly from Python. The demo instance contains a photo of the first guitar we queried earlier:
file_record = db.execute_query(
"FIND FILE *my_first_guitar*",
unique=True,
)
target_path = file_record.download()
print(target_path)
The downloaded file is stored locally, and the path is returned as target_path.
For large datasets, it can be more efficient to access files through a mounted filesystem instead of downloading them through the API.
Summary#
This tutorial covered:
Connecting to a LinkAhead server.
Running queries from Python.
Working with
ContainerandRecordobjects.Accessing record properties by name and id.
Extracting property values from multiple records.
Using ids in follow-up queries.
Downloading files.
Continue with Creating a Data Model to create Properties, RecordTypes, and inheritance hierarchies in LinkAhead.