Proqtor
Proq (short for Programming Question) is a markdown based format and a command-line tool for authoring programming questions at scale.
The markdown based files with this format are called proq files.
Note: This package is created with the name proq and the command-line tool and the format and the tool is hence called proq. The package was renamed to proqtor to
avoid confusion with another package called proq in pypi which deals with process queues.
Installation
To use proq as a command line the recommended way is to install it as a tool using uv. See here here for instructions regarding using uv.
uv python install 3.12
uv tool install proqtor
In this Package
- Proq file format - A Markdown based jinja template format for authoring a programming question in a human readable format.
proq- A command line tool for working with proq files.ProQ- A pydantic model defining a programming question. This provides an pyhton API that can be used to integrate proq with other code evaluation environments.- Proq set config file format - An YAML file that defines a set of proqs with heading outline with references to the proq file.
This library defines a pydantic model for a programming question and a markdown based jinja template format for authoring a proq which can be loaded as the proq model.
Proq File Format
The Proq File Format is a structured way to define coding problems, solutions, and test cases using a combination of Markdown-based Jinja templates. This format ensures clarity, flexibility, and compatibility with auto-grading environments. Each file is divided into well-defined sections with specific purposes and annotations.
The proq file is a jinja template which is rendered before loaded.
File Structure
A Proq file is composed of three main sections:
- YAML Header
- Problem Statement
- Solution
- Test Cases
1. YAML Header
The YAML header contains metadata about the problem, such as its title and tags. The title and tags is defined in the pydantic model. But also support additional tags.
Example
---
title: Delete first three elements of a list
tags: ['list','list manipulation','slicing']
---
2. Problem Statement
This section describes the coding task to be solved, along with examples to clarify the requirements.
3. Solution
The solution is defined in a Markdown code block and annotated with special HTML-like tags to define the different parts of solution.
Sample Solution
# Solution
```python test.py -r 'python test.py'
# Anything above the template is the prefix part
<template>
def delete_first_three(l: list) -> None:
'''
Given a list, delete the first three elements in the list.
Arguments:
l: list - a list of elements.
Return: None - the list is modified in place.
'''
<los>...</los>
<sol>del l[:3]</sol>
</template>
# Visible part of the suffix would go here
<suffix_invisible>
{% include '../function_type_and_modify_check_suffix.py.jinja' %}
```
Solution Parts Overview:
-
Template (Required): The
<template>...</template>tag denotes the editable area of the code which can contain multiple<sol>...</sol>and<los>...</los>tags within. The template includes the parts of the code that common in both solution and the editable template.<sol>...</sol>(Required): Marks the content that is only present in the solution. There should be atleast onesoltag.<los>...</los>: Marks the content that is only present in the template.
-
Prefix (Optional): The part above the template block.
Non-editable code that appears before the main solution. -
<template>...</template>(Required): -
Suffix (Optional): The part below the template block. Non-editable code after the solution.
-
Invisible Suffix (Optional): The part comes after the suffix whose begining is marked by the opening tag
<suffix_invisible>. Non-visible code for additional functionality or testing.
Code Block Header - Execute Config
The language specified in the start of the solution code block is considered as the coding language. In addition to the language, the first line also has some arguments that resemble command line arguments of the below format.
```lang FILE_NAME -r 'RUN_COMMAND' -b 'BUILD_COMMAND'
Examples
```python test.py -r 'python test.py'
```c test.c -b 'gcc test.c -o test' -r './test'
This is used for local evaluation of the programming assignments.
4. Test Cases
Test cases verify the solution and are divided into Public and Private cases. Each case specifies input, the function call, and the expected output. The Test cases will have the following structure. The code blocks inside the second level headings are alternatively assumed to be inputs and outputs.
# Public Test Cases
## Input 1
```
Some input
```
## Output 1
```
Some output
```
# Private Test Cases
## Input 1 - With Some info
```
Some hidden input
```
## Output 1
```
Some hidden output
```
The Command Line Tool
proq is the main command line tool with sub-commands for dealing with proq files.
Commands
Use proq [command] --help to know more about the sub-command.
proq create- create a empty proq file templates for authoring the programming questions.proq evaluate- evaluate the test cases configured using the build and compile process defined proq files.proq correct- corrects the given proq by computing the outputs from the inputs and the solution given.proq export-test-cases- export the test cases into a folder with two subfolders public and private with the inputs and outputs as text files.proq show-code- Displays the different sections of the code block in a highlighted manner.proq export- export a proq file or a proq set config file as JSON, html or pdf.proq generate- Generate proqs with few shot examples(experimental).
Examples
Creating a proq
- Default template (uses python).
proq create sample.md
- Specifying number of public and private testcases.
proq create --n-public 3 --n-private 5 sample.md
- Specifying the programming language. Currently
python,javaandcare supported. For other languages the execute config have to be configured manually (see here).proq create --lang c sample.md
Evaluating a proq
-
Evaluating a single proq file.
proq evaluate sample.md -
Evaluating a single proq file in verbose mode displaying what went wrong.
proq evaluate sample.md -v proq evaluate sample.md --verbose -
Printing expected and actual output in diff mode. Diff mode has no effect without
-v.proq evaluate sample.md -v -d proq evaluate sample.md -v --diff -
Evaluating multiple files.
proq evaluate sample1.md sample2.md sample3.mdThis evaluates the given three files.
-
Evaluating multiple files using glob patterns and brace expansions.
proq evaluate sample*.md proq evaluate sample{1..4}.md proq evaluate sample{1,3}.mdThis evaluates the files that are expanded as the result.
Correcting a proq
- Correcting a single proq file.
proq correct sample.md - Correcting multiple proq files.
proq correct sample*.md proq correct sample{1..4}.md proq correct sample{1,3}.md
Exporting the Test Cases
-
Exporting the test cases as a folder
proq export-test-cases sample.md -
Exporting the test cases as a zip
proq export-test-cases sample.md --zip proq export-test-cases sample.md -z
Checking out the Code block
proq show-code command is used to display the different parts of the code block in a highlighted manner.
-
Show code as unrendered template.
proq show-code sample.md -
Show code after rendering the template
proq show-code --render proq show-code -r -
Show only the template or the solution instead of "diff".
proq show-code --mode template proq show-code -m solution
Running the Solution
proq run command is used to run the solution in a tempdir as it is run from commandline. It uses the build and run arguments from the execute config in the solution block (see this).
proq run sample.md
Exporting a proq
proq export supports exporting to json, html and pdf formats. PDF conversion uses the systems chrome executable. It uses 'chrome' as the default executable name. To set a different executable name configure CHROME environment variable.
-
Specifying only the format. Uses the same file name with the extension of the export format.
proq export sample.md -f pdfThis will create a file called sample.pdf
-
With different chrome executable.
export CHROME=google-chrome-stable proq export sample.md -f pdf -
Hiding Private testcases in the HTML or PDF output.
proq export sample.md -f html --hide-private-testcases
Generating new proqs with Few shot examples (experimental)
proq generate uses LLMs with a prompt and fewshot examples to create new proq files. Currently Open AI (openai) and groq models are supported. This will need the respective API keys to be added as environment variables. Models are specified in the format "provider:model_name".
- Using default model "groq:openai/gpt-oss-20b".
export GROQ_API_KEY=<Your API Key> proq generate "write a function to find the sum of squares of odd numbers in a given list" example1.md example2.md -o sum_squares_odd.md - Specifying different model
export OPENAI_API_KEY=<Your API Key> proq generate "write a function to find the sum of squares of odd numbers in a given list" example1.md example2.md -o sum_squares_odd.md -m "openai:gpt-4o-mini"
Proq Set Config File
A proq set config file can be used to define a set of proqs under different sections and subsections in a yaml having the following structure.
class NestedProq:
title: str
content: NestedProq | str # relative path to the proq file
Example
See assessment.yaml and unit.yaml
ProQ Python API
See core.py and prog_langs.py for proq related classess and functions.
Metadata
Release files for proqtor 2.2.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| proqtor-2.2.1.tar.gz | 31.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| proqtor-2.2.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 63.8 kB
Release files / proqtor-2.2.1.tar.gz
| Download URL | proqtor-2.2.1.tar.gz |
|---|---|
| Size | 31.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f5cafb90803654b15f7fe9614a331569b5b4fa26062aa6e52b8c36242752addf
|
|
BLAKE2b-256 checksum How to use checksums |
07f9405bc851e9959c4620980c7eb05b5e2e0c4e0fe844aa2b8477ae36dc8e4b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 28, 2025.
Transparency logRelease files / proqtor-2.2.1-py3-none-any.whl
| Download URL | proqtor-2.2.1-py3-none-any.whl |
|---|---|
| Size | 32.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
11f57a06d235f32ae53236bf8874b281149f038d5bd595772066109198589574
|
|
BLAKE2b-256 checksum How to use checksums |
5ce475801e8e5fe26c49d48d5c50d882d8b2671363b063eeb47afbdfaf3e627d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 28, 2025.
Transparency log