• Stars
    star
    636
  • Rank 70,723 (Top 2 %)
  • Language
    Ruby
  • License
    MIT License
  • Created over 5 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A set of tools to make the Sorbet typechecker work with Ruby on Rails seamlessly.

Notice

This repository is no longer maintained and will be sunset. The Sorbet community has endorsed the Tapioca gem for generating RBI's, including those for Rails. Please consider migrating over!

sorbet-rails

Gem Version Build Status codecov

A set of tools to make the Sorbet typechecker work with Ruby on Rails seamlessly.

This gem adds a few Rake tasks to generate Ruby Interface (RBI) files for dynamic methods generated by Rails. It also includes signatures for related Rails classes. The RBI files are added to a sorbet/rails-rbi/ folder.

sorbet-rails supports Rails 5+ or later.

Notice: we no longer support Rails 4.2. Version 0.5.6 is the last version supporting Rails 4.2.

Initial Setup

  1. Follow the steps here to set up the latest version of Sorbet, up to being able to run srb tc.

  2. Add sorbet-rails to your Gemfile and install them with Bundler.

# -- Gemfile --
gem 'sorbet-rails'

Add sorbet-rails to the :default group because of "Features Provided at Runtime" below.

❯ bundle install
  1. Generate RBI files for your routes, models, etc
❯ bundle exec rake rails_rbi:routes
❯ bundle exec rake rails_rbi:models
❯ bundle exec rake rails_rbi:helpers
❯ bundle exec rake rails_rbi:mailers
❯ bundle exec rake rails_rbi:jobs
❯ bundle exec rake rails_rbi:custom

# or run them all at once
❯ bundle exec rake rails_rbi:all
  1. Update hidden-definition files and automatically upgrade each file's typecheck level:
❯ bundle exec srb rbi hidden-definitions
❯ bundle exec srb rbi suggest-typed

Because we've generated RBI files for routes, models, and helpers, a lot more files should be typecheckable now. Many methods in hidden.rbi may be removed because they are now typed.

Static RBI Generation

Models

This Rake task generates RBI files for all models in the Rails application (all descendants of ActiveRecord::Base):

❯ bundle exec rake rails_rbi:models

You can also regenerate RBI files for specific models. To accommodate for STI, this will generate rbi for all the subclasses of the models included.

❯ bundle exec rake rails_rbi:models[ModelName,AnotherOne,...]

The generation task currently creates the following signatures:

  • Column getters & setters
  • Associations getters & setters
  • Enum values, checkers & scopes
  • Named scopes
  • Model Relation class

It is possible to add custom RBI generation logic for your custom module or gems via the plugin system. Check out the plugins section below if you are interested.

We also add following methods to make type-checking easier:

pluck_to_tstruct instead of pluck

The pluck method in Rails is a performant way to query value without instantiating ActiveRecord objects. However, it doesn't have any type information: it doesn't have type information (or name) of the attribute plucked. Sorbet-rails provides pluck_to_tstruct method as a replacement that returns an array of T::Struct instead. The attributes plucked is based on props defined in the T::Struct

# -- API
Arel.pluck_to_tstruct(TA[ <TStructSubClass> ].new)

# -- example
class WizardStruct < T::Struct
  const :name, String
  const :house, T.nilable(String)
end

Wizard.pluck_to_tstruct(TA[WizardStruct].new)  # T::Array[WizardStruct]
Wizard.all.pluck_to_tstruct(TA[WizardStruct].new)  # T::Array[WizardStruct]

You can also pass a keyword argument called associations that represents a mapping of a T::Struct's keys to an associated table's columns.

# -- API
Arel.pluck_to_tstruct(TA[ <TStructSubclass> ].new, associations: < Hash<Symbol, String> >)

# -- example
class WizardWithWandStruct < T::Struct
  const :name, String
  const :house, T.nilable(String)
  const :wand_wood_type, String
end

Wizard.joins(:wand).pluck_to_tstruct(
  TA[WizardWithWandStruct].new,
  associations: { wand_wood_type: "wands.wood_type" }
)
Wizard.all.joins(:wand).pluck_to_tstruct(
  TA[WizardWithWandStruct].new,
  associations: { wand_wood_type: "wands.wood_type" }
)

This method is based on pluck_to_hash gem.

typed_enum instead of enum

If you use Rails enum, sorbet-rails will generate a corresponding T::Enum. It will also include getters, setters, and scope methods in the rbi file it generates.

ie.

  enum house: {
    Gryffindor: 0,
    Hufflepuff: 1,
    Ravenclaw: 2,
    Slytherin: 3,
  }

Will generate this enum:

class Wizard
  class House < T::Enum
    enums do
      Gryffindor = new('Gryffindor')
      Hufflepuff = new('Hufflepuff')
      Ravenclaw = new('Ravenclaw')
      Slytherin = new('Slytherin')
    end
  end
end

And these methods:

  sig { returns(T.nilable(String)) }
  def house; end

  sig { params(value: T.nilable(T.any(Integer, String, Symbol))).void }
  def house=(value); end

  sig { returns(T.nilable(Wizard::House)) }
  def typed_house; end

  sig { params(value: T.nilable(Wizard::House)).void }
  def typed_house=(value); end

Alternatively, you can replace your call to enum with typed_enum. This will hide the Rails methods (house) from Sorbet static-check (they are still usable in un-checked files).

  typed_enum house: {
    Gryffindor: 0,
    Hufflepuff: 1,
    Ravenclaw: 2,
    Slytherin: 3,
  }

Generates only typed enum setter & getter:

  sig { returns(T.nilable(Wizard::House)) }
  def typed_house; end

  sig { params(value: T.nilable(Wizard::House)).void }
  def typed_house=(value); end

RelationType alias

There are several kinds of relations of a model: User::ActiveRecord_Relation, User::ActiveRecord_AssociationRelation and User::ActiveRecord_Associations_CollectionProxy. Usually the code may need just any relation type. We add a Model::RelationType type alias for every model to use it.

class User
  RelationType = T.type_alias do
    T.any(
      User::ActiveRecord_Relation,
      User::ActiveRecord_AssociationRelation,
      User::ActiveRecord_Associations_CollectionProxy
    )
  end
end

Controllers

❯ bundle exec  rake rails_rbi:custom

sorbet-rails adds TypedParams to extract typed controller parameters.

TypedParams takes a parameter definition, which is a subclass of T::Struct and coerces the params object into an instance of that subclass using sorbet-coerce:

class MyCoolController < ApplicationController
  class MyActionParams < T::Struct
    const :id, T.nilable(Integer)
    const :show, T.nilable(T::Boolean)
    const :wands, T::Array[Integer]
  end
  sig { void }
  def my_action
    typed_params = TypedParams[MyActionParams].new.extract!(params)
    # T.reveal_type(typed_params) => MyActionParams
    # T.reveal_type(typed_params.show) => T.nilable(T::Boolean)
  end
end

If it fails to coerce the params into the right type, an ActionController::BadRequest exception will be raised with the coercion context for debugging.

Note: The API TypedParams[...].new.extract! may seem verbose, but necessary to support this feature. Ideally, the API can be simply TypedParams.extract!(...). However, sorbet doesn't support defining a method that accept a type and return an instance of the type. If this feature is supported by sorbet in the future, it will be easy to codemod to be TypedParams.extract(...)! part from your code. Note: require_typed and fetch_typed are deprecated in favor of TypedParams. They will be removed in v0.7.

Routes

This Rake task generates an RBI file defining _path and _url methods for all named routes in routes.rb:

❯ bundle exec rake rails_rbi:routes

Helpers

This Rake task generates a helpers.rbi file that includes a basic module definition which includes the Kernel module and ActionView::Helpers, to allow for some basic Ruby methods to be used in helpers without Sorbet complaining.

❯ bundle exec rake rails_rbi:helpers

If you have additional modules that are included in all your helpers and you want helpers.rbi to reflect this, you can configure it:

# -- config/initializers/sorbet_rails.rb
SorbetRails.configure do |config|
  config.extra_helper_includes = ['ApplicationHelper', 'Devise::Controllers::Helpers']
end

Mailers

This Rake task generates RBI files for all mailer classes in the Rails application (all descendants of ActionMailer::Base)

❯ bundle exec rake rails_rbi:mailers

Since mailing action methods are based on instance methods defined in a mailer class, the signature of a mailing action method will be dependent on the signature the instance method has

  • If there is a (sorbet) sig written for the instance method, it generates a matching sig for the mailing action method
  • If not, all the params in the mailing action method will be T.untyped.
  • For return type though, the mailing action method will return ActionMailer::MessageDelivery instead of the return type of the instance method.

Jobs

This Rake task generates RBI files for all jobs classes in the Rails application (all descendants of ActiveJob::Base).

❯ bundle exec rake rails_rbi:jobs

It will generate perform_later and perform_now methods for the job classes matching the signature of the perform method of the job. If there is a (sorbet) sig written for perform, it will use the same sig for perform_* methods.

Runtime Features

In addition to features provided by the static generator, sorbet-rails can provide additional features when required. This is why the installation instructions specify that sorbet-rails should be placed in the :default group of the Gemfile, not a specific environment group (eg. development only).

  • Model: The gem provides some helper method to a model to make type-checking easier:

    • find_n, first_n, last_n
    • where_missing
    • pluck_to_tstruct
    • typed_enum
  • Model Relation:

    • Make relation classes public. By default, relation classes like User::ActiveRecord_Relation, User::ActiveRecord_AssociationRelation are private
    • Add type alias, eg Model::RelationType, to represents any type of relation of a model.
  • Controller: use TypedParams to convert controller parameters to a typed structure

In addition to requireing sorbet-rails, you must also run bundle exec rake rails_rbi:custom, which will produce the RBI for these runtime features.

Discussion: #211, #214

Tips & Tricks

Look for # typed: ignore files

Because Sorbet's initial setup tries to flag files at whichever typecheck level generates 0 errors, there may be files in your repository that are # typed: ignore. This is because sometimes Rails allows very dynamic code that Sorbet does not believe it can typecheck.

It is worth going through the list of files that is ignored and resolve them (and auto upgrade the types of other files; see initial setup above). Usually this will make many more files able to be typechecked.

Overriding generated signatures if needed

sorbet-rails relies on Rails reflection to generate signatures. There are features this gem doesn't support yet such as attribute custom types. The gem also doesn't know the signature of any methods you have overridden. However, it is possible to override the signatures that sorbet-rails generates.

For example, here is how to override the signature for a method in a model:

# -- app/models/model_name.rbi --

# typed: strong
class ModelName
  sig { returns(T::Hash[...]) }
  def field_name; end

  sig { params(obj: T::Hash[....]).void }
  def field_name=(obj); end
end

Replace Rails.application.routes.url_helpers

When using url helpers like _url or _path methods outside of a controller, we usually have to add include Rails.application.routes.url_helpers in the class. However, Sorbet does not allow code that includes dynamic module. Sorbet Rails provides a drop-in replacement module for the dynamic url_helpers module, called GeneratedUrlHelpers. Following code change should resolve the sorbet type-check error:

class MyClass
-  include Rails.application.routes.url_helpers
+  include GeneratedUrlHelpers
end

find, first and last

These 3 methods can either return a single nilable record or an array of records. Sorbet does not allow us to define multiple signatures for a function (except stdlib). It doesn't support defining one function signature that has varying returning value depending on the input parameter type. We opt to define the most commonly used signature for these methods, and monkey-patch new functions for the secondary use case.

In short:

  • Use find, first and last to fetch a single record.
  • Use find_n, first_n, last_n to fetch an array of records.

find_by_<attributes>, <attribute>_changed?, etc.

Rails supports dynamic methods based on attribute names, such as find_by_<attribute>, <attribute>_changed?, etc. They all have static counterparts. Instead of generating all possible dynamic methods that Rails support, we recommend to use of the static version of these methods instead (also recommended by RuboCop).

Following are the list of attribute dynamic methods and their static counterparts. The static methods have proper signatures:

  • find_by_<attributes> -> find_by(<attributes>)
  • find_by_<attributes>! -> find_by!(<attributes>)
  • <attribute>_changed? -> attribute_changed?(<attribute>)
  • <attribute>_was -> attribute_was(<attribute>)
  • saved_change_to_<attribute>? -> saved_change_to_attribute?(<attribute>)
  • <attribute>_before_type_cast -> read_attribute_before_type_cast(<attribute>)
  • will_save_change_to_<attribute>? -> will_save_change_to_attribute?(<attribute>)

after_commit and other callbacks

Consider converting after_commit callbacks to use instance method functions. Sorbet doesn't support binding an optional block with a different context. Because of this, when using a callback with a custom block, the block is evaluated in the wrong context (Class-level context). Refer to this page for a full list of callbacks available in Rails.

Before:

after_commit do ... end

After:

after_commit :after_commit
def after_commit
  ...
end

If you wanted to make these changes using Codemod, try these commands:

# from methods like after_commit do <...> end
❯ codemod -d app/models/ --extensions rb \
  '(\s*)(before|after)_(validation|save|create|commit|find|initialize|destroy) do' \
  '\1\2_\3 :\2_\3\n\1def \2_\3'

# from methods like after_commit { <...> }
❯ codemod -d app/models/ --extensions rb \
  '(\s*)(before|after)_(validation|save|create|commit|find|initialize|destroy) \{ (.*) \}' \
  '\1\2_\3 :\2_\3\n\1def \2_\3\n\1\1\4\n\1end'

Note that Codemod's preview may show that the indentation is off, but it works.

unscoped with a block

The unscoped method returns a Relation when no block is provided. When a block is provided, unscoped calls the block and returns its result, which could be any type.

sorbet-rails chooses to define unscoped as returning a Relation because it's more common and more useful. If you want to use a block, either override the unscoped definition, or replace:

Model.unscoped do … end

with:

Model.unscoped.scoping do … end

select with a block

The select method in Rails has two modes: it can be given a list of symbols, in which case rails will only return the given columns from the database, or it can be given a block, in which case it acts like Enumerable.select and returns an array.

We have chosen to support select with a block as the primary use case, since it is a more prevalent use of this method. We provide select_columns as an alternative if you want to select a list of columns.

Model.select { |record| record.id > 1} # valid, returns an array
Model.select_columns(:id, :name) # valid, returns an association

Model.select(:id, :name) # sorbet error, use `select_column` instead

flatten an array of relation

When you call flatten on an array of ActiveRecord::Relation, sorbet doesn't recognize that it will flatten the relation and return an array of model. The work around is to call to_a on the relation first.

# doesn't work
arr = [Model.recent, Model.old].flatten # T::Array[Model::ActiveRecord_Relation]

# work around
arr = [Model.recent, Model.old].map(&:to_a).flatten # T::Array[Model]

flat_map has a similar issue.

foo.bars.flat_map { |b| b.scope } # T::Array[T.untyped]

foo.bars.flat_map { |b| b.scope.to_a } # T::Array[Scope]

Avoid and_call_original in rspecs

If you run into the following issue when running rspec, it's likely because you're using expect(:method_name).and_call_original to mock a method in RSpec. We've found the double mock doesn't interact well with Sorbet's sig wrapper and caused flaky spec. The spec should be rewritten to expect the outcome of the method instead. (It still works with expect(:method_name) and expect(:method_name).and_return(...)

     RuntimeError:
       `sig` not present for method `:method_name` but you're trying to run it anyways. This should
       only be executed if you used `alias_method` to grab a handle to a method after `sig`ing it, but
       that clearly isn't what you are doing. Maybe look to see if an exception was thrown in your `sig`
       lambda or somehow else your `sig` wasn't actually applied to the method. Contact #dev-productivity
       if you're really stuck.

where.missing does not exist on ActiveRecord::Relation

The where method in Rails has two modes: it can be passed no arguments where it will return an ActiveRecord::QueryMethods::WhereChain object, or when given arguments, returns an ActiveRecord::Relation object. By default we've opted to support where with arguments and have provided a where_missing method to avoid conflicts during static typing.

Wizard.where.missing(:wand) # sorbet error, use `where_missing` instead

Wizard.where_missing(:wand) # valid, returns a relation

Note: where.missing / where_missing are only available in Rails 6.1 or above

Extending RBI Generation logic

Extending Model Generation Task with Custom Plugins

sorbet-rails support a customizable plugin system that you can use to generate additional RBI for each model. This will be useful to generate RBI for methods dynamically added by gems or private concerns. If you write plugins for public gems, please feel free to contribute it to this repo.

Defining a Custom ModelPlugin

A custom plugin should be a subclass of SorbetRails::ModelPlugins::Base. Each plugin would implement a generate(root) method that generate additional rbi for the model.

At a high level, here is the structure of a plugin:

# -- lib/my_custom_plugin.rb
class MyCustomPlugin < SorbetRails::ModelPlugins::Base
  sig { override.params(root: Parlour::RbiGenerator::Namespace).void }
  def generate(root)
    # TODO: implement the generation logic
    # You can use @model_class and @available_classes here
  end
end

During the generation phase, the system will create a new instance of the plugin, with the model_class to be generated and a set of all available_classes (available models) detected in the Rails App.

We use Parlour gem to generate the RBI for a model. Please check out Parlour wiki for guide to add RBI, eg create a new module, class, or method in the generated file.

At a high level, you'd usually want to create a model-scoped module for your methods, and include or extend it in the base model class. The generation logic usually looks like this:

  def generate(root)
    # Make sure this is only run for relevant class
    return unless @model_class.include?(CustomModule)

    custom_module_name = self.model_module_name("CustomModule")
    custom_module_rbi = root.create_module(custom_module_name)

    # here we re-create the model class!
    model_class_rbi = root.create_class(self.model_class_name)
    model_class_rbi.create_extend(custom_module_name)

    # then create custom methods, constants, etc. for this module.
    custom_module_rbi.create_method(...)

    # this is allowed but not recommended, because it limit the ability to override the method.
    model_class_rbi.create_method(...)
  end

Notice that we re-create model_class_rbi here. Parlour's ConflictResolver will merge the classes or modules with the same name together to generate 1 beautiful RBI file. It'll also flag and skip if any method is created multiple times with conflict signatures. Check-out useful predefined module names & helper methods in model_utils.

It is also allowed to put methods into a model class directly. However, it is not recommended because it'll be harder to override the method. sorbet will enforce that the overriding method match the signature generated. It also makes the generated RBI file less modularized.

However, sometimes this is required to make sorbet recognize the signature. This is the case for class methods added by ActiveRecord::Concerns. Because ActiveSupport::Concern class methods will be inserted to the class directly, you need to also put the sig in the model class rbi directly.

It is also recommended to check if the generated methods are detected by sorbet as a gem method (in sorbet/rbi/gem/gem_name.rbi) or hidden methods (in sorbet/rbi/hidden-definitions/hidden.rbi). If so, you may need to re-run srb rbi hidden-definition or put method in the model class directly.

Check out the plugins written for sorbet-rails's own model RBI generation logic for examples.

Registering new plugins

You can register your plugins in an initializer:

# -- config/initializers/sorbet_rails.rb
SorbetRails::ModelRbiFormatter.register_plugin(MyCustomPlugin)

Enabling built-in plugins

sorbet-rails comes with a handful of gem plugins that can be enabled in an initializer. You can pass enabled gem plugins to config.enabled_gem_plugins, like so:

# -- config/initializers/sorbet_rails.rb
SorbetRails.configure do |config|
  config.enabled_gem_plugins = [
    :kaminari
  ]
end

These are the currently-supported gems and their symbolized names:

Gem Symbol
ElasticSearch :elastic_search
FriendlyId :friendly_id
Kaminari :kaminari
PgSearch :pg_search
Shrine :shrine
active_flag :active_flag
Paperclip :paperclip
AttrJson :attr_json
FlagShihTzu :flag_shih_tzu
AASM :aasm
Money-Rails :money_rails

You can also configure the core model plugins if needed. The default plugins are defined in the config. For the full list of plugin symbols, check out here.

Customize Generation Class

For mailer and job rbi generation, you can customize the logic by setting the generation class in the config:

SorbetRails.configure do |config|
  config.job_generator_class = CustomJobRbiGenerator
  config.mailer_generator_class = CustomMailerRbiGenerator
end

The custom generator can subclass the provided generators and override the populate_rbi method. For example:

class CustomJobRbiGenerator < SorbetRails::JobRbiFormatter
  def populate_rbi
    rbi_generator.root.add_comment("== Custom Generator ==")
    super
  end
end

Contributing

Contributions and ideas are welcome! Please see our contributing guide and don't hesitate to open an issue or send a pull request to improve the functionality of this gem.

This project adheres to the Contributor Covenant code of conduct. By participating, you are expected to uphold this code. Please report unacceptable behavior to [email protected].

License

MIT

More Repositories

1

cellxgene

An interactive explorer for single-cell transcriptomics data
JavaScript
622
star
2

czi-prosemirror

Rich Text Editor built with React and ProseMirror
JavaScript
331
star
3

fogg

Manage Infrastructure as Code with less pain.
Go
269
star
4

shasta

[MOVED] Moved to paoloshasta/shasta. De novo assembly from Oxford Nanopore reads
C++
269
star
5

MedMentions

A corpus of Biomedical papers annotated with mentions of UMLS entities.
262
star
6

miniwdl

Workflow Description Language developer tools & local runner
Python
175
star
7

cellxgene-census

CZ CELLxGENE Discover Census
Jupyter Notebook
82
star
8

czid-web

Infectious Disease Sequencing Platform
Ruby
72
star
9

software-mentions

Jupyter Notebook
66
star
10

single-cell-data-portal

The data portal supporting the submission, exploration, and management of projects and datasets to cellxgene.
TypeScript
63
star
11

cztack

The CZI infrastructure stack.
HCL
61
star
12

blessclient

Go client to negotiate SSH certificates
Go
60
star
13

axe-storybook-testing

Command line interface for testing Storybook stories for accessibility.
TypeScript
52
star
14

napari-hub

Discover, install, and share napari plugins
TypeScript
51
star
15

ChemDisGene

Bio relation extraction labeled dataset
Python
40
star
16

s3parcp

Faster than s3cp
Go
37
star
17

single-cell-curation

Code and documentation for the curation of cellxgene datasets
Python
37
star
18

czid-workflows

Portable WDL workflows for CZ ID production pipelines
Python
36
star
19

redis-memo

A Redis-based version addressable caching system. Memoize pure functions, aggregated database queries, and 3rd party API calls.
Ruby
33
star
20

redcord

A Ruby ORM like Active Record, but for Redis.
Ruby
32
star
21

idseq-workflows

Portable WDL workflows for IDseq production pipelines
Python
31
star
22

taxoniq

Taxon Information Query - fast, offline querying of NCBI Taxonomy and related data
Python
30
star
23

sorbet-coerce

A type coercion lib works with Sorbet's static type checker and type definitions
Ruby
29
star
24

ExpressionMatrix2

Software for exploration of gene expression data from single-cell RNA sequencing.
C++
29
star
25

edu-design-system

Design system for Education Projects
TypeScript
28
star
26

chalice-app-template

An AWS Lambda serverless app template with Terraform deployment management
Python
28
star
27

czid-dag

Please see https://github.com/chanzuckerberg/czid-workflows for the latest version of CZ ID workflows.
Python
27
star
28

sci-components

2021 Science Design System Component Library
TypeScript
25
star
29

scRNA-python-workshop

All the action is on the course webpage -->
Jupyter Notebook
24
star
30

alhazen

AI agents + toolkits for scientific knowledge
Jupyter Notebook
20
star
31

czid-cli

CZID (formerly IDseq) infectious disease command-line interface
Go
19
star
32

software-impact-hackathon-2023

A collection of projects by participants in CZI's hackathon "Mapping the Impact of Research Software in Science" (October 2023)
18
star
33

happy

Happy Path Deployment Tool
Go
18
star
34

cellxgene-documentation

Documentation for the cellxgene product
17
star
35

aws-oidc

AWS OIDC Federation
Go
15
star
36

cryoet-data-portal

CryoET Data Portal
TypeScript
15
star
37

rotator

Rotator is a tool for rotating credentials on a regular schedule.
Go
15
star
38

czid-dedup

deduplicate FASTA and FASTQ files
Rust
15
star
39

czgenepi

Python
13
star
40

terraform-provider-bless

Terraform provider to automate the creation of BLESS deployments
Go
12
star
41

scEvalsJam

Jupyter Notebook
12
star
42

czi-oss-training

Training Materials for Good Open Source Citizenship
11
star
43

s3mi

Transfer big files fast between S3 and EC2. Pronounced "semi".
Python
11
star
44

single-cell-explorer

Hosted version of cellxgene
TypeScript
11
star
45

napari-plugin-alfa-cohort

Repo for the CZI Imaging Team's napari plugin Alfa Cohort collaboration
11
star
46

pyrepl

JS/Python execution bridge
JavaScript
9
star
47

software-mention-extraction

Software mention extraction and linking from scientific articles
Jupyter Notebook
9
star
48

napari-cryoet-data-portal

A napari plugin to list, preview, and open data from the CZ Imaging Institute's CryoET Data Portal
Python
8
star
49

prometheus-demo

Simulates monitoring HTTP microservice and short-lived job metrics
Python
8
star
50

ruby-prof-speedscope

A ruby-prof printer for the speedscope.app trace viewer.
Ruby
8
star
51

galago

Interpretation aids for genomic epidemiology
TypeScript
8
star
52

go-misc

miscellaneous go code
Go
8
star
53

scoreboard

minimalist web app for comparing algorithm performance on benchmark data
JavaScript
8
star
54

idseq-cli

IDseq infectious disease command-line interface
Python
8
star
55

open-science

curated links and customized materials to support biomedical researchers in implementing open science approaches
JavaScript
8
star
56

swipe

SFN-WDL infrastructure for pipeline execution - a template repository and Terraform module for SFN-WDL based projects
Python
7
star
57

idseq-bench

IDseq infectious disease benchmarking tools
Python
7
star
58

napari-hub-collections

DEPRECATED: collections of plugins for the napari hub
Python
7
star
59

bff

Breaking, Feature, Fix - a tool for managing semantic versioning
Go
6
star
60

gs

A small, user-friendly Google Cloud Storage CLI client
Python
6
star
61

ontology-ui

Ontology visualizer
TypeScript
6
star
62

frontend-libs

Monorepo of TypeScript projects for the Chan Zuckerberg Initiative.
TypeScript
6
star
63

miniwdl-plugins

MiniWDL plugins
Python
6
star
64

concept_discovery

Python
6
star
65

spatial-warehouse

Investigation into spatial data and data schema
Jupyter Notebook
6
star
66

docs-editor

rich text editor for education purpose.
HTML
5
star
67

reaper

Go
5
star
68

DRSM-corpus

An annotated literature corpus for NLP studies of 'Disease Research State' based on different categories of research.
5
star
69

full-text-mining-ner

Open Source Code for Extraction of Methods and Datasets from Biomedical Papers
Python
5
star
70

github-actions

A collection of re-usable GitHub Actions
HCL
5
star
71

single-cell

A collection of documents that reflect various design decisions that have been made for the cellxgene project.
4
star
72

nbconvert-service

A very light API wrapper around nbconvert
Python
4
star
73

napari-hub-cli

This is a CLI for the napari hub
Python
4
star
74

czid-platformics

Python
4
star
75

wdl-cell-ranger

Run Cell Ranger pipelines using WDL and Cromwell
Python
4
star
76

cellxgene-compbio-methods

Jupyter Notebook
3
star
77

shasta-docs

[DEPRECATED] Shasta github.io repo for user guides, etc.
3
star
78

napari-segmentation-workshop

workshop materials for performing cell segmentation in napari
TeX
3
star
79

cellxgene-ontology-guide

Python
2
star
80

napari.dev

HTML
2
star
81

homebrew-tap

Ruby
2
star
82

chained-aws-lambda

Python
2
star
83

ncbi-tool-cliclient

CLI client for NCBI data tool
Go
2
star
84

ncbi-tool-sync

Sync component for NCBI data tool
Go
2
star
85

czecs

CLI deployment tool for AWS Elastic Container Service
Go
2
star
86

czLandscapingTk

Landscaping analysis tools for publicly available scientific knowledge sources.
Python
2
star
87

scatter-demo

demo scatter plot using webgl and regl
JavaScript
2
star
88

go-kmsauth

Port kmsauth to go
Go
2
star
89

safe_type

Type Coercion & Type Enhancement
Ruby
2
star
90

awesome-data-insights-projects

2
star
91

platformics

Codegen Python GraphQL Entity Framework
Python
2
star
92

miniwdl-viz

A library to decompose WDL files into a JSON/YAML, and create a mermaid flowchart
WDL
2
star
93

shasta-docker

[DEPRECATED] This repository contains the code and configuration required to create Docker images for Shasta on different platforms.
Python
2
star
94

mini-ete3-js

npm package for basic phylogenetics functionality in the browser
TypeScript
1
star
95

cellxgene-manuscript-2023

Code and data to reproduce analyses in the 2023 cellxgene manuscript
Jupyter Notebook
1
star
96

CZ-PR-bot

A Github bot for streamlined PR reviews
JavaScript
1
star
97

ncbi-tool-search

Collection of script-style utility functions for the NT/NR search mapping research.
Go
1
star
98

crc-squared

light speed crc32c checksums
Go
1
star
99

go-travis-wait

A better wrapper for travis_wait
Shell
1
star
100

single-cell-tissue-coverage-visualization-prototype

HTML
1
star