Open-source project
wimglenn/advent-of-code-data avatar
wimglenn/advent-of-code-data

advent-of-code-data: puzzle inputs from a single Python import

Get your Advent of Code data with a single import statement

666 stars57 forksPythonMIT

At a glance

What is it?
The aocd package fetches Advent of Code puzzle inputs, caches them locally, and can submit answers on your behalf, with a command line for saving raw input files. Its session token handling, including a browser cookie scraper, is the part to read carefully before you point it at your account, and the package documents the rate limit you will hit if you guess wrong.
Who is it for?
Adopt advent-of-code-data if you solve Advent of Code in Python and want the input fetching, caching and submission plumbing handled for you, especially if you want your own solution entry point to be run by the package. Do not adopt it in a shared or automated context, since it holds your session token, submits answers on your behalf and can rate limit your account.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 83 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

One import, or one function call

The package is called advent-of-code-data on PyPI and imported as aocd. The pitch is a single import statement:

``` python from aocd import data

code

For anyone who finds that too magical, the README offers a function that returns the data as a string:

python >>> from aocd import get_data >>> get_data(day=24, year=2015) '1\n2\n3\n7\n11\n13\n17\n19\n23\n31...

code

The call returns the puzzle input as a string. The mechanism underneath is the same for both. The package authenticates with the Advent of Code server, downloads the puzzle input for the day and year you asked for, and stores it in a local cache. The README is explicit that aocd will cache puzzle inputs and answers, including incorrect guesses, clientside, to save unnecessary requests to the server.

That caching behaviour is the most consequential design decision in the package, and it is a good one for a solver. Puzzle inputs are personalised per user, so caching them locally means you can re-run your solution offline, and it means the server is not hit on every run. It also means the cache is a record of what you have tried, which the submission code uses later.

For a script that just wants today's input, there is a command line too:

bash aocd > input.txt # saves today's data aocd 13 2018 > day13.txt # save some other day's data ```

So the package covers three shapes of use: a library for interactive work, a function for programmatic access, and a shell command for saving raw files you want to keep.

The session token, and the cookie scraper you may not need

Puzzle inputs differ by user, so the package needs your session id, and the README's answer is an environment variable:

``` bash export AOC_SESSION=cafef00db01dfaceba5eba11deadbeef

code

Windows users are told to use set instead of export. The token is the cookie set when you log in to Advent of Code, and the README says you can find it with your browser inspector.

If you would rather not use an environment variable, tokens can live in files. The default location is ~/.config/aocd/token, and setting the AOCD_DIR environment variable to an existing directory moves it elsewhere. That variable is worth setting deliberately rather than by default, because the directory holds a credential equivalent to a session cookie and the default sits in a dotfile directory that people tend to back up or sync.

There is also a script, added in version 0.9.0, called aocd-token, which attempts to find session tokens from your browser's cookie storage. The README labels the feature experimental, requires the additional package browser-cookie3, and says only Chrome, Firefox and Edge are currently supported. On macOS you may get an authentication dialog requesting permission, since Python is attempting to read browser storage files, and the README says this is expected because the script is scraping those private files to access session tokens.

The script writes what it finds to the token file:

bash $ aocd-token > ~/.config/aocd/token ```

This is a convenience with a real cost. It reads another application's private credential store, and it depends on a third party package doing the reading. For a one-off December ritual it is fine; for a machine you also work on, copying a token out of the browser once is the more predictable option.

Submitting answers, and the rate limit that comes with it

The package can submit answers for you, and this is where the README shifts tone, because the feature has consequences beyond convenience.

The basic call passes the answer, the part and the day and year:

``` python from aocd import submit submit(my_answer, part="a", day=25, year=2017)

code

The same filename introspection used for fetching also works for submission, and aocd can determine the level, part a or part b, automatically and submit to the correct part, so the short form works too:

python from aocd import submit submit(my_answer) ```

The response from the server is printed in the terminal, and a correct answer refreshes the puzzle in your browser so you can read the next part's instructions.

Then the warning, which is worth quoting in spirit because it defines the real constraint: proceed with caution, and if you submit wrong guesses your user will get rate-limited by Eric, so don't call submit until you are fairly confident you have a correct answer. That is the failure mode of automatic submission in a system that counts wrong guesses against a per-user quota.

Version 2.0.0 added a guard against the most common way to waste that quota. If the server previously told you that an answer was too high, aocd remembers that and prevents you from submitting an even higher value such as 1300. The package refuses to send a value the server has already rejected, and it remembers wrong answers in the cache alongside the inputs.

For an automated solver that runs against a live account, that guard is the difference between a rate limit and a wasted afternoon.

The models layer, and a puzzle object that remembers your mistakes

Added in version 0.8.0, the aocd.models submodule provides User and Puzzle classes, with input data available through regular attribute access:

``` python >>> from aocd.models import Puzzle >>> puzzle = Puzzle(year=2017, day=20) >>> puzzle <Puzzle(2017, 20) at 0x107322978 - Particle Swarm> >>> puzzle.input_data 'p=<-1027,-979,-188>, v=<7,60,66>, a=<9,1,-7>\np=<-1846,-1539,-1147>, v=<88,145,67>, a=<6,-5,2> ...

code

The repr even carries the puzzle title, which is a small nicety that saves a lookup, and the input text itself is available as the input_data attribute.

Answers are set the same way, by attribute, and the object remembers what you submitted:

python >>> puzzle.answer_a = 299 That's not the right answer; your answer is too high. If you're stuck, there are some general tips on the about page, or you can ask for hints on the subreddit. Please wait one minute before trying again. (You guessed 299.) [Return to Day 20] >>> puzzle.answer_a = 299 aocd will not submit that answer again. You've previously guessed 299 and the server responded: That's not the right answer; your answer is too high. If you're stuck, there are some general tips on the about page, or you can ask for hints on the subreddit. Please wait one minute before trying again. (You guessed 299.) [Return to Day 20] ```

So the second assignment does not hit the network. The rejection message from the server is stored and replayed to you, which is both the rate limit protection and a convenience.

Version 2.0.4 added a convenience import, from aocd import puzzle, returning a Puzzle instance bound to the auto-detected day, year and user, so a script that already knows where it is in the run does not have to spell out the date.

Plugging your own solver into the runner

The package can execute your solution for you, and it does that through a documented entry point rather than by importing your code by convention.

You register a callable in the adventofcode.user entry point group, and aocd will call it with three keyword arguments, year, day and data. The README points at the author's own package as the worked example, where the entry point is called wim, and shows what running against that code looks like once the package is installed with pip install advent-of-code-wim.

The same idea appears in the manifest, which declares two empty entry point groups, adventofcode.user for user solvers and adventofcode.examples for example-parser implementations. The example-parser group is what the 2.0.0 feature of fetching example data plugs into, and the README points at a separate project, aocd-example-parser, for how the scraping of examples works.

The runner itself is a console script named aoc, alongside aocd, aocd-token and aoce. Four commands is a small surface, and each one maps to a distinct job: fetch and cache, run your solver, scrape a token, and work with examples.

For a project that wants to be driven by aocd rather than to call aocd, the entry point is the contract to implement. The three keyword arguments are fixed, so the callable you register has to accept year, day and data, and it is called by the package rather than by you, which means it also has to behave well when it is called with a day you have already solved.

Example data, and the caching that keeps the server happy

Version 2.0.0 added the ability to get example data and the corresponding answers, which is the feature most Advent of Code solvers actually need, because a puzzle is much easier to develop against a small example than against the full input.

The command line output shows the whole flow. Asking for the example of day 5 of 2022 prints the puzzle title, the URL, the example data and then the answers:

``` bash $ aocd 2022 5 --example --- Day 5: Supply Stacks --- https://adventofcode.com/2022/day/5 ------------------------------- Example data 1/1 ------------------------------- [D] [N] [C] [Z] [M] [P] 1 2 3

move 1 from 2 to 1 move 3 from 1 to 3 move 2 from 2 to 1 move 1 from 1 to 2 -------------------------------------------------------------------------------- answer_a: CMZ answer_b: MCD -------------------------------------------------------------------------------- ```

Getting the answers with the example is the part that saves the most time, since you can check your solver end to end without spending a real submission.

The implementation detail is delegated, and the README says so plainly: the scraping of examples is handled by aocd-example-parser, and the manifest depends on that package with a version floor of 2025.12.12. The aocd.examples entry point group exists so that alternative example parsers can be plugged in.

The dependency list is otherwise modest, with beautifulsoup4 for parsing the puzzle pages, urllib3 for requests, pebble for the cache, aocd-example-parser for examples, tzdata on Windows, and typing_extensions for Python below 3.11. The package requires Python 3.10 or later, and the notebook extra adds IPython and jupyter-server.

The caching is what keeps the request count down, and the test configuration in the manifest reflects a package that takes the network seriously: pytest runs with --disable-socket and --allow-unix-socket, so the test suite cannot make ordinary network calls.

Editorial conclusion

Adopt advent-of-code-data if you solve Advent of Code in Python and want the input fetching, caching and submission plumbing handled for you, especially if you want your own solution entry point to be run by the package. Do not adopt it in a shared or automated context, since it holds your session token, submits answers on your behalf and can rate limit your account. Verify first that your session token file or AOC_SESSION variable is set correctly, that the AOCD_DIR you choose is not inside a repository you push, and that you understand the cache includes your incorrect guesses, since the package deliberately remembers them and will refuse to resubmit a value the server already rejected.

Frequently asked questions

How do I install advent-of-code-data?

Install it with pip install advent-of-code-data, or pip install 'advent-of-code-data[nb]' if you want to use it in a Jupyter notebook, which pulls in IPython and jupyter-server. The package requires Python 3.10 or later.

Where does advent-of-code-data get my session token?

You can export it in the AOC_SESSION environment variable, or keep token files in the default location ~/.config/aocd/token, with AOCD_DIR pointing elsewhere if you want another directory. There is also an experimental aocd-token script that scrapes session tokens from Chrome, Firefox or Edge cookie storage and needs the browser-cookie3 package.

Does advent-of-code-data cache my answers?

Yes. The README states that aocd caches puzzle inputs and answers, including incorrect guesses, clientside to save unnecessary requests to the server. That cache is what lets it refuse to submit a value the server already rejected.

Can advent-of-code-data submit my answers for me?

Yes, through the submit function, either with explicit part, day and year or with day and year inferred from the filename, and it can also work out whether to submit part a or part b. The README warns that wrong guesses get your user rate-limited, and version 2.0.0 added a check that blocks submitting a value the server already said was too high.

Official sources

  1. Issues
  2. License: MIT
  3. README
  4. Releases
  5. wimglenn/advent-of-code-data on GitHub

Was this useful?