There are several libraries that plugins can import for programmatic access to records stored in CycleServer.

The application.datastore plugin provides the following methods to load and store records:

get(type, key1, key2, key3…)
Returns the record uniquely defined by the given key, or null if none exists.
find(type, [filter])
Returns a list of the records of the given type. If the filter is supplied, it is evaluated as a classad expression, and only records matching the filter are returned.
query(query|view)
Returns the records from the given SELECT query. This can include limits on the attributes returned, as well as ORDER BY and LIMIT clauses.
save(record|records)
Stores the given record or records if it does not exist. Merges the supplied attributes in if it does.
delete(type, filter)

Deletes records that match the given filter and type. Note: Records are only flagged as deleted and can still be seen if desired:

datatore.query("SELECT * FROM YourType WHERE _Deleted is true")
purge(type, filter)
Removes records that match the given filter and type from the datastore.

The application.records plugin lets you create new record objects:

create()
Returns an empty record
create(type)
Returns a new record of the given type
create(type, key1, key2, key3…)
Creates a record of the given type identified by the given key values
create(map)
Returns a record based on the given map or dictionary

The application.expressions plugin simplifies working with datastore expressions:

parse(text)
Returns the result of parsing the given expression. Example: expressions.parse("Attribute == "abc"")
attributeEqualsValue(attribute, value)
Returns the expression attribute == value. Note that value is automatically quoted if needed.
attributeIn(attribute, values…)
Returns the expression attribute IN {values}. Values are automatically quoted if needed.
attributesIn(attributes, tuples_list…)

Returns the expression {attributes} IN {{tuples_list}}. The tuples_list argument is a list of lists. Each inner list must have as many items as the list of attributes. Example:

attributesIn(["abc", "def"], [ [123, 456], [789, "abc"] ])

would return this expression:

{abc, def} IN { { 123, 456 }, { 789, "abc" } }
andAll(expressions…)
Combines all expressions with the && operator.
orAll(expressions…)
Combines all expressions with the || operator.
toExpression(obj)
Converts the given base object (string, integer, list, etc) into its Expression equivalent
toObject(expr)
Converts the given expression into the base object, if possible. Composite expressions like
binary operators and function calls are unconverted.

Interacting with the Plugin API from Jython

It is very easy to experiment with the plugin API using the Jython interpreter that ships with CycleServer.

$ $CS_HOME/util/jython
>>> from application import datastore
>>> ds = datastore.connectToRemoteDataStore('http://localhost:8080', 'user', 'pass')
>>> ds.get('Application.Timer', 'plugin.cycle.application.task.cleanup')
[ AdType="Application.Timer"; CurrentState="Idle"; EnteredCurrentState=`2016-04-26T12:09:34.696+07:00`; FireCount=70; FireTime=`2016-04-26T12:09:34.445+07:00`; Interval=`1:00:00`; LastFireTime=`2016-04-26T11:09:34.444+07:00`; LastRuntime=`0.013`; LastScheduledFireTime=`2016-04-26T11:09:34.444+07:00`; LastStatus=true; LastStatusMessage="Timer plugin.cycle.application.task.cleanup completed"; MisfireCount=9; Misfired=false; Name="plugin.cycle.application.task.cleanup"; NextFireTime=`2016-04-26T13:09:34.444+07:00`; Plugin="cycle.application.task.cleanup"; Schedule=undefined; ScheduledFireTime=`2016-04-26T12:09:34.444+07:00`; StartTime=`2016-04-12T13:31:46.086+07:00` ]
>>> from application.expressions import parse
>>> ds.find('Application.Timer', parse('Name=="plugin.cycle.application.task.cleanup"'))
[ AdType="Application.Timer"; CurrentState="Idle"; EnteredCurrentState=`2016-04-26T12:09:34.696+07:00`; FireCount=70; FireTime=`2016-04-26T12:09:34.445+07:00`; Interval=`1:00:00`; LastFireTime=`2016-04-26T11:09:34.444+07:00`; LastRuntime=`0.013`; LastScheduledFireTime=`2016-04-26T11:09:34.444+07:00`; LastStatus=true; LastStatusMessage="Timer plugin.cycle.application.task.cleanup completed"; MisfireCount=9; Misfired=false; Name="plugin.cycle.application.task.cleanup"; NextFireTime=`2016-04-26T13:09:34.444+07:00`; Plugin="cycle.application.task.cleanup"; Schedule=undefined; ScheduledFireTime=`2016-04-26T12:09:34.444+07:00`; StartTime=`2016-04-12T13:31:46.086+07:00` ]