This repository is a small project for a job interview.
See ASSIGNMENT.md for the assignment.
PLAN.md contains an outline written up before getting started.
PROMPT.md is a prompt history of working with Claude Code on this project.
Install uv if you don't have it: https://docs.astral.sh/uv/getting-started/installation/
Then install dependencies:
uv syncThe project is using a sqlite database for simplicity during development. To initialize the db and run migrations:
uv run python manage.py migrateTo run tests with Django's test runner:
uv run python manage.py testCreate a .env file at the project root with your NASA API key:
APOD_API_KEY=your_key_here
Note: Requests to the NASA API will default to using DEMO_KEY as the API key.
However it is recommended that you get a free API key at https://api.nasa.gov/
The project uses a Django management command to fetch APOD records. It supports fetching single dates as well as date ranges.
Fetch a single date:
uv run --env-file=.env python manage.py fetch_apod --date 2026-01-04Fetch a date range:
uv run --env-file=.env python manage.py fetch_apod --start-date 2026-03-01 --end-date 2026-03-10Note: Future dates will raise an error from the NASA API.
By default, the management command will try to fetch and save three related Wikipedia articles.
Skip Wikipedia enrichment:
uv run --env-file=.env python manage.py fetch_apod --date 2026-03-17 --no-supplemental-infouv run python manage.py runserverVisit the following urls in your browser to make use of DRF's browsable API.
http://localhost:8000/api/apod-info/
Single entry:
http://localhost:8000/api/apod-info/1/
Filter by date:
http://localhost:8000/api/apod-info/?date=2026-01-04
I went down a rabbit hole writing the APODClient. It started with a desire to add support for date ranges. I noticed that fetching a month's worth of data from the NASA API was noticeably slower, so I thought I would break up large date ranges into smaller requests. This was probably more complexity than I should have taken on based on the intended time constraints and scope of the requirements.
I also ran into unexpected challenges using the APODInfoSerializer for object creation in the client in cases where the record already existed. While my solution works, it feels overly complex and probably not the most idiomatic solution. With more time I would look for another way to handle duplicate objects.
The quality of related Wikipedia articles leaves lots of room for improvement. Sometimes no articles are found and other times the articles are obviously unrelated. With more time, I would work on improving the search process. Using an LLM to extract relevant keywords seems like an obvious path to explore.
In retrospect, generating some supplemental data from an LLM would probably have returned more interesting data with less effort.
It would have liked to add some kind of scheduled task to fetch APODInfo. It could run at server startup and on a scheduled basis (e.g. daily). Celery beat came to mind, but again, this is probably overkill for the scope of this project.
Given more time, I would have preferred to use docker. I haven't setup docker with uv previously, and I was concerned it would take too much time. Docker would have made it trivial to use a db like Postgresql and use Celery if desired.
The clients could be make more robust with more error handling and retry functionality for transient errors such as rate limits. A quick but big improvement would be to pass the NASA date out of range error message through to the CommandError.
I considered adding some validation to ensure the date is not in the future, but I wasn't sure if the picture of the day is updated at the same time every day, nor did I know what time it's updated. I opted not to add this validation so I wouldn't ever prevent a user from fetching the newest picture of the day due to over eager validation.
I always like adding a Django admin, and it would be convenient for users to have an admin action to trigger the management command to fetch APOD data. It would require an intermediate form page to enter date info, but would be relatively simple.