ResumeParser.pro

Parse a Resume to JSON in Python

No spaCy, no models, no GPU: the extraction happens server-side. Your Python's whole job is uploading a file and reading JSON. Two ways to do it below; both fit in one screen.

To parse a resume in Python, POST the file to the SharpAPI parse_resume endpoint and poll the returned status URL until the job succeeds. The response carries 50+ structured fields. Total code: under 30 lines with requests, under 10 with the official SDK.

Option 1 — the official SDK

Install once, and the polling loop disappears:

pip install sharpapi
from sharpapi import SharpApiService

sharp_api = SharpApiService(api_key='YOUR_SHARP_API_KEY')

status_url = sharp_api.parse_resume(
    file_path='resumes/candidate.pdf',
    language='English',  # optional
)

parsed_resume = sharp_api.fetch_results(status_url)
print(parsed_resume.get_result_json())

Option 2 — plain requests, full control

If you would rather see the whole HTTP conversation — or you are wiring this into an existing client — the raw flow is two calls:

parse_resume.py — requests only
import time
import requests

API_KEY = 'YOUR_SHARP_API_KEY'
HEADERS = {'Authorization': f'Bearer {API_KEY}'}

# 1. Submit the file — returns 202 + a status URL immediately
with open('resumes/candidate.pdf', 'rb') as fh:
    submit = requests.post(
        'https://sharpapi.com/api/v1/hr/parse_resume',
        headers=HEADERS,
        files={'file': ('candidate.pdf', fh, 'application/pdf')},
        data={'language': 'English'},
    )
submit.raise_for_status()
status_url = submit.json()['status_url']

# 2. Poll until the job finishes (typically a few seconds)
while True:
    job = requests.get(status_url, headers=HEADERS).json()
    if job['data']['attributes']['status'] in ('success', 'failed'):
        break
    time.sleep(2)

result = job['data']['attributes']['result']
print(result['candidate_name'])
for position in result['positions']:
    print(f"- {position['position_name']} @ {position['company_name']}")

What comes back

result is the full deterministic schema — candidate profile, positions[] with per-role skills, education_qualifications[] with normalized degrees, plus derived signals like years_of_experience. Explore the complete payload before you write your models — one Pydantic class covers every response.

Production notes

  • Skip polling at scale. Pass a webhook URL with the submission and receive results push-style — essential once you parse in bulk.
  • Handle the failed status. Corrupt files and password-protected PDFs fail cleanly; log the job id and move on.
  • Photos work too. JPG/PNG/TIFF go through the same call — OCR is server-side, so the code above already handles scanned resumes.

Questions, answered

Is there an official Python SDK for resume parsing?

Yes — pip install sharpapi gives you SharpApiService with a parse_resume(file_path, language) method and a fetch_results(status_url) helper that handles the polling loop for you.

Do I need any ML or NLP libraries installed?

No. The extraction runs server-side; your Python code only uploads a file and reads JSON. The requests library — or the SDK — is the entire dependency footprint.

How do I handle the asynchronous flow in Python?

The POST returns a status URL immediately. Poll it every second or two until status is success, or skip polling entirely by passing a webhook URL and receiving the result push-style.