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.
|
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
|
## Installation
|
||||||
|
29
database.py
29
database.py
@ -30,17 +30,29 @@ class Association(Base):
|
|||||||
relationship_id = Column(Integer,
|
relationship_id = Column(Integer,
|
||||||
ForeignKey("relationships.id",
|
ForeignKey("relationships.id",
|
||||||
ondelete="CASCADE"))
|
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")
|
relationship = sqlalchemy_relationship("Relationship")
|
||||||
|
|
||||||
|
left_paper = sqlalchemy_relationship("Paper",
|
||||||
|
foreign_keys=left_id,
|
||||||
|
back_populates="related_to")
|
||||||
|
|
||||||
|
|
||||||
class Paper(Base):
|
class Paper(Base):
|
||||||
__tablename__ = "papers"
|
__tablename__ = "papers"
|
||||||
id = Column(Integer, primary_key=True)
|
id = Column(Integer, primary_key=True)
|
||||||
doi = Column(String(), nullable=True, unique=True)
|
doi = Column(String(), nullable=True, unique=True)
|
||||||
arxiv_id = Column(String(25), nullable=True, unique=True)
|
arxiv_id = Column(String(25), nullable=True, unique=True)
|
||||||
related = sqlalchemy_relationship("Association",
|
# related_to are papers related to this paper (this_paper R …)
|
||||||
foreign_keys="Association.left_id")
|
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):
|
def __repr__(self):
|
||||||
return "<Paper(id='%d', doi='%s', arxiv_id='%s')>" % (
|
return "<Paper(id='%d', doi='%s', arxiv_id='%s')>" % (
|
||||||
@ -53,6 +65,7 @@ class Paper(Base):
|
|||||||
"""
|
"""
|
||||||
Dict to dump for the JSON API.
|
Dict to dump for the JSON API.
|
||||||
"""
|
"""
|
||||||
|
relationships = [a.relationship.name for a in self.related_to]
|
||||||
return {
|
return {
|
||||||
"types": self.__tablename__,
|
"types": self.__tablename__,
|
||||||
"id": self.id,
|
"id": self.id,
|
||||||
@ -64,7 +77,15 @@ class Paper(Base):
|
|||||||
"self": "/papers/%d" % (self.id,)
|
"self": "/papers/%d" % (self.id,)
|
||||||
},
|
},
|
||||||
"relationships": {
|
"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>", callback=routes.get.fetch_by_id)
|
||||||
app.get("/papers/<id:int>/relationships/<name>",
|
app.get("/papers/<id:int>/relationships/<name>",
|
||||||
callback=routes.get.fetch_relationship)
|
callback=routes.get.fetch_relationship)
|
||||||
|
app.get("/papers/<id:int>/<name>",
|
||||||
# TODO: Fetch relationships
|
callback=routes.get.fetch_relationship)
|
||||||
|
|
||||||
|
|
||||||
app.post("/papers", callback=routes.post.create_paper)
|
app.post("/papers", callback=routes.post.create_paper)
|
||||||
|
@ -36,7 +36,12 @@ def fetch_papers(db):
|
|||||||
"self": "/papers/1"
|
"self": "/papers/1"
|
||||||
},
|
},
|
||||||
"relationships": {
|
"relationships": {
|
||||||
TODO
|
"cite": {
|
||||||
|
"links": {
|
||||||
|
"related": "/papers/1/relationships/cite"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
…
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -62,7 +67,7 @@ def fetch_by_id(id, db):
|
|||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
GET /id/<id>
|
GET /papers/1
|
||||||
Accept: application/vnd.api+json
|
Accept: application/vnd.api+json
|
||||||
|
|
||||||
|
|
||||||
@ -70,24 +75,27 @@ def fetch_by_id(id, db):
|
|||||||
|
|
||||||
{
|
{
|
||||||
"data": {
|
"data": {
|
||||||
{
|
"type": "papers",
|
||||||
"type": "papers",
|
"id": 1,
|
||||||
"id": 1,
|
"attributes": {
|
||||||
"attributes": {
|
"doi": "10.1126/science.1252319",
|
||||||
"doi": "10.1126/science.1252319",
|
"arxiv_id": "1401.2910"
|
||||||
"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.
|
:param db: A database session, injected by the ``Bottle`` plugin.
|
||||||
:returns: An ``HTTPResponse``.
|
:returns: An ``HTTPResponse``.
|
||||||
"""
|
"""
|
||||||
@ -101,6 +109,55 @@ def fetch_by_id(id, db):
|
|||||||
|
|
||||||
def fetch_relationship(id, name, 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
|
# Update the relationship
|
||||||
a = database.Association(relationship_id=relationship.id)
|
a = database.Association(relationship_id=relationship.id)
|
||||||
a.right_paper = right_paper
|
a.right_paper = right_paper
|
||||||
left_paper.related.append(a)
|
left_paper.related_to.append(a)
|
||||||
try:
|
try:
|
||||||
db.add(a)
|
db.add(a)
|
||||||
db.add(left_paper)
|
db.add(left_paper)
|
||||||
|
Loading…
Reference in New Issue
Block a user