rsfc 0.0.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.
rsfc-0.0.1/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Andrés Montero
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.
rsfc-0.0.1/PKG-INFO ADDED
@@ -0,0 +1,197 @@
1
+ Metadata-Version: 2.3
2
+ Name: rsfc
3
+ Version: 0.0.1
4
+ Summary: EVERSE Research Software Fairness Checks
5
+ License: MIT
6
+ Author: Andres Montero
7
+ Author-email: andres.montero.martin@upm.es
8
+ Requires-Python: >=3.10,<=3.13
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.10
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Programming Language :: Python :: 3.13
15
+ Requires-Dist: anyascii (==0.3.2)
16
+ Requires-Dist: attrs (==25.3.0)
17
+ Requires-Dist: beautifulsoup4 (==4.13.4)
18
+ Requires-Dist: bibtexparser (==1.4.3)
19
+ Requires-Dist: bs4 (==0.0.1)
20
+ Requires-Dist: build (==1.2.2.post1)
21
+ Requires-Dist: certifi (==2025.6.15)
22
+ Requires-Dist: chardet (==5.2.0)
23
+ Requires-Dist: charset-normalizer (==3.4.2)
24
+ Requires-Dist: click (==8.2.1)
25
+ Requires-Dist: click-option-group (==0.5.7)
26
+ Requires-Dist: contourpy (==1.3.2)
27
+ Requires-Dist: contractions (==0.1.73)
28
+ Requires-Dist: cycler (==0.12.1)
29
+ Requires-Dist: duckdb (==1.3.1)
30
+ Requires-Dist: elementpath (==4.8.0)
31
+ Requires-Dist: falcon (==3.1.3)
32
+ Requires-Dist: fastjsonschema (==2.21.1)
33
+ Requires-Dist: fonttools (==4.58.4)
34
+ Requires-Dist: idna (==3.10)
35
+ Requires-Dist: imbalanced-learn (==0.11.0)
36
+ Requires-Dist: inflect (==7.5.0)
37
+ Requires-Dist: iniconfig (==2.1.0)
38
+ Requires-Dist: jinja2 (==3.1.6)
39
+ Requires-Dist: joblib (==1.5.1)
40
+ Requires-Dist: jsonpath-python (==1.0.6)
41
+ Requires-Dist: jsonschema (==4.24.0)
42
+ Requires-Dist: jsonschema-specifications (==2025.4.1)
43
+ Requires-Dist: jupyter-core (==5.8.1)
44
+ Requires-Dist: kiwisolver (==1.4.8)
45
+ Requires-Dist: lxml (==5.4.0)
46
+ Requires-Dist: markdown (==3.8.1)
47
+ Requires-Dist: markupsafe (==3.0.2)
48
+ Requires-Dist: matplotlib (==3.10.3)
49
+ Requires-Dist: more-itertools (==10.7.0)
50
+ Requires-Dist: morph-kgc (==2.8.1)
51
+ Requires-Dist: nbformat (==5.10.4)
52
+ Requires-Dist: nltk (==3.9.1)
53
+ Requires-Dist: numpy (==1.26.4)
54
+ Requires-Dist: packaging (==25.0)
55
+ Requires-Dist: pandas (==2.3.0)
56
+ Requires-Dist: pillow (==11.2.1)
57
+ Requires-Dist: platformdirs (==4.3.8)
58
+ Requires-Dist: pluggy (==1.6.0)
59
+ Requires-Dist: pyahocorasick (==2.2.0)
60
+ Requires-Dist: pyoxigraph (==0.3.22)
61
+ Requires-Dist: pyparsing (==3.2.3)
62
+ Requires-Dist: pyproject-hooks (==1.2.0)
63
+ Requires-Dist: pystache (>=0.6.8,<0.7.0)
64
+ Requires-Dist: pytest (==7.4.4)
65
+ Requires-Dist: python-dateutil (==2.9.0.post0)
66
+ Requires-Dist: pytz (==2025.2)
67
+ Requires-Dist: pyyaml (==6.0.2)
68
+ Requires-Dist: rdflib (==7.1.4)
69
+ Requires-Dist: rdflib-jsonld (==0.6.2)
70
+ Requires-Dist: referencing (==0.36.2)
71
+ Requires-Dist: regex (==2024.11.6)
72
+ Requires-Dist: requests (==2.32.4)
73
+ Requires-Dist: rpds-py (==0.25.1)
74
+ Requires-Dist: ruamel-yaml (==0.18.14)
75
+ Requires-Dist: ruamel-yaml-clib (==0.2.12)
76
+ Requires-Dist: scikit-learn (==1.3.2)
77
+ Requires-Dist: scipy (==1.15.3)
78
+ Requires-Dist: six (==1.17.0)
79
+ Requires-Dist: somef (==0.9.11)
80
+ Requires-Dist: soupsieve (==2.7)
81
+ Requires-Dist: textblob (==0.17.1)
82
+ Requires-Dist: textsearch (==0.0.24)
83
+ Requires-Dist: threadpoolctl (==3.6.0)
84
+ Requires-Dist: toml (==0.10.2)
85
+ Requires-Dist: tomli (==2.2.1)
86
+ Requires-Dist: tqdm (==4.67.1)
87
+ Requires-Dist: traitlets (==5.14.3)
88
+ Requires-Dist: typeguard (==4.4.4)
89
+ Requires-Dist: typing-extensions (==4.14.0)
90
+ Requires-Dist: tzdata (==2025.2)
91
+ Requires-Dist: urllib3 (==2.5.0)
92
+ Requires-Dist: validators (==0.22.0)
93
+ Requires-Dist: xgboost (==2.1.4)
94
+ Project-URL: Homepage, https://github.com/oeg-upm/rsfc
95
+ Description-Content-Type: text/markdown
96
+
97
+ # Research Software Fairness Checks (RSFC)
98
+
99
+ A command line interface to automatically evaluate the quality of a Github or Gitlab repository.
100
+
101
+ **Authors**: Daniel Garijo, Andrés Montero
102
+
103
+
104
+ ## Features
105
+
106
+ Given a repository URL, RSFC will perform a series of checks based on a list of research software quality indicators (RSQI). The RSQIs currently covered by the package are:
107
+
108
+ - software_has_license
109
+ - software_has_citation
110
+ - has_releases
111
+ - repository_workflows
112
+ - version_control_use
113
+ - requirements_specified
114
+ - software_documentation
115
+ - persistent_and_unique_identifier
116
+ - descriptive_metadata
117
+
118
+ For more information about these RSQIs, you can check https://github.com/EVERSE-ResearchSoftware/indicators. We have plans to implement all of the RSQIs available in that repository.
119
+
120
+
121
+ ## Requirements
122
+
123
+ Python 3.10.8 or higher
124
+
125
+ Dependencies are available in the requirements.txt or pyproject.toml file located in the root of the repository
126
+
127
+ ## Install from Github with Poetry
128
+
129
+ To install the package, first clone the repository in your machine.
130
+ This project uses Poetry for dependency and environment management.
131
+
132
+ ```
133
+ git clone https://github.com/oeg-upm/rsfc.git
134
+ ```
135
+
136
+ Go to the project's root directory
137
+
138
+ ```
139
+ cd rsfc
140
+ ```
141
+
142
+ Install Poetry (if you haven’t already)
143
+
144
+ ```
145
+ curl -sSL https://install.python-poetry.org | python3 -
146
+ ```
147
+
148
+ Make sure Poetry is available in your PATH
149
+
150
+ ```
151
+ poetry --version
152
+ ```
153
+
154
+ Create the virtual environment and install dependencies
155
+
156
+ ```
157
+ poetry install
158
+ ```
159
+
160
+ Activate the virtual environment (Optional)
161
+
162
+ ```
163
+ source $(poetry env info --path)/bin/activate
164
+ ```
165
+
166
+ Your terminal prompt should now show something like:
167
+
168
+ ```
169
+ (rsfc-py3.11) your-user@your-machine rsfc %
170
+ ```
171
+
172
+ With virtual environment activated you can tried like this:
173
+
174
+ ```
175
+ rsfc --help
176
+ ```
177
+
178
+ Without poetry virtual environment activated you need to use the poetry run:
179
+
180
+ ```
181
+ poetry run rsfc --help
182
+ ```
183
+
184
+ ## Usage
185
+
186
+ After installation, you can use the package by running if you activated the poetry env
187
+
188
+ ```
189
+ rsfc <repo_url>
190
+ ```
191
+
192
+ or like this without the poetry env
193
+
194
+ ```
195
+ poetry ruyn rsfc <repo_url>
196
+ ```
197
+
rsfc-0.0.1/README.md ADDED
@@ -0,0 +1,100 @@
1
+ # Research Software Fairness Checks (RSFC)
2
+
3
+ A command line interface to automatically evaluate the quality of a Github or Gitlab repository.
4
+
5
+ **Authors**: Daniel Garijo, Andrés Montero
6
+
7
+
8
+ ## Features
9
+
10
+ Given a repository URL, RSFC will perform a series of checks based on a list of research software quality indicators (RSQI). The RSQIs currently covered by the package are:
11
+
12
+ - software_has_license
13
+ - software_has_citation
14
+ - has_releases
15
+ - repository_workflows
16
+ - version_control_use
17
+ - requirements_specified
18
+ - software_documentation
19
+ - persistent_and_unique_identifier
20
+ - descriptive_metadata
21
+
22
+ For more information about these RSQIs, you can check https://github.com/EVERSE-ResearchSoftware/indicators. We have plans to implement all of the RSQIs available in that repository.
23
+
24
+
25
+ ## Requirements
26
+
27
+ Python 3.10.8 or higher
28
+
29
+ Dependencies are available in the requirements.txt or pyproject.toml file located in the root of the repository
30
+
31
+ ## Install from Github with Poetry
32
+
33
+ To install the package, first clone the repository in your machine.
34
+ This project uses Poetry for dependency and environment management.
35
+
36
+ ```
37
+ git clone https://github.com/oeg-upm/rsfc.git
38
+ ```
39
+
40
+ Go to the project's root directory
41
+
42
+ ```
43
+ cd rsfc
44
+ ```
45
+
46
+ Install Poetry (if you haven’t already)
47
+
48
+ ```
49
+ curl -sSL https://install.python-poetry.org | python3 -
50
+ ```
51
+
52
+ Make sure Poetry is available in your PATH
53
+
54
+ ```
55
+ poetry --version
56
+ ```
57
+
58
+ Create the virtual environment and install dependencies
59
+
60
+ ```
61
+ poetry install
62
+ ```
63
+
64
+ Activate the virtual environment (Optional)
65
+
66
+ ```
67
+ source $(poetry env info --path)/bin/activate
68
+ ```
69
+
70
+ Your terminal prompt should now show something like:
71
+
72
+ ```
73
+ (rsfc-py3.11) your-user@your-machine rsfc %
74
+ ```
75
+
76
+ With virtual environment activated you can tried like this:
77
+
78
+ ```
79
+ rsfc --help
80
+ ```
81
+
82
+ Without poetry virtual environment activated you need to use the poetry run:
83
+
84
+ ```
85
+ poetry run rsfc --help
86
+ ```
87
+
88
+ ## Usage
89
+
90
+ After installation, you can use the package by running if you activated the poetry env
91
+
92
+ ```
93
+ rsfc <repo_url>
94
+ ```
95
+
96
+ or like this without the poetry env
97
+
98
+ ```
99
+ poetry ruyn rsfc <repo_url>
100
+ ```
@@ -0,0 +1,99 @@
1
+ [tool.poetry]
2
+ name = "rsfc"
3
+ version = "0.0.1"
4
+ description = "EVERSE Research Software Fairness Checks"
5
+ authors = ["Andres Montero <andres.montero.martin@upm.es>"]
6
+ license = "MIT"
7
+ readme = "README.md"
8
+ packages = [{ include = "rsfc", from = "src" }]
9
+ homepage = "https://github.com/oeg-upm/rsfc"
10
+
11
+ [tool.poetry.dependencies]
12
+ python = ">=3.10,<=3.13"
13
+ somef = "0.9.11"
14
+ regex = "2024.11.6"
15
+ requests = "2.32.4"
16
+ anyascii = "0.3.2"
17
+ attrs = "25.3.0"
18
+ beautifulsoup4 = "4.13.4"
19
+ bibtexparser = "1.4.3"
20
+ bs4 = "0.0.1"
21
+ build = "1.2.2.post1"
22
+ certifi = "2025.6.15"
23
+ chardet = "5.2.0"
24
+ charset-normalizer = "3.4.2"
25
+ click = "8.2.1"
26
+ click-option-group = "0.5.7"
27
+ contourpy = "1.3.2"
28
+ contractions = "0.1.73"
29
+ cycler = "0.12.1"
30
+ duckdb = "1.3.1"
31
+ elementpath = "4.8.0"
32
+ falcon = "3.1.3"
33
+ fastjsonschema = "2.21.1"
34
+ fonttools = "4.58.4"
35
+ idna = "3.10"
36
+ imbalanced-learn = "0.11.0"
37
+ inflect = "7.5.0"
38
+ iniconfig = "2.1.0"
39
+ jinja2 = "3.1.6"
40
+ joblib = "1.5.1"
41
+ jsonpath-python = "1.0.6"
42
+ jsonschema = "4.24.0"
43
+ jsonschema-specifications = "2025.4.1"
44
+ jupyter-core = "5.8.1"
45
+ kiwisolver = "1.4.8"
46
+ lxml = "5.4.0"
47
+ markdown = "3.8.1"
48
+ markupsafe = "3.0.2"
49
+ matplotlib = "3.10.3"
50
+ more-itertools = "10.7.0"
51
+ morph-kgc = "2.8.1"
52
+ nbformat = "5.10.4"
53
+ nltk = "3.9.1"
54
+ numpy = "1.26.4"
55
+ packaging = "25.0"
56
+ pandas = "2.3.0"
57
+ pillow = "11.2.1"
58
+ platformdirs = "4.3.8"
59
+ pluggy = "1.6.0"
60
+ pyahocorasick = "2.2.0"
61
+ pyoxigraph = "0.3.22"
62
+ pyparsing = "3.2.3"
63
+ pyproject-hooks = "1.2.0"
64
+ pytest = "7.4.4"
65
+ python-dateutil = "2.9.0.post0"
66
+ pytz = "2025.2"
67
+ pyyaml = "6.0.2"
68
+ rdflib = "7.1.4"
69
+ rdflib-jsonld = "0.6.2"
70
+ referencing = "0.36.2"
71
+ rpds-py = "0.25.1"
72
+ ruamel-yaml = "0.18.14"
73
+ ruamel-yaml-clib = "0.2.12"
74
+ scikit-learn = "1.3.2"
75
+ scipy = "1.15.3"
76
+ six = "1.17.0"
77
+ soupsieve = "2.7"
78
+ textblob = "0.17.1"
79
+ textsearch = "0.0.24"
80
+ threadpoolctl = "3.6.0"
81
+ toml = "0.10.2"
82
+ tomli = "2.2.1"
83
+ tqdm = "4.67.1"
84
+ traitlets = "5.14.3"
85
+ typeguard = "4.4.4"
86
+ typing-extensions = "4.14.0"
87
+ tzdata = "2025.2"
88
+ urllib3 = "2.5.0"
89
+ validators = "0.22.0"
90
+ xgboost = "2.1.4"
91
+ pystache = "^0.6.8"
92
+
93
+ [tool.poetry.scripts]
94
+ rsfc = "rsfc.main:main"
95
+
96
+ [build-system]
97
+ requires = ["poetry-core"]
98
+ build-backend = "poetry.core.masonry.api"
99
+
@@ -0,0 +1,3 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ __version__ = "0.0.1"
@@ -0,0 +1,13 @@
1
+ import argparse
2
+
3
+ def main():
4
+ parser = argparse.ArgumentParser(description="RSFC - EVERSE Research Software Fairness Checks")
5
+ parser.add_argument("repo_url", help="URL of the Github repository to be analyzed")
6
+
7
+ args = parser.parse_args()
8
+
9
+ from rsfc.rsfc_core import build_assessment
10
+ build_assessment(args.repo_url)
11
+
12
+ if __name__ == "__main__":
13
+ main()
File without changes
@@ -0,0 +1,117 @@
1
+ import urllib
2
+ from urllib.parse import unquote
3
+ import requests
4
+ from datetime import datetime
5
+
6
+ class AssessedSoftware:
7
+ def __init__(self, repo_url, repo_type):
8
+ self.software_url = repo_url
9
+ base_url = self.get_repo_base_url(repo_url, repo_type)
10
+ self.software_name = self.get_soft_name(unquote(base_url))
11
+ self.software_version = self.get_soft_version(base_url, repo_type)
12
+ self.software_id = None
13
+
14
+
15
+ def get_repo_base_url(self, repo_url, repo_type):
16
+ parsed_url = urllib.parse.urlparse(repo_url)
17
+ path_parts = parsed_url.path.strip("/").split("/")
18
+ if len(path_parts) < 2:
19
+ raise ValueError("Error when getting repository API URL")
20
+
21
+ owner, repo = path_parts[-2], path_parts[-1]
22
+
23
+ if repo_type == 'GITHUB':
24
+ url = f"https://api.github.com/repos/{owner}/{repo}"
25
+ elif repo_type == "GITLAB":
26
+ project_path = urllib.parse.quote(f"{owner}/{repo}", safe="")
27
+ url = f"https://gitlab.com/api/v4/projects/{project_path}"
28
+ else:
29
+ raise ValueError("URL not within supported types (Github and Gitlab)")
30
+
31
+ return url
32
+
33
+ '''def get_base_url(self, repo_url, repo_type):
34
+ parsed_url = urllib.parse.urlparse(repo_url)
35
+ path_parts = parsed_url.path.strip("/").split("/")
36
+ if len(path_parts) < 2:
37
+ raise ValueError("Error when getting Github API URL")
38
+ owner, repo = path_parts[-2], path_parts[-1]
39
+
40
+ url = f"https://api.github.com/repos/{owner}/{repo}"
41
+
42
+ return url'''
43
+
44
+
45
+ def get_soft_name(self, base_url):
46
+ name = base_url.rstrip("/").split("/")[-1]
47
+ return name
48
+
49
+
50
+ def get_soft_version(self, url, repo_type):
51
+ try:
52
+ releases_url = f"{url}/releases"
53
+
54
+ response = requests.get(releases_url)
55
+ response.raise_for_status()
56
+ releases = response.json()
57
+
58
+ latest_release = None
59
+ latest_date = None
60
+
61
+ for release in releases:
62
+ if repo_type == "GITHUB":
63
+ date_str = release.get("published_at")
64
+ tag = release.get("tag_name")
65
+ elif repo_type == "GITLAB":
66
+ date_str = release.get("released_at")
67
+ tag = release.get("tag_name")
68
+ else:
69
+ raise ValueError("Unsupported repository type")
70
+
71
+ if date_str and tag:
72
+ try:
73
+ dt = datetime.fromisoformat(date_str.rstrip("Z"))
74
+ except ValueError:
75
+ continue
76
+
77
+ if latest_release is None or dt > latest_date:
78
+ latest_release = tag
79
+ latest_date = dt
80
+
81
+ return latest_release
82
+
83
+ except Exception as e:
84
+ print(f"Error fetching releases from {repo_type} at {releases_url}: {e}")
85
+ return None
86
+
87
+
88
+
89
+ '''def get_soft_version(self, url):
90
+ try:
91
+ releases_url = f"{url}/releases"
92
+ response = requests.get(releases_url)
93
+ response.raise_for_status()
94
+ releases = response.json()
95
+
96
+ latest_release = None
97
+ latest_date = None
98
+ for release in releases:
99
+ date_str = release.get("published_at")
100
+ tag = release.get("tag_name")
101
+ if date_str and tag:
102
+ try:
103
+ dt = datetime.fromisoformat(date_str.rstrip("Z"))
104
+ except ValueError:
105
+ continue
106
+
107
+ if latest_release is None or dt > latest_date:
108
+ latest_release = tag
109
+ latest_date = dt
110
+
111
+ return latest_release
112
+
113
+ except Exception as e:
114
+ print(f"Error fetching releases from GitHub: {e}")
115
+ return None'''
116
+
117
+
@@ -0,0 +1,28 @@
1
+ from rsfc.utils import constants
2
+
3
+ class Check:
4
+ def __init__(self, indicator_id, process, output, evidence):
5
+ self.checkers_info = constants.CHECKERS_DICT
6
+
7
+ self.indicator_id = indicator_id
8
+ self.process = process
9
+ self.output = output
10
+ self.evidence = evidence
11
+
12
+ def convert(self):
13
+ return {
14
+ "@type": "CheckResult",
15
+ "assessesIndicator": {
16
+ "@id": self.indicator_id
17
+ },
18
+ "checkingSoftware": {
19
+ "@type": "schema:SoftwareApplication",
20
+ "name": self.checkers_info['rsfc']['name'],
21
+ "@id": self.checkers_info['rsfc']['id'],
22
+ "softwareVersion": self.checkers_info['rsfc']['version']
23
+ },
24
+ "process": self.process,
25
+ "status": { "@id": "schema:CompletedActionStatus" },
26
+ "output": self.output,
27
+ "evidence": self.evidence
28
+ }