def create_resource(self, resource_type=None, uri=None):
'''
Convenience method for creating a new resource
Note: A Resource is instantiated, but is not yet created. Still requires resource.create().
Args:
uri (rdflib.term.URIRef, str): uri of resource to create
resource_type (NonRDFSource (Binary), BasicContainer, DirectContainer, IndirectContainer): resource type to create
Returns:
(NonRDFSource (Binary), BasicContainer, DirectContainer, IndirectContainer): instance of appropriate type
'''
if resource_type in [NonRDFSource, Binary, BasicContainer, DirectContainer, IndirectContainer]:
return resource_type(self, uri)
else:
raise TypeError("expecting Resource type, such as BasicContainer or NonRDFSource")
python类term()的实例源码
def copy(self, destination):
'''
Method to copy resource to another location
Args:
destination (rdflib.term.URIRef, str): URI location to move resource
Returns:
(Resource) new, moved instance of resource
'''
# set move headers
destination_uri = self.repo.parse_uri(destination)
# http request
response = self.repo.api.http_request('COPY', self.uri, data=None, headers={'Destination':destination_uri.toPython()})
# handle response
if response.status_code == 201:
return destination_uri
else:
raise Exception('HTTP %s, could not move resource %s to %s' % (response.status_code, self.uri, destination_uri))
def add_triple(self, p, o, auto_refresh=None):
'''
add triple by providing p,o, assumes s = subject
Args:
p (rdflib.term.URIRef): predicate
o (): object
auto_refresh (bool): whether or not to update object-like self.rdf.triples
Returns:
None: adds triple to self.rdf.graph
'''
self.rdf.graph.add((self.uri, p, self._handle_object(o)))
# determine if triples refreshed
self._handle_triple_refresh(auto_refresh)
def set_triple(self, p, o, auto_refresh=True):
'''
Assuming the predicate or object matches a single triple, sets the other for that triple.
Args:
p (rdflib.term.URIRef): predicate
o (): object
auto_refresh (bool): whether or not to update object-like self.rdf.triples
Returns:
None: modifies pre-existing triple in self.rdf.graph
'''
self.rdf.graph.set((self.uri, p, self._handle_object(o)))
# determine if triples refreshed
self._handle_triple_refresh(auto_refresh)
def remove_triple(self, p, o, auto_refresh=True):
'''
remove triple by supplying p,o
Args:
p (rdflib.term.URIRef): predicate
o (): object
auto_refresh (bool): whether or not to update object-like self.rdf.triples
Returns:
None: removes triple from self.rdf.graph
'''
self.rdf.graph.remove((self.uri, p, self._handle_object(o)))
# determine if triples refreshed
self._handle_triple_refresh(auto_refresh)
def parse_uri(self, uri=None):
'''
parses and cleans up possible uri inputs, return instance of rdflib.term.URIRef
Args:
uri (rdflib.term.URIRef,str): input URI
Returns:
rdflib.term.URIRef
'''
# no uri provided, assume root
if not uri:
return rdflib.term.URIRef(self.root)
# string uri provided
elif type(uri) == str:
# assume "short" uri, expand with repo root
if type(uri) == str and not uri.startswith('http'):
return rdflib.term.URIRef("%s%s" % (self.root, uri))
# else, assume full uri
else:
return rdflib.term.URIRef(uri)
# already rdflib.term.URIRef
elif type(uri) == rdflib.term.URIRef:
return uri
# unknown input
else:
raise TypeError('invalid URI input')
def uri_as_string(self):
'''
return rdflib.term.URIRef URI as string
Returns:
(str)
'''
return self.uri.toPython()
def _handle_object(self, object_input):
'''
Method to handle possible values passed for adding, removing, modifying triples.
Detects type of input and sets appropriate http://www.w3.org/2001/XMLSchema# datatype
Args:
object_input (str,int,datetime,): many possible inputs
Returns:
(rdflib.term.Literal): with appropriate datatype attribute
'''
# if object is string, convert to rdflib.term.Literal with appropriate datatype
if type(object_input) == str:
return rdflib.term.Literal(object_input, datatype=rdflib.XSD.string)
# integer
elif type(object_input) == int:
return rdflib.term.Literal(object_input, datatype=rdflib.XSD.int)
# float
elif type(object_input) == float:
return rdflib.term.Literal(object_input, datatype=rdflib.XSD.float)
# date
elif type(object_input) == datetime.datetime:
return rdflib.term.Literal(object_input, datatype=rdflib.XSD.date)
else:
return object_input
def get_resource(self, uri, resource_type=None, response_format=None):
'''
return appropriate Resource-type instance
- issue HEAD request, determine Resource type (BasicContainer, DirectContainer, IndirectContainer, or NonRDFSource (Binary))
- issue GET request and retrieve resource metadata at uri/fcr:metadata
Args:
uri (rdflib.term.URIRef,str): input URI
resource_type (): resource class e.g. BasicContainer, NonRDFSource, or extensions thereof
response_format (str): expects mimetype / Content-Type header such as 'application/rdf+xml', 'text/turtle', etc.
Returns:
Resource
'''
# handle uri
uri = self.parse_uri(uri)
# remove fcr:metadata if included, as handled below
if uri.toPython().endswith('/fcr:metadata'):
uri = rdflib.term.URIRef(uri.toPython().rstrip('/fcr:metadata'))
# HEAD request to detect resource type
head_response = self.api.http_request('HEAD', uri)
# 404, item does not exist, return False
if head_response.status_code == 404:
logger.debug('resource uri %s not found, returning False' % uri)
return False
# assume exists, parse headers for resource type and return instance
elif head_response.status_code == 200:
# if resource_type not provided
if not resource_type:
# parse LDP resource type from headers
resource_type = self.api.parse_resource_type(head_response)
logger.debug('using resource type: %s' % resource_type)
# fire GET request
get_response = self.api.http_request(
'GET',
"%s/fcr:metadata" % uri,
response_format=response_format)
# return resource
return resource_type(self,
uri,
response=get_response)
else:
raise Exception('HTTP %s, error retrieving resource uri %s' % (head_response.status_code, uri))
def get_txn(self, txn_name, txn_uri):
'''
Retrieves known transaction and adds to self.txns.
TODO:
Perhaps this should send a keep-alive request as well? Obviously still needed, and would reset timer.
Args:
txn_prefix (str, rdflib.term.URIRef): uri of the transaction. e.g. http://localhost:8080/rest/txn:123456789
txn_name (str): local, human name for transaction
Return:
(Transaction) local instance of transactions from self.txns[txn_uri]
'''
# parse uri
txn_uri = self.parse_uri(txn_uri)
# request new transaction
txn_response = self.api.http_request('GET',txn_uri, data=None, headers=None)
# if 200, transaction exists
if txn_response.status_code == 200:
logger.debug("transactoin found: %s" % txn_uri)
# init new Transaction, and pass Expires header
txn = Transaction(
self, # pass the repository
txn_name,
txn_uri,
expires = None)
# append to self
self.txns[txn_name] = txn
# return
return txn
# if 404, transaction does not exist
elif txn_response.status_code in [404, 410]:
logger.debug("transaction does not exist: %s" % txn_uri)
return False
else:
raise Exception('HTTP %s, could not retrieve transaction' % txn_response.status_code)
# Transaction