Yet another Codeforces CLI tool
Project description
pyforces
Yet another command-line interface tool for Codeforces designed for (neo)vim competitors. Rebirth of xalanq/cf-tool.
Why another CLI tool?
Codeforces added bot detection recently, and AFAIK all the existing CLI tools are blocked. ref1 ref2
Features
- Parse sample testcases.
- Test your solution with parsed testcases.
- Submit code.
- Generate code from templates.
- Start a contest (parse sample testcases for all problems and optionally gen template).
- Gym support.
Feature requests and PRs are welcomed.
Since this tool is designed for speed only, some features of xalanq/cf-tool are removed. If you want some other features like contest standing, please use Codeforces webpage itself or other GUI tools like CCH.
Installation
pip install pyforces-cli
See FAQ if you encounter any problems.
Usage
pyforces configto login and configure your tool. Firefox is needed for login. See How to login below.pyforces race 2092to start the contest2092. The contest id is in the URL, for example 2092. Same for gym (numbers >= 100000 are gyms).pyforces testin the problem directory, like~/cf/contest/2092/a, to test your solution against parsed sample testcases. Note that you need to first compile it yourself, and the executable filename is derived from the cpp filename. If the executable file's modified time is earlier than the source file's, you will see a warning.pyforces submitin the problem folder, to submit your solution.pyforces parsein the problem folder to parse sample testcases.pyforces genin the problem folder to generate a file from template.
How to login
First, you need to login to codeforces in Firefox. If you don't use Firefox, either use it once or find a way (like a plugin?) to configure your ~/.pyforces/headers.txt (If you don't know what is ~, try searching home directory).
Then, follow this video to configure your HTTP header:
https://github.com/user-attachments/assets/cac3b09a-1809-4de3-bc9a-53d8d9df8c05
(Note: in the video the root name has been configured to cf not default pyforces.)
If the method in the video fails, check FAQ first. If that doesn't help, you can manually paste your headers to ~/.pyforces/headers.txt. If you use Firefox, directly pasting the "(Copy All)" to ~/.pyforces/headers.txt is okay. If you use other browsers, check this example headers.txt.
IMPORTANT: It is recommended to paste your headers before each contest. I'm not sure how long they last but it works for a single contest's session.
Vim config
The intended use of this tool is to bind some keys to speed up testing and submitting. Here is an example neovim keybinding configuration (vim users need to replace term by !):
" test, and submit if test passed
nnoremap <F5> :w<CR>:term pyforces test -f % && pyforces submit -f %<CR>
" test
nnoremap <F6> :term pyforces test -f %<CR>
" submit
nnoremap <F7> :w<CR>:term pyforces submit -f %<CR>
Change the keys to your choices as you wish.
Also, if you don't want to mess up keybindings of other buffers or projects, consider adding a filetype check and buffer prefix:
" test, and submit if test passed
au FileType cpp nnoremap <buffer><F5> :w<CR>:term pyforces test -f % && pyforces submit -f %<CR>
" test
au FileType cpp nnoremap <buffer><F6> :term pyforces test -f %<CR>
" submit
au FileType cpp nnoremap <buffer><F7> :w<CR>:term pyforces submit -f %<CR>
" python support, with program_type_id=70 (PyPy 3.10)
au FileType python nnoremap <buffer><F5> :w<CR>:term pyforces test -f % && pyforces submit --file=% --program-type-id=70<CR>
au FileType python nnoremap <buffer><F6> :w<CR>:term pyforces test -f %<CR>
au FileType python nnoremap <buffer><F7> :w<CR>:term pyforces submit -f % --program-type-id=70<CR>
FAQ
pip install failed
error: externally-managed-environment
× This environment is externally managed
It is recommended to install this tool in a virtual environment. I'd suggest astral-uv in 2025.
If you don't want to use a virtual environment, adding --break-system-packages at the end of pip install should work.
Command 'pyforces' not found
If pyforces command isn't available, you can use python -m pyforces to invoke pyforces.
Terminal stuck when pasting headers
Change the buffer size of your terminal, and make sure you press enter after pasting it if it seems to stuck. You can modify the buffer size in your terminal's settings.
Is it violating bot detection?
Since login requries you to actually login in Firefox first, this doesn't violate bot detection. For more details, see here.
Cannot track last submission
This is a known bug and cannot be reproduced stably. However the submission always works, so you can still manually track the status.
Other issues
If you encounter any issues, please read the error message and stacktrace first. If you believe this is a bug or unwanted feature, submit an issue with the stacktrace, or use pyforces --log-level=debug <subcommand> [sub-arguments] to get even more verbose output.
TODO
- Bug fix: some problems have multiple sub-problems like g1, g2
- Bug fix: cannot track last submission
- Floating-point errors in tests
- (Neo)vim config example
- Fix "ensure logged in" (some old cookies still work on the host url)
- Use websocket to receive status updates
-
Test on Windows & MacWrite tests(?) - Provide more test outputs
- Better CLI
and color - Arguments for time and memory limit
- Arguments for user customization (submit with custom URL and problem id)
- Log to
~/.pyforces/logs/to track bugs - Log requests and responses
- Also store images if
parse_problem_md
Not Planned
- Login with username and password (too complicated firewall)
- SPJ, interactive problem and communication. Most users don't write SPJ or interactor during contest, and after contest it is better to write custom test scripts for these problems.
- Export as a python SDK for other libraries. CLI is the only way to use this tool.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pyforces_cli-0.5.0.tar.gz.
File metadata
- Download URL: pyforces_cli-0.5.0.tar.gz
- Upload date:
- Size: 28.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d128ab9effd2c73eb71515a6fbbb20aca7b06b36704132ba1ab1519bcd12a525
|
|
| MD5 |
d0d6c1620dbb32ce3fb7d6d05b37bda7
|
|
| BLAKE2b-256 |
6782c4e8ecd8bdf61e887a842337eee600665c1fe73ccbf0727e7d06bcc2ef93
|
Provenance
The following attestation bundles were made for pyforces_cli-0.5.0.tar.gz:
Publisher:
python-publish.yml on LZDQ/pyforces
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pyforces_cli-0.5.0.tar.gz -
Subject digest:
d128ab9effd2c73eb71515a6fbbb20aca7b06b36704132ba1ab1519bcd12a525 - Sigstore transparency entry: 702295375
- Sigstore integration time:
-
Permalink:
LZDQ/pyforces@1f7c872bdb15411b69c473d1b80ef202a3067069 -
Branch / Tag:
refs/tags/v0.5.0 - Owner: https://github.com/LZDQ
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@1f7c872bdb15411b69c473d1b80ef202a3067069 -
Trigger Event:
release
-
Statement type:
File details
Details for the file pyforces_cli-0.5.0-py3-none-any.whl.
File metadata
- Download URL: pyforces_cli-0.5.0-py3-none-any.whl
- Upload date:
- Size: 27.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
59cb969a38b5da47f8d8dd6f5dc1ba03b920f693c5306996e56a13ddb34a1f32
|
|
| MD5 |
ab268db0a5120599b46269993632397d
|
|
| BLAKE2b-256 |
b63a7c3021d53fb0c4be640f5d5c6d5ba6b252e517c60eb757eb67379de2d637
|
Provenance
The following attestation bundles were made for pyforces_cli-0.5.0-py3-none-any.whl:
Publisher:
python-publish.yml on LZDQ/pyforces
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pyforces_cli-0.5.0-py3-none-any.whl -
Subject digest:
59cb969a38b5da47f8d8dd6f5dc1ba03b920f693c5306996e56a13ddb34a1f32 - Sigstore transparency entry: 702295376
- Sigstore integration time:
-
Permalink:
LZDQ/pyforces@1f7c872bdb15411b69c473d1b80ef202a3067069 -
Branch / Tag:
refs/tags/v0.5.0 - Owner: https://github.com/LZDQ
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@1f7c872bdb15411b69c473d1b80ef202a3067069 -
Trigger Event:
release
-
Statement type: