Deployment, configuration, and workflow documentation for maintainers and developers.
- Python 3.8+
- pip
git clone https://github.com/youngfish42/FL-paper-update-tracker.git
cd FL-paper-update-tracker
pip install -r requirements.txtcd src
python main.py run --env=devIn dev mode the script will:
- Load the cache from
cached/dblp.yaml - Query DBLP for all configured
keywords × queriescombinations - Print logs to stdout
- Not write to
GITHUB_ENV
You can inspect topic_new_items and msg in the logs to preview the issue content.
Additional CLI flags:
--primary_only— Run in two-phase mode: primary keyword scans all venues first, then secondary keywords only scan venues where new papers were found. This mimics the automatic cron/push behavior.--all_years— Disable the year filter and skip abstract fetching / translation. Useful for backfilling the entire history.
All behavior is controlled by config.yaml in the project root.
dblp:
url: https://dblp.org/search/publ/api?q={}&format=json&h=1000
keywords:
- federate
- gradient inversion
- FedAvg
- ...
queries:
- "venue:IJCAI:"
- "venue:NeurIPS:"
# ... add more queries here
mails:
- "im.young@foxmail.com"| Field | Description |
|---|---|
dblp.url |
DBLP search API endpoint. {} is replaced by the fully-encoded topic query. h=1000 requests up to 1000 hits. |
dblp.keywords |
List of research-domain keywords (e.g. [federate, FedAvg, ...]). The first keyword is the primary keyword; secondary keywords are only scanned on venues that produced new papers during automatic runs. This is the main field to change when switching to a different domain. |
dblp.queries |
List of plain-text DBLP venue restrictions. The runner automatically URL-encodes each query and prepends the encoded keyword before calling the API. |
dblp.mails |
The first address is used as the Crossref API contact email. Additional addresses are reserved for future mail-notification features. |
- Find the DBLP venue code (e.g.,
venue:ICMLorstreamid:journals/pami). - Append the plain query string to
dblp.queries. For example:venue:ICML:streamid:journals/pami:
- Update
scripts/convert_cache_to_md.pyif you want the new venue to appear under a specific category inFL-Papers.md. - Update
README.md(both English and Chinese sections) to list the new venue.
This repository uses GitHub Actions to run the tracker automatically.
| Trigger | Description |
|---|---|
| Schedule | Every day at 00:00 UTC+8 (cron: 0 0 * * *) |
| Push | On every push to the main branch |
| Manual | Via workflow_dispatch in the Actions tab |
- Checkout – Clones the repository.
- Setup Python – Installs Python 3.8.
- Install Dependencies – Runs
pip install -r requirements.txt. - Run Tracker – Executes
src/main.pywith--env=prodand--primary_only(for cron/push). It assembles each API query fromkeywords+queries, fetches results, filters by year, deduplicates byeeand bytitle, and updatescached/dblp.yaml.- Primary keyword (
keywords[0]) scans all venues. - Secondary keywords only scan venues where the primary keyword discovered new papers, reducing API load.
- Primary keyword (
- Extract Related Code (optional) – Runs
scripts/fetch_related_code.pyto scan abstracts for GitHub repository links and backfillrelated_codefields. - Fetch Missing Abstracts (optional) – Runs
scripts/fetch_abstracts.pyto backfill emptyabstractfields and their Chinese translations for existing papers. - Update FL-Papers.md – Runs
scripts/convert_cache_to_md.pyto regenerate the categorized Markdown paper list from the updated cache. - Setup Var – Escapes the generated Markdown message for GitHub Actions.
- Push Done Work – Commits
cached/dblp.yamlandFL-Papers.mdback to themainbranch. - Create Issue – If new papers were found, opens a GitHub Issue using
.github/issue-template.md.
The issue title follows this pattern:
Paper Update [Venue1, Venue2, ...] @ YYYY-MM-DD
The issue body contains:
- A summary header for each venue with new papers (e.g.,
VenueName [+3]) - An unordered list of paper titles with
[PUB]hyperlinks pointing to the DBLPeefield - When a
related_codefield is present, an additional[CODE]hyperlink is appended after[PUB]
.
├── .github/
│ ├── workflows/
│ │ └── watch.yml # GitHub Actions workflow
│ └── issue-template.md # Issue template (Nunjucks)
├── cached/
│ └── dblp.yaml # Persistent cache of reported papers
├── scripts/
│ ├── convert_cache_to_md.py # Converts cache to structured Markdown
│ ├── fetch_abstracts.py # Backfill/refresh paper abstracts
│ ├── fetch_dois.py # Backfill missing DOIs
│ ├── fetch_related_code.py # Backfill GitHub links from abstracts
│ ├── dedup_cache_by_title.py# One-off deduplication by title
│ └── dedup_cache_global.py # One-off global cross-topic deduplication
├── src/
│ ├── main.py # Entry point and orchestration
│ └── utils.py # API calls, parsing, formatting, dedup logic
├── config.yaml # Venue list and settings
├── FL-Papers.md # Structured Markdown output of tracked papers
├── requirements.txt # Python dependencies
├── README.md # User-facing documentation
├── TECHNICAL.md # This file
└── AGENTS.md # Maintenance guide for agents
src/main.py– Loads cache, iterates over topics, queries DBLP, filters by year, performs three-stage deduplication (byee, bytitle, and global cross-topic), fetches abstracts and translations for new papers, extracts related code links, and writes new papers toGITHUB_ENV.src/utils.py– Containsget_dblp_items(JSON parsing),deduplicate_items_by_ee/deduplicate_items_by_title(two-stage dedup logic),filter_items_by_year(year window filter),get_msg(Markdown formatting),fetch_abstract_for_papers(abstract retrieval from Crossref / Semantic Scholar / arXiv / OpenAlex),translate_abstracts_for_papers(Chinese translation via Qwen-MT-plus),extract_github_links(code link extraction),fetch_doi_for_papers(DOI backfill), and helpers for topic short-name extraction.cached/dblp.yaml– YAML mapping of topic → list of paper dicts. Serves as the source of truth for what has already been reported.scripts/convert_cache_to_md.py– RegeneratesFL-Papers.mdfrom the cache using domain-specific venue and category maps.scripts/fetch_abstracts.py– Standalone script to backfillabstractfields for existing papers. Supports--year alland--retry-failed.scripts/fetch_dois.py– Standalone script to backfill missingdoifields. Supports--year alland--retry-all.scripts/fetch_related_code.py– Standalone script to backfillrelated_codefields by scanning abstracts for GitHub links. Supports--year alland--retry-failed.scripts/dedup_cache_by_title.py&scripts/dedup_cache_global.py– One-off maintenance scripts for cache deduplication.
If the cache becomes corrupted or you want to re-report all papers:
rm cached/dblp.yamlThe next run will treat every paper as new and recreate the cache.
Edit .github/workflows/watch.yml:
schedule:
- cron: '0 0 * * *' # Change this cron expression# Process current-year papers (default)
python scripts/fetch_abstracts.py
# Process all years
python scripts/fetch_abstracts.py --year all
# Retry previously failed entries
python scripts/fetch_abstracts.py --retry-failed# Process current-year papers with missing DOI
python scripts/fetch_dois.py
# Process all years
python scripts/fetch_dois.py --year all
# Re-fetch for all papers
python scripts/fetch_dois.py --retry-all# Process current-year papers
python scripts/fetch_related_code.py
# Process all years
python scripts/fetch_related_code.py --year all
# Retry previously failed entries
python scripts/fetch_related_code.py --retry-failed- Edit
config.yaml→dblp.keywords(first keyword is primary). - Adjust
dblp.queriesto match the new domain. - Update
scripts/convert_cache_to_md.py:VENUE_MAP,CATEGORY_MAP,CATEGORY_ORDER, andVENUE_ORDER. - Reset the cache by deleting or renaming
cached/dblp.yaml.
Edit src/utils.py → get_msg. The function is called from src/main.py after merging papers by venue (name_topic). Each venue appears once in the issue body, with the heading plus the full paper list.
Edit src/utils.py → filter_items_by_year:
min_year = current_year - 3
max_year = current_year + 1Adjust the offsets as needed.