Add routes to fetch relationships
* Add routes to fetch relationships for a given paper. * Add backrefs in relationships to be able to get the reversed relationship. * Update some doc.
This commit is contained in:
parent
48a4b0d8b0
commit
e7332e3b91
@ -3,7 +3,7 @@ Metadata for arXiv
|
||||
|
||||
The goal of this repository is to provide a minimal API to put metadata on arXiv papers.
|
||||
|
||||
TODO: Better description.
|
||||
TODO: Better description + API description.
|
||||
|
||||
|
||||
## Installation
|
||||
|
29
database.py
29
database.py
@ -30,17 +30,29 @@ class Association(Base):
|
||||
relationship_id = Column(Integer,
|
||||
ForeignKey("relationships.id",
|
||||
ondelete="CASCADE"))
|
||||
right_paper = sqlalchemy_relationship("Paper", foreign_keys=right_id)
|
||||
right_paper = sqlalchemy_relationship("Paper",
|
||||
foreign_keys=right_id,
|
||||
back_populates="related_by")
|
||||
relationship = sqlalchemy_relationship("Relationship")
|
||||
|
||||
left_paper = sqlalchemy_relationship("Paper",
|
||||
foreign_keys=left_id,
|
||||
back_populates="related_to")
|
||||
|
||||
|
||||
class Paper(Base):
|
||||
__tablename__ = "papers"
|
||||
id = Column(Integer, primary_key=True)
|
||||
doi = Column(String(), nullable=True, unique=True)
|
||||
arxiv_id = Column(String(25), nullable=True, unique=True)
|
||||
related = sqlalchemy_relationship("Association",
|
||||
foreign_keys="Association.left_id")
|
||||
# related_to are papers related to this paper (this_paper R …)
|
||||
related_to = sqlalchemy_relationship("Association",
|
||||
foreign_keys="Association.left_id",
|
||||
back_populates="left_paper")
|
||||
# related_by are papers referenced by this paper (… R this_paper)
|
||||
related_by = sqlalchemy_relationship("Association",
|
||||
foreign_keys="Association.right_id",
|
||||
back_populates="right_paper")
|
||||
|
||||
def __repr__(self):
|
||||
return "<Paper(id='%d', doi='%s', arxiv_id='%s')>" % (
|
||||
@ -53,6 +65,7 @@ class Paper(Base):
|
||||
"""
|
||||
Dict to dump for the JSON API.
|
||||
"""
|
||||
relationships = [a.relationship.name for a in self.related_to]
|
||||
return {
|
||||
"types": self.__tablename__,
|
||||
"id": self.id,
|
||||
@ -64,7 +77,15 @@ class Paper(Base):
|
||||
"self": "/papers/%d" % (self.id,)
|
||||
},
|
||||
"relationships": {
|
||||
# TODO
|
||||
k: {
|
||||
"links": {
|
||||
"related": (
|
||||
"/papers/%d/relationships/%s?reverse={reverse}" %
|
||||
(self.id, k)
|
||||
)
|
||||
}
|
||||
}
|
||||
for k in relationships
|
||||
}
|
||||
}
|
||||
|
||||
|
4
main.py
4
main.py
@ -45,8 +45,8 @@ app.get("/papers", callback=routes.get.fetch_papers)
|
||||
app.get("/papers/<id:int>", callback=routes.get.fetch_by_id)
|
||||
app.get("/papers/<id:int>/relationships/<name>",
|
||||
callback=routes.get.fetch_relationship)
|
||||
|
||||
# TODO: Fetch relationships
|
||||
app.get("/papers/<id:int>/<name>",
|
||||
callback=routes.get.fetch_relationship)
|
||||
|
||||
|
||||
app.post("/papers", callback=routes.post.create_paper)
|
||||
|
@ -36,7 +36,12 @@ def fetch_papers(db):
|
||||
"self": "/papers/1"
|
||||
},
|
||||
"relationships": {
|
||||
TODO
|
||||
"cite": {
|
||||
"links": {
|
||||
"related": "/papers/1/relationships/cite"
|
||||
}
|
||||
},
|
||||
…
|
||||
}
|
||||
}
|
||||
]
|
||||
@ -62,7 +67,7 @@ def fetch_by_id(id, db):
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
GET /id/<id>
|
||||
GET /papers/1
|
||||
Accept: application/vnd.api+json
|
||||
|
||||
|
||||
@ -70,24 +75,27 @@ def fetch_by_id(id, db):
|
||||
|
||||
{
|
||||
"data": {
|
||||
{
|
||||
"type": "papers",
|
||||
"id": 1,
|
||||
"attributes": {
|
||||
"doi": "10.1126/science.1252319",
|
||||
"arxiv_id": "1401.2910"
|
||||
"type": "papers",
|
||||
"id": 1,
|
||||
"attributes": {
|
||||
"doi": "10.1126/science.1252319",
|
||||
"arxiv_id": "1401.2910"
|
||||
},
|
||||
"links": {
|
||||
"self": "/papers/1"
|
||||
},
|
||||
"relationships": {
|
||||
"cite": {
|
||||
"links": {
|
||||
"related": "/papers/1/relationships/cite"
|
||||
}
|
||||
},
|
||||
"links": {
|
||||
"self": "/papers/1"
|
||||
},
|
||||
"relationships": {
|
||||
TODO
|
||||
}
|
||||
…
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:param id: The id of the requested article.
|
||||
:param id: The id of the requested paper.
|
||||
:param db: A database session, injected by the ``Bottle`` plugin.
|
||||
:returns: An ``HTTPResponse``.
|
||||
"""
|
||||
@ -101,6 +109,55 @@ def fetch_by_id(id, db):
|
||||
|
||||
def fetch_relationship(id, name, db):
|
||||
"""
|
||||
TODO
|
||||
Fetch relationships of the given type associated with the given paper.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
GET /papers/1/relationships/cite
|
||||
Accept: application/vnd.api+json
|
||||
|
||||
|
||||
.. code-block:: json
|
||||
|
||||
{
|
||||
"links": {
|
||||
"self": "/papers/1/relationships/cite",
|
||||
"related": "/papers/1/cite"
|
||||
},
|
||||
"data": [
|
||||
{
|
||||
"type": "papers",
|
||||
"id": 2,
|
||||
},
|
||||
…
|
||||
]
|
||||
}
|
||||
|
||||
:param id: The id of the requested paper.
|
||||
:param name: The name of the requested relationship for this paper.
|
||||
:param db: A database session, injected by the ``Bottle`` plugin.
|
||||
:returns: An ``HTTPResponse``.
|
||||
"""
|
||||
pass
|
||||
reversed = (
|
||||
"reverse" in bottle.request.params and
|
||||
bottle.request.params["reverse"] != 0
|
||||
)
|
||||
resource = db.query(database.Paper).filter_by(id=id).first()
|
||||
if resource:
|
||||
response = {
|
||||
"links": {
|
||||
"self": "/papers/%d/relationships/%s" % (id, name),
|
||||
"related": "/papers/%d/%s" % (id, name),
|
||||
},
|
||||
"data": [
|
||||
]
|
||||
}
|
||||
if reversed:
|
||||
relationships = resource.related_by
|
||||
else:
|
||||
relationships = resource.related_to
|
||||
for r in relationships:
|
||||
if r.relationship.name == name:
|
||||
response["data"].append({"type": name, "id": r.right_id})
|
||||
return tools.APIResponse(tools.pretty_json(response))
|
||||
return bottle.HTTPError(404, "Not found")
|
||||
|
@ -193,7 +193,7 @@ def update_relationship_backend(left_id, right_id, name, db):
|
||||
# Update the relationship
|
||||
a = database.Association(relationship_id=relationship.id)
|
||||
a.right_paper = right_paper
|
||||
left_paper.related.append(a)
|
||||
left_paper.related_to.append(a)
|
||||
try:
|
||||
db.add(a)
|
||||
db.add(left_paper)
|
||||
|
Loading…
Reference in New Issue
Block a user