sigaa-tools 0.1.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- sigaa_tools-0.1.1/LICENSE +21 -0
- sigaa_tools-0.1.1/PKG-INFO +315 -0
- sigaa_tools-0.1.1/README.md +287 -0
- sigaa_tools-0.1.1/pyproject.toml +59 -0
- sigaa_tools-0.1.1/setup.cfg +4 -0
- sigaa_tools-0.1.1/sigaa/__init__.py +3 -0
- sigaa_tools-0.1.1/sigaa/auth.py +42 -0
- sigaa_tools-0.1.1/sigaa/cli.py +982 -0
- sigaa_tools-0.1.1/sigaa/client.py +379 -0
- sigaa_tools-0.1.1/sigaa/config.py +123 -0
- sigaa_tools-0.1.1/sigaa/curriculum.py +139 -0
- sigaa_tools-0.1.1/sigaa/documents.py +221 -0
- sigaa_tools-0.1.1/sigaa/exporters/__init__.py +1 -0
- sigaa_tools-0.1.1/sigaa/exporters/ics.py +119 -0
- sigaa_tools-0.1.1/sigaa/http.py +146 -0
- sigaa_tools-0.1.1/sigaa/mcp_server.py +826 -0
- sigaa_tools-0.1.1/sigaa/models.py +350 -0
- sigaa_tools-0.1.1/sigaa/parsers/__init__.py +1 -0
- sigaa_tools-0.1.1/sigaa/parsers/attendance.py +57 -0
- sigaa_tools-0.1.1/sigaa/parsers/curriculum.py +255 -0
- sigaa_tools-0.1.1/sigaa/parsers/grades.py +86 -0
- sigaa_tools-0.1.1/sigaa/parsers/materials.py +105 -0
- sigaa_tools-0.1.1/sigaa/parsers/matricula.py +89 -0
- sigaa_tools-0.1.1/sigaa/parsers/news.py +99 -0
- sigaa_tools-0.1.1/sigaa/parsers/participantes.py +88 -0
- sigaa_tools-0.1.1/sigaa/parsers/plano.py +45 -0
- sigaa_tools-0.1.1/sigaa/parsers/portal.py +214 -0
- sigaa_tools-0.1.1/sigaa/parsers/schedule.py +37 -0
- sigaa_tools-0.1.1/sigaa/parsers/sipac.py +476 -0
- sigaa_tools-0.1.1/sigaa/parsers/tarefa.py +87 -0
- sigaa_tools-0.1.1/sigaa/parsers/transcript.py +265 -0
- sigaa_tools-0.1.1/sigaa/services/__init__.py +1 -0
- sigaa_tools-0.1.1/sigaa/services/sync.py +212 -0
- sigaa_tools-0.1.1/sigaa/services/whatsnew.py +44 -0
- sigaa_tools-0.1.1/sigaa/setup_wizard.py +268 -0
- sigaa_tools-0.1.1/sigaa/sipac.py +313 -0
- sigaa_tools-0.1.1/sigaa/store/__init__.py +1 -0
- sigaa_tools-0.1.1/sigaa/store/db.py +154 -0
- sigaa_tools-0.1.1/sigaa/store/repository.py +448 -0
- sigaa_tools-0.1.1/sigaa_tools.egg-info/PKG-INFO +315 -0
- sigaa_tools-0.1.1/sigaa_tools.egg-info/SOURCES.txt +78 -0
- sigaa_tools-0.1.1/sigaa_tools.egg-info/dependency_links.txt +1 -0
- sigaa_tools-0.1.1/sigaa_tools.egg-info/entry_points.txt +3 -0
- sigaa_tools-0.1.1/sigaa_tools.egg-info/requires.txt +12 -0
- sigaa_tools-0.1.1/sigaa_tools.egg-info/top_level.txt +1 -0
- sigaa_tools-0.1.1/tests/test_academic_documents.py +330 -0
- sigaa_tools-0.1.1/tests/test_attendance.py +24 -0
- sigaa_tools-0.1.1/tests/test_attendance_store.py +64 -0
- sigaa_tools-0.1.1/tests/test_config.py +30 -0
- sigaa_tools-0.1.1/tests/test_curriculum_cli.py +137 -0
- sigaa_tools-0.1.1/tests/test_curriculum_client.py +119 -0
- sigaa_tools-0.1.1/tests/test_curriculum_parser.py +117 -0
- sigaa_tools-0.1.1/tests/test_curriculum_view.py +87 -0
- sigaa_tools-0.1.1/tests/test_grades_deadlines.py +55 -0
- sigaa_tools-0.1.1/tests/test_http_configuration.py +21 -0
- sigaa_tools-0.1.1/tests/test_materials.py +56 -0
- sigaa_tools-0.1.1/tests/test_matricula.py +37 -0
- sigaa_tools-0.1.1/tests/test_mcp_curriculum.py +124 -0
- sigaa_tools-0.1.1/tests/test_mcp_curriculum_protocol.py +64 -0
- sigaa_tools-0.1.1/tests/test_mcp_document_resources.py +121 -0
- sigaa_tools-0.1.1/tests/test_mcp_documents.py +135 -0
- sigaa_tools-0.1.1/tests/test_mcp_downloads.py +184 -0
- sigaa_tools-0.1.1/tests/test_mcp_mode.py +78 -0
- sigaa_tools-0.1.1/tests/test_mcp_protocol.py +83 -0
- sigaa_tools-0.1.1/tests/test_mcp_sipac.py +132 -0
- sigaa_tools-0.1.1/tests/test_parsers.py +134 -0
- sigaa_tools-0.1.1/tests/test_participantes.py +73 -0
- sigaa_tools-0.1.1/tests/test_plan_deadlines.py +124 -0
- sigaa_tools-0.1.1/tests/test_plano.py +29 -0
- sigaa_tools-0.1.1/tests/test_setup_wizard.py +206 -0
- sigaa_tools-0.1.1/tests/test_sipac_cli.py +132 -0
- sigaa_tools-0.1.1/tests/test_sipac_client.py +242 -0
- sigaa_tools-0.1.1/tests/test_sipac_parser.py +99 -0
- sigaa_tools-0.1.1/tests/test_sipac_search_client.py +109 -0
- sigaa_tools-0.1.1/tests/test_sipac_search_parser.py +115 -0
- sigaa_tools-0.1.1/tests/test_store.py +54 -0
- sigaa_tools-0.1.1/tests/test_transcript_parser.py +157 -0
- sigaa_tools-0.1.1/tests/test_turma_grades.py +94 -0
- sigaa_tools-0.1.1/tests/test_turma_postback_isolation.py +88 -0
- sigaa_tools-0.1.1/tests/test_whatsnew.py +61 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Puca Vaz
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: sigaa-tools
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: User-friendly SIGAA and public SIPAC UFPB client (CLI + MCP)
|
|
5
|
+
Author: Puca Vaz
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/PucaVaz/sigaa-tools
|
|
8
|
+
Project-URL: Repository, https://github.com/PucaVaz/sigaa-tools
|
|
9
|
+
Project-URL: Issues, https://github.com/PucaVaz/sigaa-tools/issues
|
|
10
|
+
Keywords: sigaa,sipac,ufpb,mcp,cli,academic
|
|
11
|
+
Classifier: Environment :: Console
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Requires-Python: >=3.11
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
License-File: LICENSE
|
|
17
|
+
Requires-Dist: httpx>=0.27
|
|
18
|
+
Requires-Dist: beautifulsoup4>=4.12
|
|
19
|
+
Requires-Dist: lxml>=5.0
|
|
20
|
+
Requires-Dist: keyring>=24
|
|
21
|
+
Requires-Dist: pypdf<7,>=5.0
|
|
22
|
+
Provides-Extra: mcp
|
|
23
|
+
Requires-Dist: mcp<2,>=1.27; extra == "mcp"
|
|
24
|
+
Provides-Extra: dev
|
|
25
|
+
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
26
|
+
Requires-Dist: ruff>=0.6.0; extra == "dev"
|
|
27
|
+
Dynamic: license-file
|
|
28
|
+
|
|
29
|
+
# sigaa-tools
|
|
30
|
+
|
|
31
|
+
> [!IMPORTANT]
|
|
32
|
+
> This is an unofficial personal project and is not affiliated with, endorsed
|
|
33
|
+
> by, or supported by UFPB, SIGAA, or SIPAC. Use it responsibly, keep request rates low,
|
|
34
|
+
> and follow the rules that apply to your SIGAA account.
|
|
35
|
+
> See [Privacidade e segurança](docs/privacidade.mdx) for what is stored and what is never stored.
|
|
36
|
+
|
|
37
|
+
Friendly CLI and MCP server for **SIGAA UFPB** and **SIPAC** public process lookup. Fetch your classes, grades, deadlines, and curriculum all at once without opening the web portal.
|
|
38
|
+
|
|
39
|
+
## Quickstart
|
|
40
|
+
|
|
41
|
+
**Step 1:** Install [uv](https://docs.astral.sh/uv/) (once only):
|
|
42
|
+
```bash
|
|
43
|
+
brew install uv
|
|
44
|
+
# or: curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
**Step 2:** Install sigaa:
|
|
48
|
+
```bash
|
|
49
|
+
uv tool install "sigaa-tools[mcp] @ git+https://github.com/PucaVaz/sigaa-tools"
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
**Step 3:** Run the setup wizard:
|
|
53
|
+
```bash
|
|
54
|
+
sigaa init
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
That's it. The wizard prompts for your SIGAA credentials, stores them securely, syncs your data, and optionally sets up MCP for Claude Code or background polling.
|
|
58
|
+
|
|
59
|
+
## What you get
|
|
60
|
+
|
|
61
|
+
- **CLI**: `sigaa classes`, `sigaa news`, `sigaa grades`, `sigaa deadlines`, etc. Fast, offline-first queries from a local SQLite database.
|
|
62
|
+
- **MCP server**: Wire into Claude Code (or any MCP client) to let AI agents fetch your SIGAA data on demand.
|
|
63
|
+
- **SIPAC lookup**: `sigaa sipac process 23074.056437/2026-26` — look up public UFPB administrative processes without a browser.
|
|
64
|
+
|
|
65
|
+
## Common commands
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
sigaa sync # fetch & persist new news, deadlines, grades
|
|
69
|
+
sigaa sync --bodies # also fetch full news article text
|
|
70
|
+
sigaa classes --schedule # enrolled classes with decoded weekly schedule
|
|
71
|
+
sigaa news --class DSCO00022 # news for one class
|
|
72
|
+
sigaa news --unread --mark-seen
|
|
73
|
+
sigaa grades --semester 2025.1 # grades by semester
|
|
74
|
+
sigaa deadlines # assessment/task due dates
|
|
75
|
+
sigaa ics --out sigaa.ics # export classes + deadlines as calendar
|
|
76
|
+
sigaa curriculum # live progress & required courses
|
|
77
|
+
sigaa cra --json # official CRA as JSON
|
|
78
|
+
sigaa watch --interval 900 # continuous sync in foreground
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Store-backed commands (`classes`, `news`, `grades`, `deadlines`) are fast and offline. Network commands (`sync`, `watch`, `curriculum`, `cra`, downloads) need internet.
|
|
82
|
+
|
|
83
|
+
## SIPAC public process lookup
|
|
84
|
+
|
|
85
|
+
Use this feature to follow UFPB administrative processes without opening each SIPAC page manually. Look up one process by its complete number or find processes by an interested party name or identifier. Process details include the current status, subject, interested parties, public documents, routing movements, status changes, and attached files.
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
sigaa sipac process 23074.056437/2026-26
|
|
89
|
+
sigaa sipac process 23074.056437/2026-26 --json
|
|
90
|
+
sigaa sipac search --name "Fulano de Tal"
|
|
91
|
+
sigaa sipac search --identifier "12345678901" --page 2 --json
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Example summary:
|
|
95
|
+
|
|
96
|
+
```text
|
|
97
|
+
23074.056437/2026-26 [ATIVO]
|
|
98
|
+
ANÁLISE DE PROPOSTA DE RESOLUÇÃO SOBRE DISTRIBUIÇÃO DE ENCARGOS DIDÁTICOS
|
|
99
|
+
Origin: CI - DIREÇÃO DE CENTRO (11.01.45.01)
|
|
100
|
+
Opened: 12/06/2026 17:26
|
|
101
|
+
Interested parties: 1 | Documents: 14 | Movements: 6
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Agents can call `sipac_get_public_process` with `{"number": "23074.056437/2026-26"}`. To search, call `sipac_search_public_processes` with either `name` or `identifier`. Both interfaces use the same `schema_version: 1` contracts as the CLI JSON output. Public SIPAC commands do not authenticate, bypass restricted documents, change processes, or persist results. See the [SIPAC process guide](docs/sipac-processes.mdx) for fields, use cases, privacy guidance, and error handling.
|
|
105
|
+
|
|
106
|
+
Headless fallback: `export SIGAA_USER=... SIGAA_PASS=...`.
|
|
107
|
+
Optional `SIGAA_DB=/path/to/sigaa.db` to override the store location.
|
|
108
|
+
|
|
109
|
+
## MCP server (for code agents)
|
|
110
|
+
|
|
111
|
+
Run `sigaa init`; it can detect or create `.mcp.json` and add the `sigaa` MCP
|
|
112
|
+
server without manual absolute-path editing.
|
|
113
|
+
|
|
114
|
+
Tools: `sigaa_list_classes`, `sigaa_list_news`, `sigaa_get_news_body`,
|
|
115
|
+
`sigaa_get_schedule`, `sigaa_list_grades`, `sigaa_list_deadlines`,
|
|
116
|
+
`sigaa_get_curriculum`, `sigaa_get_cra`, `sigaa_export_ics`,
|
|
117
|
+
`sipac_get_public_process`, `sipac_search_public_processes`,
|
|
118
|
+
`sigaa_download_historico`,
|
|
119
|
+
`sigaa_download_declaracao_vinculo`, `sigaa_download_atestado_matricula`,
|
|
120
|
+
`sigaa_sync`. Store-backed reads are offline; sync, live lookups, and downloads
|
|
121
|
+
touch the network.
|
|
122
|
+
|
|
123
|
+
`sipac_get_public_process(number)` returns the public process metadata exposed
|
|
124
|
+
by UFPB: general data, interested parties, documents and public download links,
|
|
125
|
+
movements, status changes, and attached files. It shares schema version 1 with
|
|
126
|
+
`sigaa sipac process --json` and does not require credentials.
|
|
127
|
+
|
|
128
|
+
`sipac_search_public_processes(name?, identifier?, page=1)` finds public
|
|
129
|
+
processes by one interested-party field. Pass exactly one of `name` or
|
|
130
|
+
`identifier`. Each response contains at most the 15 results exposed by one
|
|
131
|
+
portal page. Results are not retained after the request finishes.
|
|
132
|
+
Identifiers such as CPF, registration number, and CNPJ are personal data. Query
|
|
133
|
+
them only for a legitimate purpose and avoid copying them into logs.
|
|
134
|
+
|
|
135
|
+
`sigaa_get_curriculum` is networked and uses the same normalized contract and
|
|
136
|
+
filters as `sigaa curriculum`: `status`, `required_only`, `period`,
|
|
137
|
+
`include_requirements`, and `include_cra`. Its default `current` view contains
|
|
138
|
+
enrolled components plus required pending ones. Pending optional components are
|
|
139
|
+
choices toward the remaining optional workload, not courses that must all be
|
|
140
|
+
completed. `sigaa_get_cra` is also networked and reads the official CRA from the
|
|
141
|
+
academic transcript; a new student may receive `source: "unavailable"` until
|
|
142
|
+
SIGAA reports one. Neither response exposes SIGAA's internal student id.
|
|
143
|
+
|
|
144
|
+
Every download tool accepts a safe filename (not an arbitrary path), never
|
|
145
|
+
overwrites, and writes under the app's private `downloads` directory. This
|
|
146
|
+
covers the three academic documents plus `sigaa_download_material` and
|
|
147
|
+
`sigaa_download_tarefa_anexo`; on those two the parameter is named `filename`
|
|
148
|
+
and no longer accepts a path. Filenames SIGAA supplies in `Content-Disposition`
|
|
149
|
+
are sanitized rather than trusted. Set
|
|
150
|
+
`SIGAA_DOWNLOAD_DIR` on the MCP server to choose another directory. A successful
|
|
151
|
+
call returns both structured metadata (filename, MIME type, and size) and
|
|
152
|
+
an opaque MCP `ResourceLink`. Clients that support resource links can present the
|
|
153
|
+
document as an attachment or download; opening it reads the saved file through
|
|
154
|
+
MCP without putting its bytes in the original tool response. The resource link is
|
|
155
|
+
valid for the current server session, while the local file remains on disk. HTML
|
|
156
|
+
certificates are exposed as download-only binary resources so an MCP client does
|
|
157
|
+
not execute the report's active SIGAA markup inline.
|
|
158
|
+
|
|
159
|
+
### Tool surface: `SIGAA_MODE`
|
|
160
|
+
|
|
161
|
+
`SIGAA_MODE` picks which tools the MCP server exposes. It defaults to `local`,
|
|
162
|
+
which exposes all 24 tools — **nothing is ever removed from a local or
|
|
163
|
+
self-hosted install**.
|
|
164
|
+
|
|
165
|
+
`SIGAA_MODE=hosted` is for a shared, multi-tenant deployment. It withholds the
|
|
166
|
+
five tools that write files to the server's disk:
|
|
167
|
+
|
|
168
|
+
| Withheld in hosted | Why |
|
|
169
|
+
| --- | --- |
|
|
170
|
+
| `sigaa_download_material` | Unbounded file writes; a class can hold hundreds of MB |
|
|
171
|
+
| `sigaa_download_tarefa_anexo` | Same |
|
|
172
|
+
| `sigaa_download_historico` | Needs a per-tenant download directory, which does not exist yet |
|
|
173
|
+
| `sigaa_download_declaracao_vinculo` | Same |
|
|
174
|
+
| `sigaa_download_atestado_matricula` | Same |
|
|
175
|
+
|
|
176
|
+
Everything else stays, including `sigaa_sync` — without it a tenant's store is
|
|
177
|
+
empty and every store-backed tool returns nothing. Its writes are confined to
|
|
178
|
+
`SIGAA_DB`. No MCP tool mutates SIGAA state in any mode: enrollment
|
|
179
|
+
selection and confirmation are deliberately CLI-only.
|
|
180
|
+
|
|
181
|
+
The mode is applied at import, so it holds whether the server is started via
|
|
182
|
+
`sigaa-mcp`, `python -m sigaa.mcp_server`, or by importing `mcp` from
|
|
183
|
+
`sigaa.mcp_server` and mounting it. Withheld tools are removed from the tool
|
|
184
|
+
manager, so they are uncallable rather than merely hidden. An unrecognized
|
|
185
|
+
`SIGAA_MODE` raises at startup instead of falling back to `local`.
|
|
186
|
+
|
|
187
|
+
A hosted deployment must also set `SIGAA_DB` and `SIGAA_DOWNLOAD_DIR` per
|
|
188
|
+
tenant. Restoring the three academic-document tools in hosted mode depends on
|
|
189
|
+
that isolation existing first.
|
|
190
|
+
|
|
191
|
+
## Scheduled polling
|
|
192
|
+
|
|
193
|
+
Run `sigaa init`; it can write the launchd plist on macOS or print the cron
|
|
194
|
+
entry for other operating systems.
|
|
195
|
+
|
|
196
|
+
## Credentials
|
|
197
|
+
|
|
198
|
+
Keyring-first, env-second. Never commit credentials, cookies, downloaded live HTML, SQLite databases, exported PDFs, or `.env` files.
|
|
199
|
+
|
|
200
|
+
`sigaa init` stores your SIGAA password securely in your OS keyring and verifies the login. Public SIPAC queries do not need credentials.
|
|
201
|
+
|
|
202
|
+
For headless environments: `export SIGAA_USER=username SIGAA_PASS=password`. Optional: `SIGAA_DB=/path/to/sigaa.db` to override the store location.
|
|
203
|
+
|
|
204
|
+
## Advanced manual configuration
|
|
205
|
+
|
|
206
|
+
Usually you should run `sigaa init`. The examples below are for manual setups,
|
|
207
|
+
debugging, or custom automation.
|
|
208
|
+
|
|
209
|
+
### Manual MCP
|
|
210
|
+
|
|
211
|
+
Run with `sigaa-mcp` (stdio). Wire into Claude Code via `.mcp.json`:
|
|
212
|
+
|
|
213
|
+
```json
|
|
214
|
+
{
|
|
215
|
+
"mcpServers": {
|
|
216
|
+
"sigaa": {
|
|
217
|
+
"command": "uvx",
|
|
218
|
+
"args": [
|
|
219
|
+
"--from",
|
|
220
|
+
"sigaa-tools[mcp] @ git+https://github.com/PucaVaz/sigaa-tools",
|
|
221
|
+
"sigaa-mcp"
|
|
222
|
+
]
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
This form carries no machine-specific path, so the file stays valid when
|
|
229
|
+
committed and shared with your team. `sigaa init` writes it for you. The server
|
|
230
|
+
reads the active account from your keyring; add
|
|
231
|
+
`"env": { "SIGAA_USER": "your_user" }` only if keyring is unavailable.
|
|
232
|
+
|
|
233
|
+
### Manual scheduled polling
|
|
234
|
+
|
|
235
|
+
**macOS (launchd)** - sync every 30 min. Save as
|
|
236
|
+
`~/Library/LaunchAgents/ai.sigaa.sync.plist` then
|
|
237
|
+
`launchctl load` it:
|
|
238
|
+
|
|
239
|
+
```xml
|
|
240
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
241
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
|
|
242
|
+
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
243
|
+
<plist version="1.0"><dict>
|
|
244
|
+
<key>Label</key><string>ai.sigaa.sync</string>
|
|
245
|
+
<key>ProgramArguments</key>
|
|
246
|
+
<array>
|
|
247
|
+
<string>/Users/you/.local/bin/sigaa</string>
|
|
248
|
+
<string>sync</string>
|
|
249
|
+
</array>
|
|
250
|
+
<key>EnvironmentVariables</key>
|
|
251
|
+
<dict><key>SIGAA_USER</key><string>your_user</string></dict>
|
|
252
|
+
<key>StartInterval</key><integer>1800</integer>
|
|
253
|
+
</dict></plist>
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
`uv tool install` puts `sigaa` in `~/.local/bin`; launchd needs it spelled out in
|
|
257
|
+
full, since it does not expand `~`. Run `which sigaa` to confirm yours.
|
|
258
|
+
|
|
259
|
+
**Linux (cron)**: `*/30 * * * * SIGAA_USER=you $HOME/.local/bin/sigaa sync`
|
|
260
|
+
(password from keyring, or add `SIGAA_PASS`).
|
|
261
|
+
|
|
262
|
+
## Architecture
|
|
263
|
+
|
|
264
|
+
```
|
|
265
|
+
sigaa/
|
|
266
|
+
config.py endpoints, JSF constants, slot-time table, creds resolution
|
|
267
|
+
http.py session: cookie jar, ViewState, re-login + retry
|
|
268
|
+
auth.py login flow
|
|
269
|
+
client.py SigaaClient -> domain models
|
|
270
|
+
sipac.py unauthenticated public SIPAC process client + JSON contract
|
|
271
|
+
models.py Student, Turma, NewsItem, Schedule, CurriculumStatus
|
|
272
|
+
parsers/ portal, news, schedule, curriculum, transcript, SIPAC process
|
|
273
|
+
store/ SQLite db + repository (dedup, queries)
|
|
274
|
+
services/ sync (fetch -> diff -> persist)
|
|
275
|
+
cli.py command line
|
|
276
|
+
mcp_server.py agent tools
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
Adding a feature (materials, attendance) = a parser + client method and a
|
|
280
|
+
CLI/MCP surface, plus store columns when it is persisted. HTML changes touch
|
|
281
|
+
only `parsers/`. Implemented so far: classes, news (+bodies), grades, deadlines,
|
|
282
|
+
curriculum progress, official CRA, academic documents, and ICS export.
|
|
283
|
+
Public SIPAC administrative-process consultation is also available live.
|
|
284
|
+
|
|
285
|
+
`exporters/` turns store data into interchange formats (currently `ics`).
|
|
286
|
+
|
|
287
|
+
## Schedule decoding
|
|
288
|
+
|
|
289
|
+
`6M2345` → Fri (day 6) morning slots 2–5. Days 2=Mon..7=Sat, shift M/T/N.
|
|
290
|
+
Clock times in `config.SLOT_TIMES_UNCONFIRMED` are an **unconfirmed** default —
|
|
291
|
+
verify against a turma's "Plano de Curso" before using them for calendar export.
|
|
292
|
+
|
|
293
|
+
## Tests
|
|
294
|
+
|
|
295
|
+
```bash
|
|
296
|
+
pytest # offline: parsers run on fixtures, store on in-memory sqlite
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
## Contributing
|
|
300
|
+
|
|
301
|
+
Interested in hacking on sigaa-tools? See [CONTRIBUTING.md](CONTRIBUTING.md) for setup and release instructions.
|
|
302
|
+
|
|
303
|
+
## Security
|
|
304
|
+
|
|
305
|
+
Single-user, local-first tool. `config.py` reads credentials from keyring first
|
|
306
|
+
and environment variables second. The SQLite db is local and may contain student
|
|
307
|
+
data copied from SIGAA. `.gitignore` excludes `*.db`, `.env`, and live HTML
|
|
308
|
+
dumps, but review generated files before sharing logs, issues, or screenshots.
|
|
309
|
+
The SIPAC process feature is read-only and public; it does not send stored
|
|
310
|
+
credentials, but its responses can contain names and identifiers already shown
|
|
311
|
+
by the public portal, so handle exported JSON responsibly.
|
|
312
|
+
|
|
313
|
+
## License
|
|
314
|
+
|
|
315
|
+
MIT. See [LICENSE](LICENSE).
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
# sigaa-tools
|
|
2
|
+
|
|
3
|
+
> [!IMPORTANT]
|
|
4
|
+
> This is an unofficial personal project and is not affiliated with, endorsed
|
|
5
|
+
> by, or supported by UFPB, SIGAA, or SIPAC. Use it responsibly, keep request rates low,
|
|
6
|
+
> and follow the rules that apply to your SIGAA account.
|
|
7
|
+
> See [Privacidade e segurança](docs/privacidade.mdx) for what is stored and what is never stored.
|
|
8
|
+
|
|
9
|
+
Friendly CLI and MCP server for **SIGAA UFPB** and **SIPAC** public process lookup. Fetch your classes, grades, deadlines, and curriculum all at once without opening the web portal.
|
|
10
|
+
|
|
11
|
+
## Quickstart
|
|
12
|
+
|
|
13
|
+
**Step 1:** Install [uv](https://docs.astral.sh/uv/) (once only):
|
|
14
|
+
```bash
|
|
15
|
+
brew install uv
|
|
16
|
+
# or: curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
**Step 2:** Install sigaa:
|
|
20
|
+
```bash
|
|
21
|
+
uv tool install "sigaa-tools[mcp] @ git+https://github.com/PucaVaz/sigaa-tools"
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
**Step 3:** Run the setup wizard:
|
|
25
|
+
```bash
|
|
26
|
+
sigaa init
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
That's it. The wizard prompts for your SIGAA credentials, stores them securely, syncs your data, and optionally sets up MCP for Claude Code or background polling.
|
|
30
|
+
|
|
31
|
+
## What you get
|
|
32
|
+
|
|
33
|
+
- **CLI**: `sigaa classes`, `sigaa news`, `sigaa grades`, `sigaa deadlines`, etc. Fast, offline-first queries from a local SQLite database.
|
|
34
|
+
- **MCP server**: Wire into Claude Code (or any MCP client) to let AI agents fetch your SIGAA data on demand.
|
|
35
|
+
- **SIPAC lookup**: `sigaa sipac process 23074.056437/2026-26` — look up public UFPB administrative processes without a browser.
|
|
36
|
+
|
|
37
|
+
## Common commands
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
sigaa sync # fetch & persist new news, deadlines, grades
|
|
41
|
+
sigaa sync --bodies # also fetch full news article text
|
|
42
|
+
sigaa classes --schedule # enrolled classes with decoded weekly schedule
|
|
43
|
+
sigaa news --class DSCO00022 # news for one class
|
|
44
|
+
sigaa news --unread --mark-seen
|
|
45
|
+
sigaa grades --semester 2025.1 # grades by semester
|
|
46
|
+
sigaa deadlines # assessment/task due dates
|
|
47
|
+
sigaa ics --out sigaa.ics # export classes + deadlines as calendar
|
|
48
|
+
sigaa curriculum # live progress & required courses
|
|
49
|
+
sigaa cra --json # official CRA as JSON
|
|
50
|
+
sigaa watch --interval 900 # continuous sync in foreground
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Store-backed commands (`classes`, `news`, `grades`, `deadlines`) are fast and offline. Network commands (`sync`, `watch`, `curriculum`, `cra`, downloads) need internet.
|
|
54
|
+
|
|
55
|
+
## SIPAC public process lookup
|
|
56
|
+
|
|
57
|
+
Use this feature to follow UFPB administrative processes without opening each SIPAC page manually. Look up one process by its complete number or find processes by an interested party name or identifier. Process details include the current status, subject, interested parties, public documents, routing movements, status changes, and attached files.
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
sigaa sipac process 23074.056437/2026-26
|
|
61
|
+
sigaa sipac process 23074.056437/2026-26 --json
|
|
62
|
+
sigaa sipac search --name "Fulano de Tal"
|
|
63
|
+
sigaa sipac search --identifier "12345678901" --page 2 --json
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Example summary:
|
|
67
|
+
|
|
68
|
+
```text
|
|
69
|
+
23074.056437/2026-26 [ATIVO]
|
|
70
|
+
ANÁLISE DE PROPOSTA DE RESOLUÇÃO SOBRE DISTRIBUIÇÃO DE ENCARGOS DIDÁTICOS
|
|
71
|
+
Origin: CI - DIREÇÃO DE CENTRO (11.01.45.01)
|
|
72
|
+
Opened: 12/06/2026 17:26
|
|
73
|
+
Interested parties: 1 | Documents: 14 | Movements: 6
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Agents can call `sipac_get_public_process` with `{"number": "23074.056437/2026-26"}`. To search, call `sipac_search_public_processes` with either `name` or `identifier`. Both interfaces use the same `schema_version: 1` contracts as the CLI JSON output. Public SIPAC commands do not authenticate, bypass restricted documents, change processes, or persist results. See the [SIPAC process guide](docs/sipac-processes.mdx) for fields, use cases, privacy guidance, and error handling.
|
|
77
|
+
|
|
78
|
+
Headless fallback: `export SIGAA_USER=... SIGAA_PASS=...`.
|
|
79
|
+
Optional `SIGAA_DB=/path/to/sigaa.db` to override the store location.
|
|
80
|
+
|
|
81
|
+
## MCP server (for code agents)
|
|
82
|
+
|
|
83
|
+
Run `sigaa init`; it can detect or create `.mcp.json` and add the `sigaa` MCP
|
|
84
|
+
server without manual absolute-path editing.
|
|
85
|
+
|
|
86
|
+
Tools: `sigaa_list_classes`, `sigaa_list_news`, `sigaa_get_news_body`,
|
|
87
|
+
`sigaa_get_schedule`, `sigaa_list_grades`, `sigaa_list_deadlines`,
|
|
88
|
+
`sigaa_get_curriculum`, `sigaa_get_cra`, `sigaa_export_ics`,
|
|
89
|
+
`sipac_get_public_process`, `sipac_search_public_processes`,
|
|
90
|
+
`sigaa_download_historico`,
|
|
91
|
+
`sigaa_download_declaracao_vinculo`, `sigaa_download_atestado_matricula`,
|
|
92
|
+
`sigaa_sync`. Store-backed reads are offline; sync, live lookups, and downloads
|
|
93
|
+
touch the network.
|
|
94
|
+
|
|
95
|
+
`sipac_get_public_process(number)` returns the public process metadata exposed
|
|
96
|
+
by UFPB: general data, interested parties, documents and public download links,
|
|
97
|
+
movements, status changes, and attached files. It shares schema version 1 with
|
|
98
|
+
`sigaa sipac process --json` and does not require credentials.
|
|
99
|
+
|
|
100
|
+
`sipac_search_public_processes(name?, identifier?, page=1)` finds public
|
|
101
|
+
processes by one interested-party field. Pass exactly one of `name` or
|
|
102
|
+
`identifier`. Each response contains at most the 15 results exposed by one
|
|
103
|
+
portal page. Results are not retained after the request finishes.
|
|
104
|
+
Identifiers such as CPF, registration number, and CNPJ are personal data. Query
|
|
105
|
+
them only for a legitimate purpose and avoid copying them into logs.
|
|
106
|
+
|
|
107
|
+
`sigaa_get_curriculum` is networked and uses the same normalized contract and
|
|
108
|
+
filters as `sigaa curriculum`: `status`, `required_only`, `period`,
|
|
109
|
+
`include_requirements`, and `include_cra`. Its default `current` view contains
|
|
110
|
+
enrolled components plus required pending ones. Pending optional components are
|
|
111
|
+
choices toward the remaining optional workload, not courses that must all be
|
|
112
|
+
completed. `sigaa_get_cra` is also networked and reads the official CRA from the
|
|
113
|
+
academic transcript; a new student may receive `source: "unavailable"` until
|
|
114
|
+
SIGAA reports one. Neither response exposes SIGAA's internal student id.
|
|
115
|
+
|
|
116
|
+
Every download tool accepts a safe filename (not an arbitrary path), never
|
|
117
|
+
overwrites, and writes under the app's private `downloads` directory. This
|
|
118
|
+
covers the three academic documents plus `sigaa_download_material` and
|
|
119
|
+
`sigaa_download_tarefa_anexo`; on those two the parameter is named `filename`
|
|
120
|
+
and no longer accepts a path. Filenames SIGAA supplies in `Content-Disposition`
|
|
121
|
+
are sanitized rather than trusted. Set
|
|
122
|
+
`SIGAA_DOWNLOAD_DIR` on the MCP server to choose another directory. A successful
|
|
123
|
+
call returns both structured metadata (filename, MIME type, and size) and
|
|
124
|
+
an opaque MCP `ResourceLink`. Clients that support resource links can present the
|
|
125
|
+
document as an attachment or download; opening it reads the saved file through
|
|
126
|
+
MCP without putting its bytes in the original tool response. The resource link is
|
|
127
|
+
valid for the current server session, while the local file remains on disk. HTML
|
|
128
|
+
certificates are exposed as download-only binary resources so an MCP client does
|
|
129
|
+
not execute the report's active SIGAA markup inline.
|
|
130
|
+
|
|
131
|
+
### Tool surface: `SIGAA_MODE`
|
|
132
|
+
|
|
133
|
+
`SIGAA_MODE` picks which tools the MCP server exposes. It defaults to `local`,
|
|
134
|
+
which exposes all 24 tools — **nothing is ever removed from a local or
|
|
135
|
+
self-hosted install**.
|
|
136
|
+
|
|
137
|
+
`SIGAA_MODE=hosted` is for a shared, multi-tenant deployment. It withholds the
|
|
138
|
+
five tools that write files to the server's disk:
|
|
139
|
+
|
|
140
|
+
| Withheld in hosted | Why |
|
|
141
|
+
| --- | --- |
|
|
142
|
+
| `sigaa_download_material` | Unbounded file writes; a class can hold hundreds of MB |
|
|
143
|
+
| `sigaa_download_tarefa_anexo` | Same |
|
|
144
|
+
| `sigaa_download_historico` | Needs a per-tenant download directory, which does not exist yet |
|
|
145
|
+
| `sigaa_download_declaracao_vinculo` | Same |
|
|
146
|
+
| `sigaa_download_atestado_matricula` | Same |
|
|
147
|
+
|
|
148
|
+
Everything else stays, including `sigaa_sync` — without it a tenant's store is
|
|
149
|
+
empty and every store-backed tool returns nothing. Its writes are confined to
|
|
150
|
+
`SIGAA_DB`. No MCP tool mutates SIGAA state in any mode: enrollment
|
|
151
|
+
selection and confirmation are deliberately CLI-only.
|
|
152
|
+
|
|
153
|
+
The mode is applied at import, so it holds whether the server is started via
|
|
154
|
+
`sigaa-mcp`, `python -m sigaa.mcp_server`, or by importing `mcp` from
|
|
155
|
+
`sigaa.mcp_server` and mounting it. Withheld tools are removed from the tool
|
|
156
|
+
manager, so they are uncallable rather than merely hidden. An unrecognized
|
|
157
|
+
`SIGAA_MODE` raises at startup instead of falling back to `local`.
|
|
158
|
+
|
|
159
|
+
A hosted deployment must also set `SIGAA_DB` and `SIGAA_DOWNLOAD_DIR` per
|
|
160
|
+
tenant. Restoring the three academic-document tools in hosted mode depends on
|
|
161
|
+
that isolation existing first.
|
|
162
|
+
|
|
163
|
+
## Scheduled polling
|
|
164
|
+
|
|
165
|
+
Run `sigaa init`; it can write the launchd plist on macOS or print the cron
|
|
166
|
+
entry for other operating systems.
|
|
167
|
+
|
|
168
|
+
## Credentials
|
|
169
|
+
|
|
170
|
+
Keyring-first, env-second. Never commit credentials, cookies, downloaded live HTML, SQLite databases, exported PDFs, or `.env` files.
|
|
171
|
+
|
|
172
|
+
`sigaa init` stores your SIGAA password securely in your OS keyring and verifies the login. Public SIPAC queries do not need credentials.
|
|
173
|
+
|
|
174
|
+
For headless environments: `export SIGAA_USER=username SIGAA_PASS=password`. Optional: `SIGAA_DB=/path/to/sigaa.db` to override the store location.
|
|
175
|
+
|
|
176
|
+
## Advanced manual configuration
|
|
177
|
+
|
|
178
|
+
Usually you should run `sigaa init`. The examples below are for manual setups,
|
|
179
|
+
debugging, or custom automation.
|
|
180
|
+
|
|
181
|
+
### Manual MCP
|
|
182
|
+
|
|
183
|
+
Run with `sigaa-mcp` (stdio). Wire into Claude Code via `.mcp.json`:
|
|
184
|
+
|
|
185
|
+
```json
|
|
186
|
+
{
|
|
187
|
+
"mcpServers": {
|
|
188
|
+
"sigaa": {
|
|
189
|
+
"command": "uvx",
|
|
190
|
+
"args": [
|
|
191
|
+
"--from",
|
|
192
|
+
"sigaa-tools[mcp] @ git+https://github.com/PucaVaz/sigaa-tools",
|
|
193
|
+
"sigaa-mcp"
|
|
194
|
+
]
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
This form carries no machine-specific path, so the file stays valid when
|
|
201
|
+
committed and shared with your team. `sigaa init` writes it for you. The server
|
|
202
|
+
reads the active account from your keyring; add
|
|
203
|
+
`"env": { "SIGAA_USER": "your_user" }` only if keyring is unavailable.
|
|
204
|
+
|
|
205
|
+
### Manual scheduled polling
|
|
206
|
+
|
|
207
|
+
**macOS (launchd)** - sync every 30 min. Save as
|
|
208
|
+
`~/Library/LaunchAgents/ai.sigaa.sync.plist` then
|
|
209
|
+
`launchctl load` it:
|
|
210
|
+
|
|
211
|
+
```xml
|
|
212
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
213
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
|
|
214
|
+
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
215
|
+
<plist version="1.0"><dict>
|
|
216
|
+
<key>Label</key><string>ai.sigaa.sync</string>
|
|
217
|
+
<key>ProgramArguments</key>
|
|
218
|
+
<array>
|
|
219
|
+
<string>/Users/you/.local/bin/sigaa</string>
|
|
220
|
+
<string>sync</string>
|
|
221
|
+
</array>
|
|
222
|
+
<key>EnvironmentVariables</key>
|
|
223
|
+
<dict><key>SIGAA_USER</key><string>your_user</string></dict>
|
|
224
|
+
<key>StartInterval</key><integer>1800</integer>
|
|
225
|
+
</dict></plist>
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
`uv tool install` puts `sigaa` in `~/.local/bin`; launchd needs it spelled out in
|
|
229
|
+
full, since it does not expand `~`. Run `which sigaa` to confirm yours.
|
|
230
|
+
|
|
231
|
+
**Linux (cron)**: `*/30 * * * * SIGAA_USER=you $HOME/.local/bin/sigaa sync`
|
|
232
|
+
(password from keyring, or add `SIGAA_PASS`).
|
|
233
|
+
|
|
234
|
+
## Architecture
|
|
235
|
+
|
|
236
|
+
```
|
|
237
|
+
sigaa/
|
|
238
|
+
config.py endpoints, JSF constants, slot-time table, creds resolution
|
|
239
|
+
http.py session: cookie jar, ViewState, re-login + retry
|
|
240
|
+
auth.py login flow
|
|
241
|
+
client.py SigaaClient -> domain models
|
|
242
|
+
sipac.py unauthenticated public SIPAC process client + JSON contract
|
|
243
|
+
models.py Student, Turma, NewsItem, Schedule, CurriculumStatus
|
|
244
|
+
parsers/ portal, news, schedule, curriculum, transcript, SIPAC process
|
|
245
|
+
store/ SQLite db + repository (dedup, queries)
|
|
246
|
+
services/ sync (fetch -> diff -> persist)
|
|
247
|
+
cli.py command line
|
|
248
|
+
mcp_server.py agent tools
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
Adding a feature (materials, attendance) = a parser + client method and a
|
|
252
|
+
CLI/MCP surface, plus store columns when it is persisted. HTML changes touch
|
|
253
|
+
only `parsers/`. Implemented so far: classes, news (+bodies), grades, deadlines,
|
|
254
|
+
curriculum progress, official CRA, academic documents, and ICS export.
|
|
255
|
+
Public SIPAC administrative-process consultation is also available live.
|
|
256
|
+
|
|
257
|
+
`exporters/` turns store data into interchange formats (currently `ics`).
|
|
258
|
+
|
|
259
|
+
## Schedule decoding
|
|
260
|
+
|
|
261
|
+
`6M2345` → Fri (day 6) morning slots 2–5. Days 2=Mon..7=Sat, shift M/T/N.
|
|
262
|
+
Clock times in `config.SLOT_TIMES_UNCONFIRMED` are an **unconfirmed** default —
|
|
263
|
+
verify against a turma's "Plano de Curso" before using them for calendar export.
|
|
264
|
+
|
|
265
|
+
## Tests
|
|
266
|
+
|
|
267
|
+
```bash
|
|
268
|
+
pytest # offline: parsers run on fixtures, store on in-memory sqlite
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
## Contributing
|
|
272
|
+
|
|
273
|
+
Interested in hacking on sigaa-tools? See [CONTRIBUTING.md](CONTRIBUTING.md) for setup and release instructions.
|
|
274
|
+
|
|
275
|
+
## Security
|
|
276
|
+
|
|
277
|
+
Single-user, local-first tool. `config.py` reads credentials from keyring first
|
|
278
|
+
and environment variables second. The SQLite db is local and may contain student
|
|
279
|
+
data copied from SIGAA. `.gitignore` excludes `*.db`, `.env`, and live HTML
|
|
280
|
+
dumps, but review generated files before sharing logs, issues, or screenshots.
|
|
281
|
+
The SIPAC process feature is read-only and public; it does not send stored
|
|
282
|
+
credentials, but its responses can contain names and identifiers already shown
|
|
283
|
+
by the public portal, so handle exported JSON responsibly.
|
|
284
|
+
|
|
285
|
+
## License
|
|
286
|
+
|
|
287
|
+
MIT. See [LICENSE](LICENSE).
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "sigaa-tools"
|
|
7
|
+
dynamic = ["version"]
|
|
8
|
+
description = "User-friendly SIGAA and public SIPAC UFPB client (CLI + MCP)"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "MIT"
|
|
11
|
+
requires-python = ">=3.11"
|
|
12
|
+
authors = [
|
|
13
|
+
{ name = "Puca Vaz" },
|
|
14
|
+
]
|
|
15
|
+
keywords = ["sigaa", "sipac", "ufpb", "mcp", "cli", "academic"]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Environment :: Console",
|
|
18
|
+
"Programming Language :: Python :: 3.11",
|
|
19
|
+
"Programming Language :: Python :: 3.12",
|
|
20
|
+
]
|
|
21
|
+
dependencies = [
|
|
22
|
+
"httpx>=0.27",
|
|
23
|
+
"beautifulsoup4>=4.12",
|
|
24
|
+
"lxml>=5.0",
|
|
25
|
+
"keyring>=24",
|
|
26
|
+
"pypdf>=5.0,<7",
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
[project.urls]
|
|
30
|
+
Homepage = "https://github.com/PucaVaz/sigaa-tools"
|
|
31
|
+
Repository = "https://github.com/PucaVaz/sigaa-tools"
|
|
32
|
+
Issues = "https://github.com/PucaVaz/sigaa-tools/issues"
|
|
33
|
+
|
|
34
|
+
[project.optional-dependencies]
|
|
35
|
+
mcp = ["mcp>=1.27,<2"]
|
|
36
|
+
dev = ["pytest>=8.0", "ruff>=0.6.0"]
|
|
37
|
+
|
|
38
|
+
[project.scripts]
|
|
39
|
+
sigaa = "sigaa.cli:main"
|
|
40
|
+
sigaa-mcp = "sigaa.mcp_server:main"
|
|
41
|
+
|
|
42
|
+
[tool.setuptools.packages.find]
|
|
43
|
+
include = ["sigaa*"]
|
|
44
|
+
|
|
45
|
+
[tool.setuptools.dynamic]
|
|
46
|
+
version = {attr = "sigaa.__version__"}
|
|
47
|
+
|
|
48
|
+
[tool.pytest.ini_options]
|
|
49
|
+
testpaths = ["tests"]
|
|
50
|
+
|
|
51
|
+
[tool.ruff]
|
|
52
|
+
line-length = 100
|
|
53
|
+
target-version = "py311"
|
|
54
|
+
|
|
55
|
+
# Pinned explicitly rather than inherited. ruff's default selection widened in
|
|
56
|
+
# 0.16, which turned a green CI red on an unchanged tree; this is the set the
|
|
57
|
+
# codebase was actually written against.
|
|
58
|
+
[tool.ruff.lint]
|
|
59
|
+
select = ["E4", "E7", "E9", "F"]
|