Skip to content

feat: Add endpoint for creating a new reference with or without PDF#549

Merged
gjreda merged 29 commits into
mainfrom
548-add-endpoints-for-adding-a-new-reference-from-s2-search-results
Sep 19, 2023
Merged

feat: Add endpoint for creating a new reference with or without PDF#549
gjreda merged 29 commits into
mainfrom
548-add-endpoints-for-adding-a-new-reference-from-s2-search-results

Conversation

@gjreda

@gjreda gjreda commented Sep 14, 2023

Copy link
Copy Markdown
Collaborator

fixes #548

This PR adds a new endpoint to create a reference from some metadata (e.g. from S2 search results). If the reference metadata includes a PDF URL, the PDF will be fetched and added to the project uploads.

TODO:

  • Allow for adding a Reference without a PDF
  • Default source_filename to {title}.pdf
  • Add citation key
  • Ability to parse Author in a more robust way? Rather than trying to parse on our own, we should probably just keep as full_name (which sometimes already happens with grobid) and allow the user to edit it in the UI if they'd like to change it.
  • Add publication date to S2 search results (would be good to pass this through with the metadata to the new endpoint)

@codecov

codecov Bot commented Sep 14, 2023

Copy link
Copy Markdown

Codecov Report

Merging #549 (9fe545c) into main (7985127) will increase coverage by 0.11%.
The diff coverage is 95.45%.

@@            Coverage Diff             @@
##             main     #549      +/-   ##
==========================================
+ Coverage   80.96%   81.07%   +0.11%     
==========================================
  Files         221      222       +1     
  Lines       13052    13124      +72     
  Branches     1242     1242              
==========================================
+ Hits        10567    10640      +73     
+ Misses       2470     2469       -1     
  Partials       15       15              
Files Changed Coverage Δ
python/main.py 0.00% <0.00%> (ø)
python/sidecar/search/service.py 47.05% <ø> (ø)
python/sidecar/projects/service.py 91.39% <87.50%> (-0.91%) ⬇️
python/sidecar/references/router.py 88.00% <93.75%> (+9.42%) ⬆️
python/sidecar/references/service.py 97.14% <97.14%> (ø)
python/sidecar/config.py 100.00% <100.00%> (ø)
python/sidecar/references/ingest.py 85.88% <100.00%> (-4.30%) ⬇️
python/sidecar/references/schemas.py 97.61% <100.00%> (+0.84%) ⬆️
python/sidecar/references/storage.py 96.84% <100.00%> (+10.70%) ⬆️
python/sidecar/search/schemas.py 100.00% <100.00%> (ø)
... and 2 more

... and 1 file with indirect coverage changes

📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more

Comment thread python/sidecar/references/schemas.py
Comment thread python/sidecar/references/service.py Outdated
@jvoytek

jvoytek commented Sep 18, 2023

Copy link
Copy Markdown
Collaborator

Can we add to the to-do list for this pull to return the id of the newly created reference to facilitate removal on the S2 Search dialog (only right after addition ie user made a mistake).

Comment on lines +54 to 59
reference = create_reference(
project_id, metadata=request.metadata, url=request.url
)
response = IngestResponse(project_name=project_id, references=[reference])

return response

@gjreda gjreda Sep 18, 2023

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add to the to-do list for this pull to return the id of the newly created reference to facilitate removal on the S2 Search dialog (only right after addition ie user made a mistake).

@jvoytek This should be what already happens here. The endpoint returns an IngestResponse with a references key, which in this case would only contain the newly created reference.

@cguedes

cguedes commented Sep 18, 2023

Copy link
Copy Markdown
Collaborator

@gjreda can we return the filepath in the API (and even save in the metadata), and return undefined/None if the reference don't contain a PDF file?

Currently the create that value in the client and that won't work with the new optional PDF rule.

function parsePdfIngestionResponse(references: Reference[]): ReferenceItem[] {
return references.map((reference) => ({
id: reference.id,
source_filename: reference.source_filename,
filepath: makeUploadPath(reference.source_filename),

CC @jvoytek

@gjreda gjreda changed the title 548 add endpoints for adding a new reference from s2 search results feat: Add endpoint for creating a new reference with or without PDF Sep 19, 2023
@gjreda gjreda marked this pull request as ready for review September 19, 2023 14:59
@gjreda gjreda requested review from cguedes and jvoytek September 19, 2023 14:59
@jvoytek

jvoytek commented Sep 19, 2023

Copy link
Copy Markdown
Collaborator

I am so very pleased, references without a PDF work like magic this morning. A few things:

  • If you haven't uploaded any PDF's and attempt to add using S2 first:
    File "/Users/jvoytek/refstudio/python/sidecar/references/storage.py", line 49, in load with open(self.filepath, "r") as f: ^^^^^^^^^^^^^^^^^^^^^^^^ FileNotFoundError: [Errno 2] No such file or directory: '/tmp/web-storage-url/user1/f82d3af8-48d5-478a-9542-e8603575f002/.storage/references.json'

  • For S2 results with (what I assume is) a redirect for the openAccessPdf like this: http://www.thelancet.com/article/S1474442214703205/pdf pypdf chokes like this:
    File "/Users/jvoytek/Library/Caches/pypoetry/virtualenvs/refstudio-hQ57T0PE-py3.11/lib/python3.11/site-packages/pypdf/_utils.py", line 266, in read_previous_line raise PdfStreamError(STREAM_TRUNCATED_PREMATURELY)

  • For all references (even ones added in through upload) when you try to open the PDF:
    RuntimeError: File at path /tmp/web-storage-url/user1/9a8571db-a2a0-4a93-94a8-a6c29c6287c9/tmp/web-storage-url/user1/9a8571db-a2a0-4a93-94a8-a6c29c6287c9/uploads/Abbott-Neuron2008.pdf does not exist.

@jvoytek

jvoytek commented Sep 19, 2023

Copy link
Copy Markdown
Collaborator

Any idea why this payload wouldn't save the published_date:
{
"type":"metadata",
"metadata":{
"source_filename":"",
"citation_key":"",
"doi":"",
"title":"Longitudinal changes in aperiodic and periodic activity in electrophysiological recordings in the first seven months of life",
"abstract":"",
"contents":"",
"published_date":"2020-07-18",
"authors":[
{"full_name":"N. Schaworonkow"},
{"full_name":"Bradley Voytek"}
]
}
}

@gjreda

gjreda commented Sep 19, 2023

Copy link
Copy Markdown
Collaborator Author

Any idea why this payload wouldn't save the published_date

I added it to search results, but forgot to add it in when creating the Reference.

If you haven't uploaded any PDF's and attempt to add using S2 first

Should be fixed now. This feature breaks a core assumption we've had thus far -- that ingests are happening via the uploads ingestion call. With this feature, it's now possible that .storage might not exist since it's forking a different path than has been required before.

For S2 results with (what I assume is) a redirect for the openAccessPdf

Need to look into this one a little more. This url returns a 403 status code, so we're unable to fetch it. I'll improve the handling of this.

For all references (even ones added in through upload) when you try to open the PDF

Still debugging this one. I'm able to view the PDF in some cases, but there are some edges where it still doesn't work. There might be some inconsistencies in how some frontend views send the filepath back. This should work now. The inconsistencies I was seeing where due to some filepaths that had already been written locally into storage.

Comment thread python/sidecar/shared.py

@cguedes cguedes left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved with a note about the downloaded file name.

Comment thread python/sidecar/references/service.py Outdated
raise HTTPError(f"Unable to fetch {url} (status code: {response.status_code})")

if not metadata.source_filename:
metadata.source_filename = f"{metadata.title[:200]}.pdf"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is metadata.title[:200] a way of truncating the title to a max of 200 characters? If so, seems too much. The filename should be pretty opaque for the client code (and server) so I think that would be safer to just use an ID (maybe of the reference) instead of the title, that might also include invalid characters for a url.

@gjreda gjreda Sep 19, 2023

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can see the point that 200 might be too long, so I'll shorten this to 75 for now.

I had the thought of showing the ID, but since we show the filename in the file browser on the left side, I thought seeing a random UUID would be a confusing user experience.

We also can't rely on the filename from the URL, since it's often a random ID or even sometimes just pdf.

IMO it'd be best if we asked a user to provide a filename when adding the reference from search results. I liken this to when you're adding a file to VS Code or downloading a PDF to your local -- you need to provide a name for it. I think a similar principle applies when adding a new reference from a URL. Interaction with the reference in the left pane is going to require knowing its name, so I think the user should provide it.

@gjreda gjreda merged commit 77ef904 into main Sep 19, 2023
@gjreda gjreda deleted the 548-add-endpoints-for-adding-a-new-reference-from-s2-search-results branch September 19, 2023 20:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add endpoint(s) for adding a new reference from S2 search results

3 participants