Back to use cases

    Use case / AI SEARCH / Python 3 / Published

    Find scholarships with deadlines and source links

    Build a scholarship finder in Python that searches the web for a field, level and year, then lists source-stated amounts and deadlines with a source link.

    Field, level and year flowing through Desearch search into a sorted scholarship deadline table

    This scholarship finder searches the web for scholarship pages for a field of study, a level and a year. It lists source-stated amounts and dates, sorted by the candidate deadline, and every row has a source URL. It is a Python CLI with no extra packages. This page shows a stored sample; there is no hosted demo.

    The problem

    Scholarship information is spread over university pages, foundations and large list sites. Deadlines are written in many formats, some pages are out of date and list pages mix many awards. Collecting a shortlist by hand means opening dozens of pages and copying dates. You need one table sorted by deadline, with the source of every row and a note on how sure each date is.

    What the app does

    • Searches the web for a field, level and year with two Desearch search routes.
    • Finds explicit dates and nearby dollar amounts in each result.
    • Marks dates near words such as deadline, due or apply by as likely deadlines, and flags the others.
    • Opens up to 3 candidate pages to confirm the date on the page itself.
    • Writes a sorted table to stdout, Markdown and CSV, plus a raw request log.

    Deadlines and amounts are as stated by the source page. A matching date does not establish eligibility or official status. Check the official page before applying.

    How it works

    1. Search. POST /search sends the query {field} {level} scholarships {year} application deadline with highlights. GET /web sends a shorter deadline query. Use --no-web to skip the second search.
    2. Find dates. The parser accepts English month names, ISO dates and US numeric dates with a four-digit year. Past dates and dates more than two calendar years ahead are dropped. No year is guessed.
    3. Read context. A deadline keyword within 80 characters before a date marks a likely deadline. A dollar amount in the same nearby sentence becomes the amount. Otherwise the amount is "not stated".
    4. Verify. Up to 3 candidate pages are read with GET /web/extract as plain text. A page that needs JavaScript is retried once with js=true. Each row becomes "confirmed on page", "date not found on page", "extract failed" or stays "snippet only".
    5. Sort and export. Duplicates merge by normalized URL, date and name. Rows are sorted by deadline, and list sites are detected and flagged.

    The code

    This verbatim excerpt from scholarship_finder.py finds explicit dates in text. It relies on DATE_RE, MONTHS, re and dt defined in the full file.

    PYTHON
    def dates(text):
        """Return (date, start, end) for explicit, valid four-digit-year dates."""
        found = []
        for m in DATE_RE.finditer(text):
            parts = re.findall(r'[A-Za-z]+|\d+', m.group())
            try:
                if m.lastgroup == 'md': month, day, year = MONTHS[parts[0].lower()], int(parts[1]), int(parts[2])
                elif m.lastgroup == 'dm': day, month, year = int(parts[0]), MONTHS[parts[1].lower()], int(parts[2])
                elif m.lastgroup == 'iso': year, month, day = map(int, parts)
                else: month, day, year = map(int, parts)
                found.append((dt.date(year, month, day), m.start(), m.end()))
            except (ValueError, KeyError):
                pass
        return found

    View the code

    Endpoints

    • POST /search
    • GET /web
    • GET /web/extract

    Example output

    From sample-output.md in the source folder, a run on 2026-10-30 for nursing, undergraduate, 2027. These are the first three of ten rows:

    | Name | Amount | Deadline | Confidence | Source URL | Endpoint | Flags |
    | --- | --- | --- | --- | --- | --- | --- |
    | Healthcare Scholarships: Invitation to Apply by Nov 13 \| Health Professions Advising | not stated | 2026-11-13 | confirmed on page | [source](<https://hpa.princeton.edu/news/healthcare-scholarships>) | search |  |
    | 2027 Undergraduate Scholarship Application  \| FNSNA.ORG | not stated | 2027-01-11 | extract failed | [source](<https://www.fnsna.org/2027-undergraduate-scholarship-application>) | search | no publish date |
    | Top 50 Nursing Scholarships in 2026 | $8,000 | 2027-02-02 | date not found on page | [source](<https://scholaroo.com/nursing-scholarships/>) | web | no publish date |

    The confidence column shows how far each date was checked. Dates and amounts were copied from the sources on that date and may have changed since.

    Run it yourself

    Get the Python examples and open the scholarship finder folder. Use Python 3.10 or newer; no packages are needed. Create an API key in the console. Save it alone in ~/.desearch_api_key, or set DESEARCH_API_KEY.

    BASH
    git clone https://github.com/Desearch-ai/desearch-py-examples
    cd desearch-py-examples/scholarship-finder

    These commands are copied from the source README. The dry run prints the planned calls without a key or network.

    SH
    python3 scholarship_finder.py --field nursing --level undergraduate --year 2027
    python3 scholarship_finder.py --field nursing --level undergraduate --year 2027 --dry-run
    python3 scholarship_finder.py --field nursing --level undergraduate --year 2027 --verify 0 --no-web --out ./results

    Use --hide-unclear to drop rows without a clear deadline, --limit to show more rows and --from-raw to rebuild results from a saved run with no new calls.

    What it costs

    The 2026-10-30 sample run made 6 calls for $0.00700 in total: $0.005 for /search with 10 results, $0.001 for /web and $0.0005 for each of two plain text extractions. One extraction that needed JavaScript and one JavaScript retry that failed were not charged. A successful JavaScript extraction probe cost $0.0015 and took 17.6 seconds on the same day.

    These are dated measurements, not current price quotes. Use --no-js to skip the JavaScript retry, and check pricing before a larger run.

    Ideas to extend it

    • Run the finder for several fields and merge the CSV files into one shortlist.
    • Rerun it each month and keep only rows whose deadline has not passed.
    • Add a column for eligibility notes copied from each confirmed page.
    • Send a reminder a week before each confirmed deadline.

    Use with AI agents

    Point an MCP client at the hosted Desearch server. Replace the placeholder with a key from the console. Do not commit the key.

    JSON
    {
      "mcpServers": {
        "desearch": {
          "url": "https://mcp.desearch.ai/mcp",
          "headers": {
            "Authorization": "Bearer <key>"
          }
        }
      }
    }

    Prompt you can paste for this example:

    Build a Python CLI scholarship finder using Desearch. Take a field, level and year. Call POST /search with highlights and GET /web with a scholarship deadline query. Parse explicit dates with a four-digit year and dollar amounts near each date, and mark dates with a nearby deadline keyword as likely deadlines. Drop past dates and dates more than two years ahead. Verify up to 3 candidate pages with GET /web/extract?format=text, and retry once with js=true when the response says js_required. Sort by deadline and print a table with name, amount, deadline, confidence, source URL and flags. Record cost per call. Always tell the user to check the official page before applying.

    Build your own example.

    Give your agents access to web and social search. Get an API key to start building, or talk to us about your integration.

    Read docs