Mixer -- Is a fixtures replacement. Supported Django, Flask, SqlAlchemy and custom python objects.

Overview

https://raw.github.com/klen/mixer/develop/docs/_static/logo.png

The Mixer is a helper to generate instances of Django or SQLAlchemy models. It's useful for testing and fixture replacement. Fast and convenient test-data generation.

Mixer supports:

Tests Status Version Downloads License

Docs are available at https://mixer.readthedocs.org/. Pull requests with documentation enhancements and/or fixes are awesome and most welcome.

Описание на русском языке: http://klen.github.io/mixer.html

Important

From version 6.2 the Mixer library doesn't support Python 2. The latest version with python<3 support is mixer 6.1.3

Requirements

  • Python 3.7+
  • Django (3.0, 3.1) for Django ORM support;
  • Flask-SQLALchemy for SQLAlchemy ORM support and integration as Flask application;
  • Faker >= 0.7.3
  • Mongoengine for Mongoengine ODM support;
  • SQLAlchemy for SQLAlchemy ORM support;
  • Peewee ORM support;

Installation

Mixer should be installed using pip:

pip install mixer

Usage

By default Mixer tries to generate fake (human-friendly) data.
If you want to randomize the generated values initialize the Mixer
by manual: Mixer(fake=False)
By default Mixer saves the generated objects in a database. If you want to disable
this, initialize the Mixer by manual like Mixer(commit=False)

Django workflow

Quick example:

from mixer.backend.django import mixer
from customapp.models import User, UserMessage

# Generate a random user
user = mixer.blend(User)

# Generate an UserMessage
message = mixer.blend(UserMessage, user=user)

# Generate an UserMessage and an User. Set username for generated user to 'testname'.
message = mixer.blend(UserMessage, user__username='testname')

# Generate SomeModel from SomeApp and select FK or M2M values from db
some = mixer.blend('someapp.somemodel', somerelation=mixer.SELECT)

# Generate SomeModel from SomeApp and force a value of money field from default to random
some = mixer.blend('someapp.somemodel', money=mixer.RANDOM)

# Generate 5 SomeModel's instances and take company field's values from custom generator
some_models = mixer.cycle(5).blend('somemodel', company=(name for name in company_names))

Flask, Flask-SQLAlchemy

Quick example:

from mixer.backend.flask import mixer
from models import User, UserMessage

mixer.init_app(self.app)

# Generate a random user
user = mixer.blend(User)

# Generate an userMessage
message = mixer.blend(UserMessage, user=user)

# Generate an UserMessage and an User. Set username for generated user to 'testname'.
message = mixer.blend(UserMessage, user__username='testname')

# Generate SomeModel and select FK or M2M values from db
some = mixer.blend('project.models.SomeModel', somerelation=mixer.SELECT)

# Generate SomeModel from SomeApp and force a value of money field from default to random
some = mixer.blend('project.models.SomeModel', money=mixer.RANDOM)

# Generate 5 SomeModel's instances and take company field's values from custom generator
some_models = mixer.cycle(5).blend('project.models.SomeModel', company=(company for company in companies))

Support for Flask-SQLAlchemy models that have __init__ arguments

For support this scheme, just create your own mixer class, like this:

from mixer.backend.sqlalchemy import Mixer

class MyOwnMixer(Mixer):

    def populate_target(self, values):
        target = self.__scheme(**values)
        return target

mixer = MyOwnMixer()

SQLAlchemy workflow

Example of initialization:

from mixer.backend.sqlalchemy import Mixer

ENGINE = create_engine('sqlite:///:memory:')
BASE = declarative_base()
SESSION = sessionmaker(bind=ENGINE)

mixer = Mixer(session=SESSION(), commit=True)
role = mixer.blend('package.models.Role')

Also, see Flask, Flask-SQLAlchemy.

Mongoengine workflow

Example usage:

from mixer.backend.mongoengine import mixer

class User(Document):
    created_at = DateTimeField(default=datetime.datetime.now)
    email = EmailField(required=True)
    first_name = StringField(max_length=50)
    last_name = StringField(max_length=50)
    username = StringField(max_length=50)

class Post(Document):
    title = StringField(max_length=120, required=True)
    author = ReferenceField(User)
    tags = ListField(StringField(max_length=30))

post = mixer.blend(Post, author__username='foo')

Marshmallow workflow

Example usage:

from mixer.backend.marshmallow import mixer
import marshmallow as ma

class User(ma.Schema):
    created_at = ma.fields.DateTime(required=True)
    email = ma.fields.Email(required=True)
    first_name = ma.fields.String(required=True)
    last_name = ma.fields.String(required=True)
    username = ma.fields.String(required=True)

class Post(ma.Schema):
    title = ma.fields.String(required=True)
    author = ma.fields.Nested(User, required=True)

post = mixer.blend(Post, author__username='foo')

Common usage

Quick example:

from mixer.main import mixer

class Test:
    one = int
    two = int
    name = str

class Scheme:
    name = str
    money = int
    male = bool
    prop = Test

scheme = mixer.blend(Scheme, prop__one=1)

DB commits

By default 'django', 'flask', 'mongoengine' backends tries to save objects in database. For preventing this behavior init mixer manually:

from mixer.backend.django import Mixer

mixer = Mixer(commit=False)

Or you can temporary switch context use the mixer as context manager:

from mixer.backend.django import mixer

# Will be save to db
user1 = mixer.blend('auth.user')

# Will not be save to db
with mixer.ctx(commit=False):
    user2 = mixer.blend('auth.user')

Custom fields

The mixer allows you to define generators for fields by manually. Quick example:

from mixer.main import mixer

class Test:
    id = int
    name = str

mixer.register(Test,
    name=lambda: 'John',
    id=lambda: str(mixer.faker.small_positive_integer())
)

test = mixer.blend(Test)
test.name == 'John'
isinstance(test.id, str)

# You could pinned just a value to field
mixer.register(Test, name='Just John')
test = mixer.blend(Test)
test.name == 'Just John'

Also, you can make your own factory for field types:

from mixer.backend.django import Mixer, GenFactory

def get_func(*args, **kwargs):
    return "Always same"

class MyFactory(GenFactory):
    generators = {
        models.CharField: get_func
    }

mixer = Mixer(factory=MyFactory)

Middlewares

You can add middleware layers to process generation:

from mixer.backend.django import mixer

# Register middleware to model
@mixer.middleware('auth.user')
def encrypt_password(user):
    user.set_password('test')
    return user

You can add several middlewares. Each middleware should get one argument (generated value) and return them.

It's also possible to unregister a middleware:

mixer.unregister_middleware(encrypt_password)

Locales

By default mixer uses 'en' locale. You could switch mixer default locale by creating your own mixer:

from mixer.backend.django import Mixer

mixer = Mixer(locale='it')
mixer.faker.name()          ## u'Acchisio Conte'

At any time you could switch mixer current locale:

mixer.faker.locale = 'cz'
mixer.faker.name()          ## u'Miloslava Urbanov\xe1 CSc.'

mixer.faker.locale = 'en'
mixer.faker.name()          ## u'John Black'

# Use the mixer context manager
mixer.faker.phone()         ## u'1-438-238-1116'
with mixer.ctx(locale='fr'):
    mixer.faker.phone()     ## u'08 64 92 11 79'

mixer.faker.phone()         ## u'1-438-238-1116'

Bug tracker

If you have any suggestions, bug reports or annoyances please report them to the issue tracker at https://github.com/klen/mixer/issues

Contributing

Development of mixer happens at Github: https://github.com/klen/mixer

Contributors

License

Licensed under a BSD license.

Comments
  • Support for Flask-SQLAlchemy models that have `__init__` arguments

    Support for Flask-SQLAlchemy models that have `__init__` arguments

    Consider the todo example from Flask-SQLAlchemy:

    from datetime import datetime
    from flask import Flask
    from flask_sqlalchemy import SQLAlchemy
    from mixer.backend.sqlalchemy import mixer
    
    app = Flask(__name__)
    db = SQLAlchemy(app)
    
    class Todo(db.Model):
        __tablename__ = 'todos'
        id = db.Column('todo_id', db.Integer, primary_key=True)
        title = db.Column(db.String(60))
        text = db.Column(db.String)
        pub_date = db.Column(db.DateTime)
    
        def __init__(self, title, text):
            self.title = title
            self.text = text
            self.pub_date = datetime.utcnow()
    

    If we try to use mixer with it:

    mixer.blend(Todo)
    
    ---------------------------------------------------------------------------
    TypeError                                 Traceback (most recent call last)
    <ipython-input-1-8a1d24676132> in <module>()
         19         self.pub_date = datetime.utcnow()
         20
    ---> 21 mixer.blend(Todo)
    
    /Users/razzi/local/venvs/thornm/lib/python2.7/site-packages/mixer/main.pyc in blend(self, scheme, **values)
        596         type_mixer = self.get_typemixer(scheme)
        597         try:
    --> 598             return type_mixer.blend(**values)
        599         except Exception:
        600             if self.params.get('silence'):
    
    /Users/razzi/local/venvs/thornm/lib/python2.7/site-packages/mixer/main.pyc in blend(self, **values)
        145                 values.append((name, value))
        146
    --> 147         target = self.populate_target(values)
        148
        149         # Run registered middlewares
    
    /Users/razzi/local/venvs/thornm/lib/python2.7/site-packages/mixer/main.pyc in populate_target(self, values)
        168     def populate_target(self, values):
        169         """ Populate target with values. """
    --> 170         target = self.__scheme()
        171         for name, value in values:
        172             setattr(target, name, value)
    
    TypeError: __init__() takes exactly 3 arguments (1 given)
    

    mixer attempts to __init__ without any arguments, which throws an error. Would supporting a model defined this way be feasible/desirable?

    One way to get around this is to make all fields have defaults in the __init__:

    class User(Base):
        __tablename__ = 'users'
        id = Column(Integer, primary_key=True)
        name = Column(String(50), unique=True)
        email = Column(String(120), unique=True)
    
        def __init__(self, name=None, email=None):
            self.name = name
            self.email = email
    

    At the very least, putting a note in the docs that models with required __init__ parameters are unsupported might save others some confusion.

    opened by razzius 6
  • Postgres UUID

    Postgres UUID

    Mixer doesn't support sqlalchemy.dialects.postgresql.UUID. I'm make simple hotfix for it based on name. I can't make tests for it because mixer's tests uses only in memory sqlite database.

    opened by orsinium 5
  • Add django2 support. Drop django1.9. Update tox and readme

    Add django2 support. Drop django1.9. Update tox and readme

    This commit adds support for Django 2.0, which is now released. It also drops support for Django 1.9.

    More work will need to be done with the tox/travis setup if the author would like travis to test django2, as it requires python3 but the current travis config is python2 only.

    opened by Fingel 5
  • Prevent distasteful sample content

    Prevent distasteful sample content

    I'm using mixer to generate sample data for a software demo in a relatively conservative industry. As such, I don't want to be showing a demo of my software and have things like [email protected] (that's a real world example) show up as an email address - it makes us look immature when we're presenting our software to enterprise clients.

    I realize we're not going to eliminate the possibility of suggestive content getting populated from time to time, but I see no reason to invite it.

    Would you be open to removing some of the more explicit sample content, or providing a way to disable it? I'd be happy to do some of the work and submit a pull request, just wanted to ask first.

    opened by fuhrysteve 5
  • Incompatible with latest version of Faker (`12.1.0`)

    Incompatible with latest version of Faker (`12.1.0`)

    Using the latest version of Faker (12.1.0) raises the following exception:

    AttributeError: type object 'Factory' has no attribute '_get_provider_class'
    

    The latest version of Faker (published 11 hours ago) removed the method "_get_provider_class".

    This package uses _get_provider_class here: https://github.com/klen/mixer/blob/39ef3b717d4ac9da1824cb9c242fd326fa00ba08/mixer/_faker.py#L33

    Disallowing the latest version of Faker seems to fix the problem.

    opened by mtilda 4
  • Error when using a Marshmallow schema

    Error when using a Marshmallow schema

    I get the following error when I want to generate an object using a marshmallow schema:

    ValueError: Mixer (<class 'src.users.schemas.UserSchema'>): Generation for OPTIONS_CLASS (UserSchema) has been stopped. Exception: __init__() missing 1 required positional argument: 'meta'
    

    The code is:

    from marshmallow import Schema, fields
    from mixer.main import mixer
    
    class UserSchema(Schema):
        id = fields.Integer(read_only=True)
        email = fields.String()
        first_name = fields.String()
        last_name = fields.String()
    
    user = mixer.blend(UserSchema)
    

    I saw this issue open, which indicates this is not possible yet. But it is in the docs already here.

    Versions:

    python==3.7.0
    marshmallow==2.16.0
    mixer==6.1.3
    

    Full trace:

    Traceback (most recent call last):
      File "/usr/local/lib/python3.7/site-packages/mixer/main.py", line 241, in gen_value
        value = fab()
      File "/usr/local/lib/python3.7/site-packages/mixer/main.py", line 134, in blend
        target = self.populate_target(values)
      File "/usr/local/lib/python3.7/site-packages/mixer/main.py", line 157, in populate_target
        target = self.__scheme()
    TypeError: __init__() missing 1 required positional argument: 'meta'
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "/usr/local/lib/python3.7/site-packages/sanic/app.py", line 603, in handle_request
        response = await response
      File "/usr/src/src/users/views.py", line 19, in get
        create_user()
      File "/usr/src/src/users/factories.py", line 7, in create_user
        user = mixer.blend(UserSchema)
      File "/usr/local/lib/python3.7/site-packages/mixer/main.py", line 568, in blend
        return type_mixer.blend(**values)
      File "/usr/local/lib/python3.7/site-packages/mixer/main.py", line 116, in blend
        for name, value in defaults.items()
      File "/usr/local/lib/python3.7/site-packages/mixer/main.py", line 116, in <genexpr>
        for name, value in defaults.items()
      File "/usr/local/lib/python3.7/site-packages/mixer/mix_types.py", line 222, in gen_value
        return type_mixer.gen_field(field)
      File "/usr/local/lib/python3.7/site-packages/mixer/main.py", line 193, in gen_field
        return self.gen_value(field.name, field, unique=unique)
      File "/usr/local/lib/python3.7/site-packages/mixer/main.py", line 247, in gen_value
        field_name, self.__scheme.__name__, exc))
    ValueError: Mixer (<class 'src.users.schemas.UserSchema'>): Generation for OPTIONS_CLASS (UserSchema) has been stopped. Exception: __init__() missing 1 required positional argument: 'meta'
    

    Any help would be appreciated!

    opened by snoepkast 4
  • change SMALLINT to 32767

    change SMALLINT to 32767

    in mysql 32768 is too large for a small int, only 32767 is allowed. (ref - https://dev.mysql.com/doc/refman/8.0/en/integer-types.html) this causes a bug for me many times.

    opened by avi-pomicell 3
  • django 2.1+ support

    django 2.1+ support

    supporting django 2.1 for a project

    Mixer 6.0.1 version raises an exception while creating FK items in django 2.1:

    Traceback (most recent call last): File "", line 1, in File "/usr/local/lib/python3.6/site-packages/mixer/main.py", line 568, in blend return type_mixer.blend(**values) File "/usr/local/lib/python3.6/site-packages/mixer/main.py", line 116, in blend for name, value in defaults.items() File "/usr/local/lib/python3.6/site-packages/mixer/main.py", line 116, in for name, value in defaults.items() File "/usr/local/lib/python3.6/site-packages/mixer/backend/django.py", line 218, in get_value return self._get_value(name, value, field) File "/usr/local/lib/python3.6/site-packages/mixer/backend/django.py", line 233, in _get_value value = field.scheme.to_python(value) File "/usr/local/lib/python3.6/site-packages/django/db/models/fields/related.py", line 874, in to_python return self.target_field.to_python(value) File "/usr/local/lib/python3.6/site-packages/django/db/models/fields/init.py", line 945, in to_python params={'value': value}, django.core.exceptions.ValidationError: ["Значение 'Anna Stevens' должно быть целым числом."]

    This patch fix it

    opened by Mikhail517 3
  • Update django.py

    Update django.py

    This line: value = field.scheme.to_python(value) raises an Exception when you upgrade to django 2.1. I don't know why it happens, but this workaround fixed the tests for me :).

    opened by ephes 3
  • Fix small positive integer field limit

    Fix small positive integer field limit

    opened by jnns 3
  • make_fabric & cls_to_simple fixes

    make_fabric & cls_to_simple fixes

    few fixes to resolve issues with sqlalchemy + MySQL

    • mixer.factory.GenFactory#cls_to_simple does not handle dialects.

    if fcls is <class 'sqlalchemy.dialects.mysql.base.VARCHAR'> original function returns None with this fix it will return <class 'sqlalchemy.sql.sqltypes.VARCHAR'>

    • mixer.backend.sqlalchemy.TypeMixer#make_fabric TINYINT(1) should be boolean. original function generates TINYINT instead of BOOLEAN which may lead to errors
    opened by overborn 3
  • build(deps): update faker requirement from <12.1,>=5.4.0 to >=5.4.0,<15.4

    build(deps): update faker requirement from <12.1,>=5.4.0 to >=5.4.0,<15.4

    Updates the requirements on faker to permit the latest version.

    Release notes

    Sourced from faker's releases.

    Release v15.3.1

    See CHANGELOG.md.

    Changelog

    Sourced from faker's changelog.

    v15.3.1 - 2022-11-07

    v15.3.0 - 2022-11-07

    v15.2.0 - 2022-11-04

    v15.1.5 - 2022-11-04

    v15.1.4 - 2022-11-04

    • Remove test dependency on random2.

    v15.1.3 - 2022-11-01

    v15.1.2 - 2022-11-01

    • Fix missing return in en_US state_abbr. Thanks @​AssenD.

    v15.1.1 - 2022-10-13

    v15.1.0 - 2022-10-11

    v15.0.0 - 2022-09-26

    v14.2.1 - 2022-09-22

    • Fix misspelled first name in da_DK locale. Thanks @​filson1.

    v14.2.0 - 2022-08-31

    v14.1.2 - 2022-08-31

    ... (truncated)

    Commits

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies python 
    opened by dependabot[bot] 1
  • Don't restrict Faker to version < 12.1

    Don't restrict Faker to version < 12.1

    What is the reason to restrict Faker to a version below 12.1? Looking at the release notes of Faker, I would not expect any breaking changes. Maybe lift the restriction completely or at least raise it to the current (major-)version?

    opened by finsterwalder 4
  • Mixer should respect decimal presision on SQLAlchemy models

    Mixer should respect decimal presision on SQLAlchemy models

    I have model with field defined like this: Column(sa.Numeric(precision=9, scale=3), nullable=False) and I am trying to use Mixer to put data into that model. Sometimes it tries to insert larger values than allowed by this field which results with error:

    sqlalchemy.exc.DataError: Mixer (<class 'test.Model'>): (psycopg2.errors.NumericValueOutOfRange) numeric field overflow
    DETAIL:  A field with precision 9, scale 3 must round to an absolute value less than 10^6.
    
    opened by pax0r 0
  • docs: Fix a few typos

    docs: Fix a few typos

    There are small typos in:

    • mixer/_compat.py
    • mixer/auto.py
    • mixer/main.py
    • mixer/markov.py

    Fixes:

    • Should read happened rather than happend.
    • Should read deprecated rather than depricated.
    • Should read constructing rather than contructing.
    • Should read automatically rather than automaticly.

    Semi-automated pull request generated by https://github.com/timgates42/meticulous/blob/master/docs/NOTE.md

    opened by timgates42 0
Owner
Kirill Klenov
Kirill Klenov
A drop-in replacement for Django's runserver.

About A drop in replacement for Django's built-in runserver command. Features include: An extendable interface for handling things such as real-time l

David Cramer 1.3k Dec 15, 2022
create custom test databases that are populated with fake data

About Generate fake but valid data filled databases for test purposes using most popular patterns(AFAIK). Current support is sqlite, mysql, postgresql

Emir Ozer 2.2k Jan 6, 2023
Waitress - A WSGI server for Python 2 and 3

Waitress Waitress is a production-quality pure-Python WSGI server with very acceptable performance. It has no dependencies except ones which live in t

Pylons Project 1.2k Dec 30, 2022
Green is a clean, colorful, fast python test runner.

Green -- A clean, colorful, fast python test runner. Features Clean - Low redundancy in output. Result statistics for each test is vertically aligned.

Nathan Stocks 756 Dec 22, 2022
Scalable user load testing tool written in Python

Locust Locust is an easy to use, scriptable and scalable performance testing tool. You define the behaviour of your users in regular Python code, inst

Locust.io 20.4k Jan 8, 2023
A cross-platform GUI automation Python module for human beings. Used to programmatically control the mouse & keyboard.

PyAutoGUI PyAutoGUI is a cross-platform GUI automation Python module for human beings. Used to programmatically control the mouse & keyboard. pip inst

Al Sweigart 7.6k Jan 1, 2023
splinter - python test framework for web applications

splinter - python tool for testing web applications splinter is an open source tool for testing web applications using Python. It lets you automate br

Cobra Team 2.6k Dec 27, 2022
Let your Python tests travel through time

FreezeGun: Let your Python tests travel through time FreezeGun is a library that allows your Python tests to travel through time by mocking the dateti

Steve Pulec 3.5k Jan 9, 2023
HTTP client mocking tool for Python - inspired by Fakeweb for Ruby

HTTPretty 1.0.5 HTTP Client mocking tool for Python created by Gabriel Falcão . It provides a full fake TCP socket module. Inspired by FakeWeb Github

Gabriel Falcão 2k Jan 6, 2023
A utility for mocking out the Python Requests library.

Responses A utility library for mocking out the requests Python library. Note Responses requires Python 2.7 or newer, and requests >= 2.0 Installing p

Sentry 3.8k Jan 2, 2023
Faker is a Python package that generates fake data for you.

Faker is a Python package that generates fake data for you. Whether you need to bootstrap your database, create good-looking XML documents, fill-in yo

Daniele Faraglia 15.2k Jan 1, 2023
Mimesis is a high-performance fake data generator for Python, which provides data for a variety of purposes in a variety of languages.

Mimesis - Fake Data Generator Description Mimesis is a high-performance fake data generator for Python, which provides data for a variety of purposes

Isaak Uchakaev 3.8k Jan 1, 2023
Coroutine-based concurrency library for Python

gevent Read the documentation online at http://www.gevent.org. Post issues on the bug tracker, discuss and ask open ended questions on the mailing lis

gevent 5.9k Dec 28, 2022
Radically simplified static file serving for Python web apps

WhiteNoise Radically simplified static file serving for Python web apps With a couple of lines of config WhiteNoise allows your web app to serve its o

Dave Evans 2.1k Jan 8, 2023
livereload server in python (MAINTAINERS NEEDED)

LiveReload Reload webpages on changes, without hitting refresh in your browser. Installation python-livereload is for web developers who know Python,

Hsiaoming Yang 977 Dec 14, 2022
A screamingly fast Python 2/3 WSGI server written in C.

bjoern: Fast And Ultra-Lightweight HTTP/1.1 WSGI Server A screamingly fast, ultra-lightweight WSGI server for CPython 2 and CPython 3, written in C us

Jonas Haag 2.9k Dec 21, 2022
Python HTTP Server

Python HTTP Server Preview Languange and Code Editor: How to run? Download the zip first. Open the http.py and wait 1-2 seconds. You will see __pycach

SonLyte 16 Oct 21, 2021
PyQaver is a PHP like WebServer for Python.

PyQaver is a PHP like WebServer for Python.

Dev Bash 7 Apr 25, 2022
Robyn is an async Python backend server with a runtime written in Rust, btw.

Robyn is an async Python backend server with a runtime written in Rust, btw. Python server running on top of of Rust Async RunTime. Installation

Sanskar Jethi 1.8k Dec 30, 2022