odysseeapi 0.2.0__tar.gz → 1.0.0__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.
- {odysseeapi-0.2.0 → odysseeapi-1.0.0}/PKG-INFO +13 -26
- {odysseeapi-0.2.0 → odysseeapi-1.0.0}/Readme.md +12 -25
- odysseeapi-1.0.0/odysseeapi/Odyssee.py +79 -0
- odysseeapi-0.2.0/odysseeapi/Odyssee.py → odysseeapi-1.0.0/odysseeapi/OdysseeCOS.py +5 -10
- {odysseeapi-0.2.0 → odysseeapi-1.0.0}/odysseeapi.egg-info/PKG-INFO +13 -26
- {odysseeapi-0.2.0 → odysseeapi-1.0.0}/odysseeapi.egg-info/SOURCES.txt +1 -0
- {odysseeapi-0.2.0 → odysseeapi-1.0.0}/pyproject.toml +2 -2
- {odysseeapi-0.2.0 → odysseeapi-1.0.0}/odysseeapi/__init__.py +0 -0
- {odysseeapi-0.2.0 → odysseeapi-1.0.0}/odysseeapi.egg-info/dependency_links.txt +0 -0
- {odysseeapi-0.2.0 → odysseeapi-1.0.0}/odysseeapi.egg-info/top_level.txt +0 -0
- {odysseeapi-0.2.0 → odysseeapi-1.0.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: odysseeapi
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 1.0.0
|
|
4
4
|
Summary: Unofficial Python API for Odyssee
|
|
5
5
|
Author-email: Géry Casiez <gery.casiez@univ-lille.fr>
|
|
6
6
|
Project-URL: Repository, https://github.com/casiez/OdysseeAPI
|
|
@@ -17,7 +17,7 @@ Provides an unofficial API for the [Odyssee platform](https://odyssee.enseigneme
|
|
|
17
17
|
|
|
18
18
|
## Features
|
|
19
19
|
|
|
20
|
-
- download applications of candidates
|
|
20
|
+
- download applications of candidates as zip files
|
|
21
21
|
- get information about candidates
|
|
22
22
|
- get information about committee members
|
|
23
23
|
- get information about institutions
|
|
@@ -32,34 +32,21 @@ Provides an unofficial API for the [Odyssee platform](https://odyssee.enseigneme
|
|
|
32
32
|
pip install odysseeapi
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
-
## Getting the authentication token
|
|
36
|
-
1. Go to the [Odyssee platform](https://odyssee.enseignementsup-recherche.gouv.fr/) using Chrome
|
|
37
|
-
1. Open the developer tools (F12 or right-click and select "Inspect")
|
|
38
|
-
1. Go to the "Network" tab
|
|
39
|
-
1. Refresh the page
|
|
40
|
-
1. Look for a request
|
|
41
|
-
- Click on the request and go to the "Headers" tab
|
|
42
|
-
- Look for the "Authorization" header and copy its value (it should start with "Bearer")
|
|
43
|
-
1. Copy the token and use it in your code to authenticate with the API
|
|
44
|
-
|
|
45
|
-
Note that the authentication uses both cookies and a bearer token, so you need to provide both to access the API.
|
|
46
|
-
The API automatically handles the cookie (using [browsercookie](https://pypi.org/project/browsercookie/)), so you only need to provide the bearer token.
|
|
47
|
-
|
|
48
|
-
Note that the token is valid for a limited time, so you may need to repeat this process periodically to obtain a new token.
|
|
49
|
-
|
|
50
|
-

|
|
51
|
-
|
|
52
35
|
## Minimal example
|
|
53
36
|
|
|
54
37
|
```python
|
|
55
|
-
from odysseeapi.
|
|
38
|
+
from odysseeapi.OdysseeCOS import OdysseeCOS
|
|
56
39
|
|
|
57
40
|
numposte = "123456"
|
|
58
|
-
|
|
41
|
+
username = "xyz"
|
|
42
|
+
password = "abc"
|
|
59
43
|
|
|
60
|
-
# Initialize the API client with the numposte
|
|
44
|
+
# Initialize the API client with the numposte and use_cache set to True
|
|
61
45
|
# setting use_cache to False forces the API client to fetch fresh data from the server for each request, while setting it to True allows the client to use cached data if available
|
|
62
|
-
odyssee =
|
|
46
|
+
odyssee = OdysseeCOS(numposte, True)
|
|
47
|
+
|
|
48
|
+
# The following line is used to authenticate the user and obtain the necessary cookies and bearer token for subsequent API calls. It is optional when using the cached data
|
|
49
|
+
odyssee.authenticate(username, password)
|
|
63
50
|
|
|
64
51
|
# Download the applications of the candidates in the specified directory
|
|
65
52
|
odyssee.download_applications('dossiers_candidats')
|
|
@@ -79,11 +66,11 @@ print(keywords)
|
|
|
79
66
|
candidates_with_details = odyssee.get_candidates_with_details()
|
|
80
67
|
print(candidates_with_details)
|
|
81
68
|
|
|
82
|
-
# odyssee.assign_jury_members_to_candidate("f1e2d3c4-b5a6-4789-9876-543210fedcba", "
|
|
69
|
+
# odyssee.assign_jury_members_to_candidate("f1e2d3c4-b5a6-4789-9876-543210fedcba", "123456", "78910")
|
|
83
70
|
|
|
84
71
|
# Download the reports of the committee members for the candidates in the specified directory
|
|
85
|
-
odyssee.downloadReports("
|
|
72
|
+
# odyssee.downloadReports("rapportsOdyssee")
|
|
86
73
|
|
|
87
|
-
#
|
|
74
|
+
# At the end of the first jury meeting, record the opinion for each candidate and the results of the vote
|
|
88
75
|
# odyssee.opinion_for_interview("f1e2d3c4-b5a6-4789-9876-543210fedcba", "A", "Motif audition", 16, 16, 0, 0, 16, 0)
|
|
89
76
|
```
|
|
@@ -7,7 +7,7 @@ Provides an unofficial API for the [Odyssee platform](https://odyssee.enseigneme
|
|
|
7
7
|
|
|
8
8
|
## Features
|
|
9
9
|
|
|
10
|
-
- download applications of candidates
|
|
10
|
+
- download applications of candidates as zip files
|
|
11
11
|
- get information about candidates
|
|
12
12
|
- get information about committee members
|
|
13
13
|
- get information about institutions
|
|
@@ -22,34 +22,21 @@ Provides an unofficial API for the [Odyssee platform](https://odyssee.enseigneme
|
|
|
22
22
|
pip install odysseeapi
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
-
## Getting the authentication token
|
|
26
|
-
1. Go to the [Odyssee platform](https://odyssee.enseignementsup-recherche.gouv.fr/) using Chrome
|
|
27
|
-
1. Open the developer tools (F12 or right-click and select "Inspect")
|
|
28
|
-
1. Go to the "Network" tab
|
|
29
|
-
1. Refresh the page
|
|
30
|
-
1. Look for a request
|
|
31
|
-
- Click on the request and go to the "Headers" tab
|
|
32
|
-
- Look for the "Authorization" header and copy its value (it should start with "Bearer")
|
|
33
|
-
1. Copy the token and use it in your code to authenticate with the API
|
|
34
|
-
|
|
35
|
-
Note that the authentication uses both cookies and a bearer token, so you need to provide both to access the API.
|
|
36
|
-
The API automatically handles the cookie (using [browsercookie](https://pypi.org/project/browsercookie/)), so you only need to provide the bearer token.
|
|
37
|
-
|
|
38
|
-
Note that the token is valid for a limited time, so you may need to repeat this process periodically to obtain a new token.
|
|
39
|
-
|
|
40
|
-

|
|
41
|
-
|
|
42
25
|
## Minimal example
|
|
43
26
|
|
|
44
27
|
```python
|
|
45
|
-
from odysseeapi.
|
|
28
|
+
from odysseeapi.OdysseeCOS import OdysseeCOS
|
|
46
29
|
|
|
47
30
|
numposte = "123456"
|
|
48
|
-
|
|
31
|
+
username = "xyz"
|
|
32
|
+
password = "abc"
|
|
49
33
|
|
|
50
|
-
# Initialize the API client with the numposte
|
|
34
|
+
# Initialize the API client with the numposte and use_cache set to True
|
|
51
35
|
# setting use_cache to False forces the API client to fetch fresh data from the server for each request, while setting it to True allows the client to use cached data if available
|
|
52
|
-
odyssee =
|
|
36
|
+
odyssee = OdysseeCOS(numposte, True)
|
|
37
|
+
|
|
38
|
+
# The following line is used to authenticate the user and obtain the necessary cookies and bearer token for subsequent API calls. It is optional when using the cached data
|
|
39
|
+
odyssee.authenticate(username, password)
|
|
53
40
|
|
|
54
41
|
# Download the applications of the candidates in the specified directory
|
|
55
42
|
odyssee.download_applications('dossiers_candidats')
|
|
@@ -69,11 +56,11 @@ print(keywords)
|
|
|
69
56
|
candidates_with_details = odyssee.get_candidates_with_details()
|
|
70
57
|
print(candidates_with_details)
|
|
71
58
|
|
|
72
|
-
# odyssee.assign_jury_members_to_candidate("f1e2d3c4-b5a6-4789-9876-543210fedcba", "
|
|
59
|
+
# odyssee.assign_jury_members_to_candidate("f1e2d3c4-b5a6-4789-9876-543210fedcba", "123456", "78910")
|
|
73
60
|
|
|
74
61
|
# Download the reports of the committee members for the candidates in the specified directory
|
|
75
|
-
odyssee.downloadReports("
|
|
62
|
+
# odyssee.downloadReports("rapportsOdyssee")
|
|
76
63
|
|
|
77
|
-
#
|
|
64
|
+
# At the end of the first jury meeting, record the opinion for each candidate and the results of the vote
|
|
78
65
|
# odyssee.opinion_for_interview("f1e2d3c4-b5a6-4789-9876-543210fedcba", "A", "Motif audition", 16, 16, 0, 0, 16, 0)
|
|
79
66
|
```
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Odyssee.py -
|
|
4
|
+
#
|
|
5
|
+
# Authors:
|
|
6
|
+
# Géry Casiez https://gery.casiez.net
|
|
7
|
+
#
|
|
8
|
+
# 2026
|
|
9
|
+
#
|
|
10
|
+
# BSD License https://opensource.org/licenses/BSD-3-Clause
|
|
11
|
+
#
|
|
12
|
+
# Redistribution and use in source and binary forms, with or without
|
|
13
|
+
# modification, are permitted provided that the following conditions are met:
|
|
14
|
+
#
|
|
15
|
+
# 1. Redistributions of source code must retain the above copyright notice, this list of conditions
|
|
16
|
+
# and the following disclaimer.
|
|
17
|
+
#
|
|
18
|
+
# 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions
|
|
19
|
+
# and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
|
20
|
+
#
|
|
21
|
+
# 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or
|
|
22
|
+
# promote products derived from this software without specific prior written permission.
|
|
23
|
+
|
|
24
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
|
25
|
+
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
26
|
+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
27
|
+
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
28
|
+
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
29
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
30
|
+
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
31
|
+
#
|
|
32
|
+
|
|
33
|
+
from playwright.sync_api import expect, sync_playwright
|
|
34
|
+
import requests
|
|
35
|
+
import re
|
|
36
|
+
|
|
37
|
+
# This class provides the basic functionality for authentication and API calls, but does not implement any specific API calls.
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class Odyssee(object):
|
|
41
|
+
def __init__(self):
|
|
42
|
+
"""
|
|
43
|
+
Initialize the Odyssee class.
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
self.base_url = "https://odyssee.enseignementsup-recherche.gouv.fr/gateway/"
|
|
47
|
+
self.s = requests.session()
|
|
48
|
+
self.headers = None
|
|
49
|
+
self.cookies = None
|
|
50
|
+
|
|
51
|
+
def authenticate(self, username, password):
|
|
52
|
+
playwright = sync_playwright().start()
|
|
53
|
+
|
|
54
|
+
browser = playwright.chromium.launch()
|
|
55
|
+
page = browser.new_page()
|
|
56
|
+
|
|
57
|
+
def log_response(response):
|
|
58
|
+
if response.status == 200:
|
|
59
|
+
if re.search(r"account/?$", response.url):
|
|
60
|
+
self.headers = {"Authorization": f"{response.request.headers['authorization']}"}
|
|
61
|
+
|
|
62
|
+
page.on("response", log_response)
|
|
63
|
+
|
|
64
|
+
page.goto("https://odyssee.enseignementsup-recherche.gouv.fr/accueil/")
|
|
65
|
+
expect(page).to_have_title(re.compile("Me connecter"))
|
|
66
|
+
|
|
67
|
+
# fill is username and password
|
|
68
|
+
page.fill('input[name="username"]', username)
|
|
69
|
+
page.fill('input[name="password"]', password)
|
|
70
|
+
|
|
71
|
+
# click the submit button
|
|
72
|
+
page.click('button[type="submit"]')
|
|
73
|
+
expect(page).to_have_title(re.compile("Bienvenue"))
|
|
74
|
+
|
|
75
|
+
# get the cookies
|
|
76
|
+
self.cookies = {cookie["name"]: cookie["value"] for cookie in page.context.cookies()}
|
|
77
|
+
|
|
78
|
+
browser.close()
|
|
79
|
+
playwright.stop()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
#
|
|
3
|
-
#
|
|
3
|
+
# OdysseeCOS.py -
|
|
4
4
|
#
|
|
5
5
|
# Authors:
|
|
6
6
|
# Géry Casiez https://gery.casiez.net
|
|
@@ -30,24 +30,19 @@
|
|
|
30
30
|
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
31
31
|
#
|
|
32
32
|
|
|
33
|
-
import
|
|
34
|
-
import browsercookie
|
|
33
|
+
from .Odyssee import Odyssee
|
|
35
34
|
import json
|
|
36
35
|
import tqdm
|
|
37
36
|
import os
|
|
38
37
|
|
|
39
|
-
class Odyssee
|
|
40
|
-
def __init__(self, numposte,
|
|
38
|
+
class OdysseeCOS(Odyssee):
|
|
39
|
+
def __init__(self, numposte, use_cache=True):
|
|
41
40
|
"""Initialize the Odyssee class.
|
|
42
41
|
numposte: the numposte to use for the API calls
|
|
43
|
-
bearer_token: the bearer token to use for the API calls
|
|
44
42
|
use_cache: whether to use caching for API responses (default: True)"""
|
|
45
43
|
|
|
44
|
+
super().__init__()
|
|
46
45
|
self.numposte = numposte
|
|
47
|
-
self.base_url = "https://odyssee.enseignementsup-recherche.gouv.fr/gateway/"
|
|
48
|
-
self.s = requests.session()
|
|
49
|
-
self.headers = {"Authorization": f"Bearer {bearer_token}"}
|
|
50
|
-
self.cookies = browsercookie.chrome()
|
|
51
46
|
self.candidatures = None
|
|
52
47
|
self.rapporteurs = None
|
|
53
48
|
self.etablissements = None
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: odysseeapi
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 1.0.0
|
|
4
4
|
Summary: Unofficial Python API for Odyssee
|
|
5
5
|
Author-email: Géry Casiez <gery.casiez@univ-lille.fr>
|
|
6
6
|
Project-URL: Repository, https://github.com/casiez/OdysseeAPI
|
|
@@ -17,7 +17,7 @@ Provides an unofficial API for the [Odyssee platform](https://odyssee.enseigneme
|
|
|
17
17
|
|
|
18
18
|
## Features
|
|
19
19
|
|
|
20
|
-
- download applications of candidates
|
|
20
|
+
- download applications of candidates as zip files
|
|
21
21
|
- get information about candidates
|
|
22
22
|
- get information about committee members
|
|
23
23
|
- get information about institutions
|
|
@@ -32,34 +32,21 @@ Provides an unofficial API for the [Odyssee platform](https://odyssee.enseigneme
|
|
|
32
32
|
pip install odysseeapi
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
-
## Getting the authentication token
|
|
36
|
-
1. Go to the [Odyssee platform](https://odyssee.enseignementsup-recherche.gouv.fr/) using Chrome
|
|
37
|
-
1. Open the developer tools (F12 or right-click and select "Inspect")
|
|
38
|
-
1. Go to the "Network" tab
|
|
39
|
-
1. Refresh the page
|
|
40
|
-
1. Look for a request
|
|
41
|
-
- Click on the request and go to the "Headers" tab
|
|
42
|
-
- Look for the "Authorization" header and copy its value (it should start with "Bearer")
|
|
43
|
-
1. Copy the token and use it in your code to authenticate with the API
|
|
44
|
-
|
|
45
|
-
Note that the authentication uses both cookies and a bearer token, so you need to provide both to access the API.
|
|
46
|
-
The API automatically handles the cookie (using [browsercookie](https://pypi.org/project/browsercookie/)), so you only need to provide the bearer token.
|
|
47
|
-
|
|
48
|
-
Note that the token is valid for a limited time, so you may need to repeat this process periodically to obtain a new token.
|
|
49
|
-
|
|
50
|
-

|
|
51
|
-
|
|
52
35
|
## Minimal example
|
|
53
36
|
|
|
54
37
|
```python
|
|
55
|
-
from odysseeapi.
|
|
38
|
+
from odysseeapi.OdysseeCOS import OdysseeCOS
|
|
56
39
|
|
|
57
40
|
numposte = "123456"
|
|
58
|
-
|
|
41
|
+
username = "xyz"
|
|
42
|
+
password = "abc"
|
|
59
43
|
|
|
60
|
-
# Initialize the API client with the numposte
|
|
44
|
+
# Initialize the API client with the numposte and use_cache set to True
|
|
61
45
|
# setting use_cache to False forces the API client to fetch fresh data from the server for each request, while setting it to True allows the client to use cached data if available
|
|
62
|
-
odyssee =
|
|
46
|
+
odyssee = OdysseeCOS(numposte, True)
|
|
47
|
+
|
|
48
|
+
# The following line is used to authenticate the user and obtain the necessary cookies and bearer token for subsequent API calls. It is optional when using the cached data
|
|
49
|
+
odyssee.authenticate(username, password)
|
|
63
50
|
|
|
64
51
|
# Download the applications of the candidates in the specified directory
|
|
65
52
|
odyssee.download_applications('dossiers_candidats')
|
|
@@ -79,11 +66,11 @@ print(keywords)
|
|
|
79
66
|
candidates_with_details = odyssee.get_candidates_with_details()
|
|
80
67
|
print(candidates_with_details)
|
|
81
68
|
|
|
82
|
-
# odyssee.assign_jury_members_to_candidate("f1e2d3c4-b5a6-4789-9876-543210fedcba", "
|
|
69
|
+
# odyssee.assign_jury_members_to_candidate("f1e2d3c4-b5a6-4789-9876-543210fedcba", "123456", "78910")
|
|
83
70
|
|
|
84
71
|
# Download the reports of the committee members for the candidates in the specified directory
|
|
85
|
-
odyssee.downloadReports("
|
|
72
|
+
# odyssee.downloadReports("rapportsOdyssee")
|
|
86
73
|
|
|
87
|
-
#
|
|
74
|
+
# At the end of the first jury meeting, record the opinion for each candidate and the results of the vote
|
|
88
75
|
# odyssee.opinion_for_interview("f1e2d3c4-b5a6-4789-9876-543210fedcba", "A", "Motif audition", 16, 16, 0, 0, 16, 0)
|
|
89
76
|
```
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
[build-system]
|
|
2
|
-
requires = ["setuptools >= 61.0", "requests", "
|
|
2
|
+
requires = ["setuptools >= 61.0", "requests", "playwright", "tqdm"]
|
|
3
3
|
build-backend = "setuptools.build_meta"
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "odysseeapi"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "1.0.0"
|
|
8
8
|
authors = [
|
|
9
9
|
{name = "Géry Casiez", email = "gery.casiez@univ-lille.fr"},
|
|
10
10
|
]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|