{"id":40704477,"url":"https://github.com/dssg/results-schema","last_synced_at":"2026-01-21T12:09:33.787Z","repository":{"id":57461618,"uuid":"90908228","full_name":"dssg/results-schema","owner":"dssg","description":"Store results of modeling runs in a relational database","archived":false,"fork":false,"pushed_at":"2018-02-12T23:01:30.000Z","size":28,"stargazers_count":1,"open_issues_count":1,"forks_count":2,"subscribers_count":13,"default_branch":"master","last_synced_at":"2025-09-29T11:13:17.447Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dssg.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-05-10T21:04:47.000Z","updated_at":"2017-11-17T18:01:45.000Z","dependencies_parsed_at":"2022-09-17T08:00:22.644Z","dependency_job_id":null,"html_url":"https://github.com/dssg/results-schema","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/dssg/results-schema","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dssg%2Fresults-schema","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dssg%2Fresults-schema/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dssg%2Fresults-schema/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dssg%2Fresults-schema/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dssg","download_url":"https://codeload.github.com/dssg/results-schema/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dssg%2Fresults-schema/sbom","scorecard":{"id":358026,"data":{"date":"2025-08-11","repo":{"name":"github.com/dssg/results-schema","commit":"d447f919e0723a69ed3fd95a879f97842f2b5845"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2.3,"checks":[{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":0,"reason":"Found 1/28 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":9,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Warn: project license file does not contain an FSF or OSI license."],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'","Warn: branch protection not enabled for branch 'fix_setup_py'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":5,"reason":"5 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: PYSEC-2021-142 / GHSA-8q59-q68h-6hv4","Warn: Project is vulnerable to: PYSEC-2018-49 / GHSA-rprw-h62v-c2w7","Warn: Project is vulnerable to: PYSEC-2019-124 / GHSA-38fc-9xqv-7f7q","Warn: Project is vulnerable to: PYSEC-2019-123 / GHSA-887w-45rq-vxgf","Warn: Project is vulnerable to: PYSEC-2012-9 / GHSA-hfg2-wf6j-x53p"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 9 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-18T10:06:08.623Z","repository_id":57461618,"created_at":"2025-08-18T10:06:08.623Z","updated_at":"2025-08-18T10:06:08.623Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28632782,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-21T04:47:28.174Z","status":"ssl_error","status_checked_at":"2026-01-21T04:47:22.943Z","response_time":86,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-01-21T12:09:32.981Z","updated_at":"2026-01-21T12:09:33.782Z","avatar_url":"https://github.com/dssg.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# results-schema\nStore results of modeling runs in a relational database\n\n**Note**: Results-schema is now a bundled component of [Triage](https://github.com/dssg/triage), and future development will take place there. To utilize results-schema within your custom pipeline, you may still import it from there.\n\n## Quick Start\n\n1. Install\n\n`pip install git+https://github.com/dssg/results-schema.git`\n\n2. Create a YAML file with your database credentials (see example_db_config.yaml), or an environment variable 'DBURL' with a connection string. The database must be created already.\n\n3. Call 'upgrade_db' function from Python console or script\n\n```\n\u003e\u003e\u003e from results_schema import upgrade_db\n\u003e\u003e\u003e upgrade_db('my_db_config.yaml')\n```\n\nThis command will create a 'results' schema and the necessary tables.\n\n\n## Modifying the schema\n\n[Alembic](http://alembic.zzzcomputing.com/en/latest/tutorial.html) is a schema migrations library written in Python. It allows us to auto-generate migrations to run incremental database schema changes, such as adding or removing a column. This is done by comparing the definition of a schema in code with that of a live database. There are many valid ways to create migrations, which you can read about in [Alembic's documentation](http://alembic.zzzcomputing.com/en/latest/tutorial.html). But here is a common workflow we will use to modify the schema.\n\n1. Have a candidate database for comparison. You can use a toy database for this that you upgrade to the current master, or use your project database if the results schema has not been manually modified.\n\n2. Make the desired modifications to [results_schema.schema](results_schema/schema.py).\n\n3. Autogenerate a migration: `alembic -c results_schema/alembic.ini -x db_config_file=my_db_config.yaml revision --autogenerate` - This will look at the difference between your schema definition and the database, and generate a new file in results_schema/alembic/versions/.\n\n4. Inspect the file generated in step 3 and make sure that the changes it is suggesting make sense. Make any modifications you want; the autogenerate functionality is just meant as a guideline.\n\n5. Upgrade the database: `alembic -c results_schema/alembic.ini -x db_config_file=my_db_config.yaml upgrade head` \n\n6. Update the [factories file](results_schema/factories/__init__.py) with your changes - see more on factories below if you are unfamiliar with them.\n\n7. If everything looks good, create a pull request!\n\n\n## Using Factories\n\nWhen you want to create rows of these results tables for a unit test, you can use the included factories to make this easier and with less boilerplate.  Factories allow you to only specify the attribute that are important to your test, and choose reasonable defaults for all other attributes. results_schema uses [FactoryBoy](http://factoryboy.readthedocs.io/en/latest/index.html) to accomplish this.\n\nA simple example is to just instantiate an `EvaluationFactory`. `Evaluations` depend on `Models`, which depend on both `ModelGroups` and `Experiments`. So instantiating an `EvaluationFactory` actually creates four objects in the database.\n\n```\nfrom results_schema.factories import EvaluationFactory, session\n\ninit_engine(engine)\nEvaluationFactory()\nsession.commit()\n\nresults = engine.execute('select model_id, metric, parameter, value from results.evaluations')\nfor row in results:\n\tprint(row)\n```\n\n```\n(1, 'precision@', '100_abs', Decimal('0.76'))\n```\n\nThis is all well and good, but often your tests will require some more control over the relationships between the objects you create, like creating different evaluations keyed to the same model. You do this by instantiating a `ModelFactory` first and then passing that to each `EvaluationFactory`:\n\n```\ninit_engine(engine)\n\nmodel = ModelFactory()\nfor metric, value in [\n\t('precision@', 0.4),\n\t('recall@', 0.3),\n]:\n\tEvaluationFactory(\n\t\tmodel_rel=model,\n\t\tmetric=metric,\n\t\tparameter='100_abs',\n\t\tvalue=value\n\t)\nsession.commit()\nresults = engine.execute('select model_id, metric, parameter, value from results.evaluations')\nfor row in results:\n\tprint(row)\n```\n\n```\n(1, 'precision@', '100_abs', Decimal('0.4'))\n(1, 'recall@', '100_abs', Decimal('0.3'))\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdssg%2Fresults-schema","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdssg%2Fresults-schema","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdssg%2Fresults-schema/lists"}