Compare commits

..
Author SHA1 Message Date
LiudengZhang 76a39fcf92 fix: correct opacity prop typo and style object in centroid labels (#2767) 2026-03-09 13:39:56 -07:00
rwbaber 5eb3021752 fix: Handle non-categorical columns with colors + update deprecated AnnData API (#2758)
Yeah that makes sense! Mergingg
2026-02-24 13:37:57 -08:00
Timmy HuangandClaude Opus 4.5 7c7203bdfe chore: replace deprecated codecov with GitHub Action (#2747)
Migrate from the deprecated codecov npm package and bash uploader to the
official codecov/codecov-action@v5. This fixes gcov errors on macOS runners
and provides better reliability for coverage uploads.

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 09:28:12 -08:00
rwbaber 5ac256fc8b fix: remove incompatible float16 fixture from general adaptor tests (#2746)
* test: remove incompatible float16 fixture from generic adaptor tests

* test: remove obsolete error test file for float16
2026-01-15 15:18:45 -08:00
2b86f8e600 fix: improve anndata error msg (#2743)
* feat: improve error message for anndata version mismatches

* fix: Remove mentioning of python update and only mention upgrading anndata

* Update server/data_anndata/anndata_adaptor.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Timmy Huang <tihuan@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-14 09:22:22 -08:00
Timmy Huang 0fddcd042a docs: Add open source required docs (#2745) 2026-01-14 09:13:54 -08:00
Justin Kiggins eb1dc8944f Update README.md (#2725)
CodeQL Scan / Analyze (javascript) (push) Has been cancelled
CodeQL Scan / Analyze (python) (push) Has been cancelled
Compatibility Tests / docker-build (push) Has been cancelled
Compatibility Tests / cxg:latest os: py:3.12 anndata:==0.10.9 (push) Has been cancelled
Compatibility Tests / cxg:latest os:macos-13 py:3.10 anndata:latest (push) Has been cancelled
Compatibility Tests / cxg:latest os:macos-13 py:3.11 anndata:latest (push) Has been cancelled
Compatibility Tests / cxg:latest os:macos-13 py:3.12 anndata:latest (push) Has been cancelled
Compatibility Tests / cxg:latest os:macos-latest py:3.10 anndata:latest (push) Has been cancelled
Compatibility Tests / cxg:latest os:macos-latest py:3.11 anndata:latest (push) Has been cancelled
Compatibility Tests / cxg:latest os:macos-latest py:3.12 anndata:latest (push) Has been cancelled
Compatibility Tests / cxg:latest os:ubuntu-latest py:3.10 anndata:latest (push) Has been cancelled
Compatibility Tests / cxg:latest os:ubuntu-latest py:3.11 anndata:latest (push) Has been cancelled
Compatibility Tests / cxg:latest os:ubuntu-latest py:3.12 anndata:latest (push) Has been cancelled
Compatibility Tests / cxg:main os:macos-13 py:3.10 anndata:latest (push) Has been cancelled
Compatibility Tests / cxg:main os:macos-13 py:3.11 anndata:latest (push) Has been cancelled
Compatibility Tests / cxg:main os:macos-13 py:3.12 anndata:latest (push) Has been cancelled
Compatibility Tests / cxg:main os:macos-latest py:3.10 anndata:latest (push) Has been cancelled
Compatibility Tests / cxg:main os:macos-latest py:3.11 anndata:latest (push) Has been cancelled
Compatibility Tests / cxg:main os:macos-latest py:3.12 anndata:latest (push) Has been cancelled
Compatibility Tests / cxg:main os:ubuntu-latest py:3.10 anndata:latest (push) Has been cancelled
Compatibility Tests / cxg:main os:ubuntu-latest py:3.11 anndata:latest (push) Has been cancelled
Compatibility Tests / cxg:main os:ubuntu-latest py:3.12 anndata:latest (push) Has been cancelled
Close inactive pull requests / close-issues (push) Has been cancelled
Trademark
2025-05-14 12:03:19 -07:00
15 changed files with 59 additions and 245 deletions
+1 -1
View File
@@ -12,7 +12,7 @@ jobs:
main:
runs-on: ubuntu-latest
steps:
- uses: amannn/action-semantic-pull-request@40166f00814508ec3201fc8595b393d451c8cd80@v3.4.1
- uses: amannn/action-semantic-pull-request@v3.4.1
with:
validateSingleCommit: true
env:
+16 -7
View File
@@ -69,10 +69,21 @@ jobs:
- name: Install dependencies
run: make pydist install-dist dev-env-server
- name: Unit tests
run: |
make unit-test-server unit-test-client
bash <(curl -s https://codecov.io/bash) -y .codecov.yml -k server -cF server,python,unitTest
cd client && ./node_modules/codecov/bin/codecov --yml=../.codecov.yml --root=../ --gcov-root=../ -C -F frontend,javascript,unitTest
run: make unit-test-server unit-test-client
- name: Generate server coverage XML
run: coverage xml -o server/coverage.xml
- name: Upload server coverage
uses: codecov/codecov-action@v5
with:
flags: server,python,unitTest
files: ./server/coverage.xml
fail_ci_if_error: false
- name: Upload client coverage
uses: codecov/codecov-action@v5
with:
flags: frontend,javascript,unitTest
files: ./client/coverage/lcov.info
fail_ci_if_error: false
smoke-tests:
runs-on: macos-latest
@@ -102,9 +113,7 @@ jobs:
pip install setuptools
make pydist install-dist
- name: Smoke tests (without annotations feature)
run: |
cd client && make smoke-test
./node_modules/codecov/bin/codecov --yml=../.codecov.yml --root=../ --gcov-root=../ -C -F frontend,javascript,smokeTest
run: cd client && make smoke-test
# TODO: reinstate: https://github.com/chanzuckerberg/cellxgene/issues/2544
# smoke-tests-annotations:
+2 -2
View File
@@ -1,6 +1,6 @@
The MIT License (MIT)
# The MIT License (MIT)
Copyright (c) 2017-2023 Chan Zuckerberg Initiative
Copyright (c) 2017-2026 Chan Zuckerberg Initiative
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
+7
View File
@@ -82,6 +82,13 @@ extension could be directly contributed, which would make it available for a wid
See the [CELLxGENE extensions](https://github.com/chanzuckerberg/cellxgene-documentation/blob/main/community-extensions.md) section of our documentation for examples of community use and CELLxGENE extensions.
### Trademarks
CZ CELLXGENE, CZ CELLXGENE DISCOVER, and CZ CELLXGENE ANNOTATE are trademarks of the Chan Zuckerberg Initiative. All rights reserved.
Use, reuse, modification, and re-distribution of the source code in this repository is subject to the terms of the applicable open source [license](LICENSE.txt). However, that license does not grant permission to use the trademarks without separate, express permission from the Chan Zuckerberg Initiative.
### Security
If you believe you have found a security issue, we would appreciate notification. Please send email to <security@chanzuckerberg.com>.
+3
View File
@@ -0,0 +1,3 @@
# Reporting Security Issues
If you believe you have found a security issue, please responsibly disclose by contacting us at [security@chanzuckerberg.com](mailto:security@chanzuckerberg.com).
-192
View File
@@ -71,7 +71,6 @@
"cheerio": "^1.0.0-rc.6",
"clean-css": "^5.1.2",
"clean-webpack-plugin": "^4.0.0-alpha.0",
"codecov": "^3.7.1",
"css-loader": "^5.2.4",
"css-minimizer-webpack-plugin": "^4.0.0",
"eslint": "^7.24.0",
@@ -5371,16 +5370,6 @@
"sprintf-js": "~1.0.2"
}
},
"node_modules/argv": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/argv/-/argv-0.0.2.tgz",
"integrity": "sha512-dEamhpPEwRUBpLNHeuCm/v+g0anFByHahxodVO/BbAarHVBBg2MccCwf9K+o1Pof+2btdnkJelYVUWjW/VrATw==",
"deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.",
"dev": true,
"engines": {
"node": ">=0.6.10"
}
},
"node_modules/aria-query": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz",
@@ -6448,26 +6437,6 @@
"node": ">=0.10.0"
}
},
"node_modules/codecov": {
"version": "3.8.3",
"resolved": "https://registry.npmjs.org/codecov/-/codecov-3.8.3.tgz",
"integrity": "sha512-Y8Hw+V3HgR7V71xWH2vQ9lyS358CbGCldWlJFR0JirqoGtOoas3R3/OclRTvgUYFK29mmJICDPauVKmpqbwhOA==",
"deprecated": "https://about.codecov.io/blog/codecov-uploader-deprecation-plan/",
"dev": true,
"dependencies": {
"argv": "0.0.2",
"ignore-walk": "3.0.4",
"js-yaml": "3.14.1",
"teeny-request": "7.1.1",
"urlgrey": "1.0.0"
},
"bin": {
"codecov": "bin/codecov"
},
"engines": {
"node": ">=4.0"
}
},
"node_modules/collect-v8-coverage": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz",
@@ -9173,21 +9142,6 @@
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
"integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="
},
"node_modules/fast-url-parser": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/fast-url-parser/-/fast-url-parser-1.1.3.tgz",
"integrity": "sha512-5jOCVXADYNuRkKFzNJ0dCCewsZiYo0dz8QNYljkOpFC6r2U4OBmKtvm/Tsuh4w1YYdDqDb31a8TVhBJ2OJKdqQ==",
"dev": true,
"dependencies": {
"punycode": "^1.3.2"
}
},
"node_modules/fast-url-parser/node_modules/punycode": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
"integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==",
"dev": true
},
"node_modules/fastest-levenshtein": {
"version": "1.0.12",
"resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz",
@@ -10251,15 +10205,6 @@
"node": ">= 4"
}
},
"node_modules/ignore-walk": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.4.tgz",
"integrity": "sha512-PY6Ii8o1jMRA1z4F2hRkH/xN59ox43DavKvD3oDpfurRlOJyAHpifIwpbdv1n4jt4ov0jSpw3kQ4GhJnpBL6WQ==",
"dev": true,
"dependencies": {
"minimatch": "^3.0.4"
}
},
"node_modules/import-fresh": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
@@ -16921,15 +16866,6 @@
"node": ">= 0.8"
}
},
"node_modules/stream-events": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz",
"integrity": "sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==",
"dev": true,
"dependencies": {
"stubs": "^3.0.0"
}
},
"node_modules/string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
@@ -17089,12 +17025,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/stubs": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz",
"integrity": "sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==",
"dev": true
},
"node_modules/stylehacks": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.0.tgz",
@@ -17353,22 +17283,6 @@
"node": ">= 6"
}
},
"node_modules/teeny-request": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-7.1.1.tgz",
"integrity": "sha512-iwY6rkW5DDGq8hE2YgNQlKbptYpY5Nn2xecjQiNjOXWbKzPGUfmeUBCSQbbr306d7Z7U2N0TPl+/SwYRfua1Dg==",
"dev": true,
"dependencies": {
"http-proxy-agent": "^4.0.0",
"https-proxy-agent": "^5.0.0",
"node-fetch": "^2.6.1",
"stream-events": "^1.0.5",
"uuid": "^8.0.0"
},
"engines": {
"node": ">=10"
}
},
"node_modules/terminal-link": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz",
@@ -17957,15 +17871,6 @@
"requires-port": "^1.0.0"
}
},
"node_modules/urlgrey": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/urlgrey/-/urlgrey-1.0.0.tgz",
"integrity": "sha512-hJfIzMPJmI9IlLkby8QrsCykQ+SXDeO2W5Q9QTW3QpqZVTx4a/K7p8/5q+/isD8vsbVaFgql/gvAoQCRQ2Cb5w==",
"dev": true,
"dependencies": {
"fast-url-parser": "^1.1.3"
}
},
"node_modules/use": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
@@ -17996,15 +17901,6 @@
"node": ">= 0.4.0"
}
},
"node_modules/uuid": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
"dev": true,
"bin": {
"uuid": "dist/bin/uuid"
}
},
"node_modules/v8-compile-cache": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz",
@@ -22694,12 +22590,6 @@
"sprintf-js": "~1.0.2"
}
},
"argv": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/argv/-/argv-0.0.2.tgz",
"integrity": "sha512-dEamhpPEwRUBpLNHeuCm/v+g0anFByHahxodVO/BbAarHVBBg2MccCwf9K+o1Pof+2btdnkJelYVUWjW/VrATw==",
"dev": true
},
"aria-query": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz",
@@ -23489,19 +23379,6 @@
"integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==",
"dev": true
},
"codecov": {
"version": "3.8.3",
"resolved": "https://registry.npmjs.org/codecov/-/codecov-3.8.3.tgz",
"integrity": "sha512-Y8Hw+V3HgR7V71xWH2vQ9lyS358CbGCldWlJFR0JirqoGtOoas3R3/OclRTvgUYFK29mmJICDPauVKmpqbwhOA==",
"dev": true,
"requires": {
"argv": "0.0.2",
"ignore-walk": "3.0.4",
"js-yaml": "3.14.1",
"teeny-request": "7.1.1",
"urlgrey": "1.0.0"
}
},
"collect-v8-coverage": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz",
@@ -25575,23 +25452,6 @@
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
"integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="
},
"fast-url-parser": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/fast-url-parser/-/fast-url-parser-1.1.3.tgz",
"integrity": "sha512-5jOCVXADYNuRkKFzNJ0dCCewsZiYo0dz8QNYljkOpFC6r2U4OBmKtvm/Tsuh4w1YYdDqDb31a8TVhBJ2OJKdqQ==",
"dev": true,
"requires": {
"punycode": "^1.3.2"
},
"dependencies": {
"punycode": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
"integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==",
"dev": true
}
}
},
"fastest-levenshtein": {
"version": "1.0.12",
"resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz",
@@ -26382,15 +26242,6 @@
"resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
"integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg=="
},
"ignore-walk": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.4.tgz",
"integrity": "sha512-PY6Ii8o1jMRA1z4F2hRkH/xN59ox43DavKvD3oDpfurRlOJyAHpifIwpbdv1n4jt4ov0jSpw3kQ4GhJnpBL6WQ==",
"dev": true,
"requires": {
"minimatch": "^3.0.4"
}
},
"import-fresh": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
@@ -31562,15 +31413,6 @@
"integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
"dev": true
},
"stream-events": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz",
"integrity": "sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==",
"dev": true,
"requires": {
"stubs": "^3.0.0"
}
},
"string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
@@ -31693,12 +31535,6 @@
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
"integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="
},
"stubs": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz",
"integrity": "sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==",
"dev": true
},
"stylehacks": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.0.tgz",
@@ -31896,19 +31732,6 @@
}
}
},
"teeny-request": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-7.1.1.tgz",
"integrity": "sha512-iwY6rkW5DDGq8hE2YgNQlKbptYpY5Nn2xecjQiNjOXWbKzPGUfmeUBCSQbbr306d7Z7U2N0TPl+/SwYRfua1Dg==",
"dev": true,
"requires": {
"http-proxy-agent": "^4.0.0",
"https-proxy-agent": "^5.0.0",
"node-fetch": "^2.6.1",
"stream-events": "^1.0.5",
"uuid": "^8.0.0"
}
},
"terminal-link": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz",
@@ -32347,15 +32170,6 @@
"requires-port": "^1.0.0"
}
},
"urlgrey": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/urlgrey/-/urlgrey-1.0.0.tgz",
"integrity": "sha512-hJfIzMPJmI9IlLkby8QrsCykQ+SXDeO2W5Q9QTW3QpqZVTx4a/K7p8/5q+/isD8vsbVaFgql/gvAoQCRQ2Cb5w==",
"dev": true,
"requires": {
"fast-url-parser": "^1.1.3"
}
},
"use": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
@@ -32380,12 +32194,6 @@
"integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
"dev": true
},
"uuid": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
"dev": true
},
"v8-compile-cache": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz",
-1
View File
@@ -101,7 +101,6 @@
"cheerio": "^1.0.0-rc.6",
"clean-css": "^5.1.2",
"clean-webpack-plugin": "^4.0.0-alpha.0",
"codecov": "^3.7.1",
"css-loader": "^5.2.4",
"css-minimizer-webpack-plugin": "^4.0.0",
"eslint": "^7.24.0",
@@ -150,7 +150,7 @@ class CentroidLabels extends PureComponent {
dilatedValue={dilatedValue}
coords={coords}
inverseTransform={inverseTransform}
opactity={selected ? 1 : deselectOpacity}
opacity={selected ? 1 : deselectOpacity}
colorAccessor={colorAccessor}
displayLabel={displayLabel}
onMouseEnter={this.handleMouseEnter}
@@ -205,7 +205,7 @@ const Label = ({
fontWeight,
fill: "black",
userSelect: "none",
opacity: { opacity },
opacity,
}}
onMouseEnter={(e) => onMouseEnter(e, colorAccessor, label)}
onMouseOut={(e) => onMouseOut(e, colorAccessor, label)}
+4 -4
View File
@@ -128,12 +128,12 @@ def prepare(
raise click.FileError(data, hint="not a valid file or path")
if not set_obs_names == "":
if set_obs_names not in adata.obs_keys():
raise click.UsageError(f"obs {set_obs_names} not found, options are: {adata.obs_keys()}")
if set_obs_names not in list(adata.obs.keys()):
raise click.UsageError(f"obs {set_obs_names} not found, options are: {list(adata.obs.keys())}")
adata.obs_names = adata.obs[set_obs_names]
if not set_var_names == "":
if set_var_names not in adata.var_keys():
raise click.UsageError(f"var {set_var_names} not found, options are: {adata.var_keys()}")
if set_var_names not in list(adata.var.keys()):
raise click.UsageError(f"var {set_var_names} not found, options are: {list(adata.var.keys())}")
adata.var_names = adata.var[set_var_names]
if make_obs_names_unique:
adata.obs.index = make_index_unique(adata.obs.index)
+1 -1
View File
@@ -228,6 +228,6 @@ def convert_anndata_category_colors_to_cxg_category_colors(data):
# create the cellxgene color entry for this category
cxg_colors[category_name] = dict(
zip(data.obs[category_name].cat.categories, [convert_color_to_hex_format(c) for c in data.uns[uns_key]])
zip(data.obs[category_name].astype('category').cat.categories, [convert_color_to_hex_format(c) for c in data.uns[uns_key]])
)
return cxg_colors
+1 -1
View File
@@ -22,7 +22,7 @@ def corpora_get_versions_from_anndata(adata):
"""
# per Corpora AnnData spec, this is a corpora file if the following is true
if "version" not in adata.uns_keys():
if "version" not in list(adata.uns.keys()):
return None
version = adata.uns["version"]
if not isinstance(version, collections.abc.Mapping) or "corpora_schema_version" not in version:
+21 -9
View File
@@ -1,4 +1,5 @@
import warnings
import importlib.metadata
import anndata
import numpy as np
@@ -16,7 +17,7 @@ from server.common.utils.type_conversion_utils import get_schema_type_hint_of_ar
from server.data_common.data_adaptor import DataAdaptor
from server.common.fbs.matrix import encode_matrix_fbs
anndata_version = version.parse(str(anndata.__version__)).release
anndata_version = version.parse(str(importlib.metadata.version('anndata'))).release
def anndata_version_is_pre_070():
@@ -63,7 +64,7 @@ class AnndataAdaptor(DataAdaptor):
return "cellxgene anndata adaptor version"
def get_library_versions(self):
return dict(anndata=str(anndata.__version__))
return dict(anndata=str(importlib.metadata.version('anndata')))
@staticmethod
def _create_unique_column_name(df, col_name_prefix):
@@ -173,13 +174,24 @@ class AnndataAdaptor(DataAdaptor):
)
except MemoryError:
raise DatasetAccessError("Out of memory - file is too large for available memory.")
except Exception:
except Exception as e:
import traceback
error_msg = str(e)
# IMPROVEMENT: Broadly catch ANY version incompatibility
if "No read method registered" in error_msg and "IOSpec" in error_msg:
message = (
"Error loading file: This H5AD file uses a newer internal format that "
"your version of 'anndata' cannot read.\n"
f"The specific error was: {error_msg}\n"
"Please upgrade anndata in your environment (pip install --upgrade anndata)."
)
else:
message = (
"File not found or is inaccessible. File must be an .h5ad object. "
"Please check your input and try again."
)
message = (
"File not found or is inaccessible. File must be an .h5ad object. "
"Please check your input and try again."
)
if self.server_config.app__verbose:
message += f"\n{traceback.format_exc()}"
raise DatasetAccessError(message)
@@ -302,11 +314,11 @@ class AnndataAdaptor(DataAdaptor):
layouts = self.dataset_config.embeddings__names
if layouts is None or len(layouts) == 0:
layouts = [key[2:] for key in self.data.obsm_keys() if type(key) is str and key.startswith("X_")]
layouts = [key[2:] for key in list(self.data.obsm.keys()) if type(key) is str and key.startswith("X_")]
# remove invalid layouts
valid_layouts = []
obsm_keys = self.data.obsm_keys()
obsm_keys = list(self.data.obsm.keys())
for layout in layouts:
layout_name = f"X_{layout}"
if layout_name not in obsm_keys:
+1 -1
View File
@@ -1,6 +1,6 @@
black
bumpversion>=0.5
codecov>=2.0.15
coverage>=5.0
parameterized>=0.7.0
pytest>=3.6.3
python-jose>=3.2.0
@@ -36,7 +36,6 @@ Test the anndata adaptor using the pbmc3k data set.
(f"{FIXTURES_ROOT}/pbmc3k-CSC-gz.h5ad", True, "normal"),
(f"{FIXTURES_ROOT}/pbmc3k-CSR-gz.h5ad", True, "normal"),
(f"{FIXTURES_ROOT}/pbmc3k_64.h5ad", False, "auto"), # 64 bit conversion tests
(f"{FIXTURES_ROOT}/pbmc3k_16.h5ad", False, "auto"), # 16 bit conversion tests
],
)
class AdaptorTest(unittest.TestCase):
@@ -1,23 +0,0 @@
import unittest
from parameterized import parameterized_class
from server.common.errors import DatasetAccessError
from test import FIXTURES_ROOT
from test.unit import app_config
@parameterized_class(
("data_locator", "backed", "X_approximate_distribution"),
[
(f"{FIXTURES_ROOT}/pbmc3k_16.h5ad", True, "auto"), # 16 bit conversion tests
],
)
class AdaptorLoadErrorTest(unittest.TestCase):
def test_float16_backed_raises_err(self):
with self.assertRaises(DatasetAccessError):
config = app_config(
self.data_locator,
backed=self.backed,
extra_dataset_config=dict(X_approximate_distribution=self.X_approximate_distribution),
)