

0 / 2 embers
0 / 3000 xp
click for more info
Complete a lesson to start your streak
click for more info
Difficulty: 5
click for more info
Not enough gems
Cost: 6 gems
1: Calculator App
incomplete
2: Validate Paths
incomplete
3: List Files
incomplete
4: Get File Content
incomplete
5: Write Files
incomplete
6: Run Python
incomplete
This lesson's interactive features are locked, please to keep using them
Now that we have a function that can get the contents of a directory, we need one that can get the contents of a file. Again, we'll just return the file contents as a string, or an error string if something went wrong.
As always, we'll scope the function to a specific working directory, which will be set by us, not by the LLM agent.
def get_file_content(working_directory: str, file_path: str) -> str:f'Error: Cannot read "{file_path}" as it is outside the permitted working directory'f'Error: File not found or is not a regular file: "{file_path}"'I'll list some useful standard library functions in the Tips section below.
Read only up to 10_000 characters from the file, in case it's very large. The .read() method of file objects makes this easy – just pass in the maximum number of characters to read as an argument. You'll get a string value representing either the full contents of the file or the first n characters, whichever is smaller.
Check if the file was larger than the limit. A simple way of doing this is to try to read one more character after reading the initial chunk. If you get an empty string, you know that you already reached the end of the file. If you get a character back, then the file still had more data. In that case, add a message to the contents string to indicate that it was truncated. For example:
# After reading the first MAX_CHARS...
if f.read(1):
content += f'[...File "{file_path}" truncated at {MAX_CHARS} characters]'Instead of hard-coding the 10_000 character limit, I stored it as a variable in a config.py file at the root of my project.
We don't want to accidentally read a gigantic file and send all that data to the LLM... that's a good way to burn through our token limits.
You can use:
result = get_file_content("calculator", "lorem.txt")
print(f"lorem.txt length: {len(result)}")
print(f"lorem.txt truncated: {'truncated' in result}")get_file_content("calculator", "main.py")
get_file_content("calculator", "pkg/calculator.py")
get_file_content("calculator", "/bin/cat") (this should return an error string)
get_file_content("calculator", "pkg/does_not_exist.py") (this should return an error string)
Run and submit the CLI tests.
os.path.abspath(): Get an absolute path from a relative path
os.path.join(): Join two paths together safely (handles slashes)
os.path.normpath(): Normalize a path (handles things like ..)
os.path.commonpath(): Get the common sub-path shared by multiple paths
os.path.isfile(): Check if a path points to an existing regular file
open(): Open a file for reading or writing
.read(): Read a text file to a string, optionally specifying a maximum number of characters
Example of reading up to a certain number of characters from a text file:
MAX_CHARS = 10_000
with open(file_path, "r") as f:
file_content_string = f.read(MAX_CHARS)The with statement automatically closes the file for us when the block finishes.