Skip to content

Commit

Permalink
refactor: use renderingToken instead of secureId (#11)
Browse files Browse the repository at this point in the history
* refactor: use renderingToken instead of secureId

* Update example payload image

* change variable names

* fix ruff errors

* Update rendering token

---------

Co-authored-by: Felipe Allegretti <[email protected]>
  • Loading branch information
miorelli and felipeall authored Mar 4, 2024
1 parent b263d0b commit fcd371f
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 31 deletions.
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
# Resume.io to PDF

Download your resume from [resume.io](https://resume.io) as a PDF file. Open the application, enter your resume
`secureId` and click the download button. It will automatically download your resume as image files, merge and
`renderingToken` and click the download button. It will automatically download your resume as image files, merge and
convert them to a PDF file, and run OCR to extract the text and make it searchable.

<div align="center"><a href="https://resumeio-to-pdf.fly.dev/"><img src="https://github.com/felipeall/resumeio-to-pdf/assets/20917430/a0479dc5-ceb8-4532-826d-eae98649a089" width="700" /></a></div>


#### How to find your secureId
#### How to find your renderingToken

Go to https://resume.io/api/app/resumes

You will see a list of your resumes. Find the one you want to download and get the `secureId` from
You will see a list of your resumes. Find the one you want to download and get the `renderingToken` from
the payload. Example:

![image](https://github.com/felipeall/resumeio-to-pdf/assets/20917430/54fb20b3-2dc1-45ca-860c-8eadac779799)
<img src="https://github.com/felipeall/resumeio-to-pdf/assets/20917430/99cdc690-9c38-4f5f-af4e-2c75e9c9575e" width="500" />



### Usage
Expand Down
29 changes: 15 additions & 14 deletions app/api/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@


@api_router.get("/download", response_class=HTMLResponse)
def download_resume(resume: str, image_size: int = 3000, extension: str = "jpg"):
def download_resume(rendering_token: str, image_size: int = 3000, extension: str = "jpg"):
"""
Download a resume from resume.io and return it as a PDF.
Parameters
----------
resume : str
ID or URL of the resume to download.
rendering_token : str
Rendering Token of the resume to download.
image_size : int, optional
Size of the images to download, by default 3000.
extension : str, optional
Expand All @@ -29,11 +29,12 @@ def download_resume(resume: str, image_size: int = 3000, extension: str = "jpg")
fastapi.responses.Response
A PDF representation of the resume with appropriate headers for inline display.
"""
resume_id = parse_resume_id(resume)
resumeio = ResumeioDownloader(resume_id=resume_id, image_size=image_size, extension=extension)
rendering_token = parse_rendering_token(rendering_token)
resumeio = ResumeioDownloader(rendering_token=rendering_token, image_size=image_size, extension=extension)
buffer = resumeio.generate_pdf()
return Response(
buffer, headers={"Content-Disposition": f'inline; filename="{resume_id}.pdf"'}, media_type="application/pdf",
buffer,
headers={"Content-Disposition": f'inline; filename="{rendering_token}.pdf"'}, media_type="application/pdf",
)


Expand All @@ -55,23 +56,23 @@ def index(request: Request):
return templates.TemplateResponse("index.html", {"request": request})


def parse_resume_id(resume_input: str) -> str:
def parse_rendering_token(rendering_token: str) -> str:
"""
Parse a resume.io ID or URL.
Parse a resume.io Rendering Token.
Parameters
----------
resume_input : str
ID or URL of the resume to parse.
rendering_token : str
Rendering Token of the resume to parse.
Returns
-------
str
The resume ID.
The resume's rendering token.
"""
match = re.search(r"^(.+resume\.io/r/)?(?P<id>[a-zA-Z0-9]{9})$", resume_input)
match = re.search(r"^(?P<rendering_token>[a-zA-Z0-9]{24})$", rendering_token)
if not match:
raise HTTPException(status_code=400, detail=f"Invalid resumeio.io ID or URL: {resume_input}")
raise HTTPException(status_code=400, detail=f"Invalid rendering token: {rendering_token}")

return match.groupdict().get("id")
return match.groupdict().get("rendering_token")
21 changes: 13 additions & 8 deletions app/services/resumeio.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,19 @@ class ResumeioDownloader:
Parameters
----------
resume_id : str
ID or URL of the resume to download.
rendering_token : str
Rendering Token of the resume to download.
extension : str, optional
Image extension to download, by default "jpg".
image_size : int, optional
Size of the images to download, by default 3000.
"""
resume_id: str
rendering_token: str
extension: str = "jpg"
image_size: int = 3000
METADATA_URL: str = "https://ssr.resume.tools/meta/ssid-{resume_id}?cache={cache_date}"
METADATA_URL: str = "https://ssr.resume.tools/meta/{rendering_token}?cache={cache_date}"
IMAGES_URL: str = (
"https://ssr.resume.tools/to-image/ssid-{resume_id}-{page_id}.{extension}?cache={cache_date}&size={image_size}"
"https://ssr.resume.tools/to-image/{rendering_token}-{page_id}.{extension}?cache={cache_date}&size={image_size}"
)

def __post_init__(self) -> None:
Expand Down Expand Up @@ -71,7 +71,9 @@ def generate_pdf(self) -> bytes:

def __get_resume_metadata(self) -> None:
"""Download the metadata for the resume."""
response = requests.get(self.METADATA_URL.format(resume_id=self.resume_id, cache_date=self.cache_date))
response = requests.get(
self.METADATA_URL.format(rendering_token=self.rendering_token, cache_date=self.cache_date),
)
self.__raise_for_status(response)
content = json.loads(response.text)
self.metadata = content.get("pages")
Expand All @@ -87,7 +89,7 @@ def __download_images(self) -> list[io.BytesIO]:
images = []
for page_id in range(1, 1 + len(self.metadata)):
image_url = self.IMAGES_URL.format(
resume_id=self.resume_id,
rendering_token=self.rendering_token,
page_id=page_id,
extension=self.extension,
cache_date=self.cache_date,
Expand Down Expand Up @@ -129,4 +131,7 @@ def __raise_for_status(self, response) -> None:
If the response status code is not 200.
"""
if response.status_code != 200:
raise HTTPException(status_code=response.status_code, detail=f"Unable to download resume {self.resume_id}")
raise HTTPException(
status_code=response.status_code,
detail=f"Unable to download resume (rendering token: {self.rendering_token})",
)
8 changes: 3 additions & 5 deletions templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,10 @@
<div class="container">
<h1 class="title">Resume.io to PDF</h1>
<iframe class="github-button" src="https://ghbtns.com/github-btn.html?user=felipeall&repo=resumeio-to-pdf&type=star&count=true&size=large" frameborder="0" scrolling="0" width="170" height="30" title="GitHub"></iframe>
<form method="get" class="resume_form" action='/download{{ resume }}'>
<input type="text" class="resume" name="resume" placeholder="Enter your resume ID or URL to download"
aria-label="Id" required="true">
<form method="get" class="resume_form" action='/download{{ rendering_token }}'>
<input type="text" class="resume" name="rendering_token" placeholder="Enter your resume Rendering Token to download" aria-label="Id" required="true" minlength="24" maxlength="24">
<button id="submit-btn" class="btn" type="submit"><span id="submit-text">Download</span>
<svg id="loader" width="23" height="23" stroke="#fff" viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg">
<svg id="loader" width="23" height="23" stroke="#fff" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<style>.spinner_V8m1 {
transform-origin: center;
animation: spinner_zKoa 2s linear infinite
Expand Down

0 comments on commit fcd371f

Please sign in to comment.