{"id":22800783,"url":"https://github.com/seii-saintway/ipymock","last_synced_at":"2025-07-09T17:05:26.025Z","repository":{"id":151959576,"uuid":"349330762","full_name":"seii-saintway/ipymock","owner":"seii-saintway","description":"A Tool that Allows You Run PyTest within Jupyter Notebook Cells","archived":false,"fork":false,"pushed_at":"2025-03-20T13:28:05.000Z","size":123,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-07-09T17:05:10.402Z","etag":null,"topics":["ai","autogpt","autogpt-no-paid-api","backend-api","chatgpt","chatgpt-api","chatgpt-free","democratize-ai","free-autogpt","gpt-4","gpt-4-api","gpt4","mock","open-source-auto-gpt","open-source-gpt","openai","openai-api","pytest","python","reverse-engineering"],"latest_commit_sha":null,"homepage":"https://seii-saintway.github.io/ipymock/","language":"Jupyter Notebook","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/seii-saintway.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2021-03-19T07:02:08.000Z","updated_at":"2025-03-20T13:28:09.000Z","dependencies_parsed_at":null,"dependency_job_id":"f2b32d10-742b-4b03-b107-343d3f7fcb5c","html_url":"https://github.com/seii-saintway/ipymock","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/seii-saintway/ipymock","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seii-saintway%2Fipymock","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seii-saintway%2Fipymock/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seii-saintway%2Fipymock/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seii-saintway%2Fipymock/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/seii-saintway","download_url":"https://codeload.github.com/seii-saintway/ipymock/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seii-saintway%2Fipymock/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264502124,"owners_count":23618554,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["ai","autogpt","autogpt-no-paid-api","backend-api","chatgpt","chatgpt-api","chatgpt-free","democratize-ai","free-autogpt","gpt-4","gpt-4-api","gpt4","mock","open-source-auto-gpt","open-source-gpt","openai","openai-api","pytest","python","reverse-engineering"],"created_at":"2024-12-12T08:07:56.760Z","updated_at":"2025-07-09T17:05:25.920Z","avatar_url":"https://github.com/seii-saintway.png","language":"Jupyter Notebook","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Running PyTest in Jupyter Notebooks\n\n\u003e iPyMock uses GPT 3.5 turbo by browser automation and \u003ca href='https://huggingface.co/GanymedeNil/text2vec-large-chinese'\u003ea CoSENT based model\u003c/a\u003e to embed English and Chinese.\n\n[![Discord Follow](https://dcbadge.vercel.app/api/server/8YhXA7TYrC?style=flat)](https://discord.gg/8YhXA7TYrC)\n[![Twitter Follow](https://img.shields.io/twitter/follow/seii_saintway?style=social)](https://twitter.com/seii_saintway)\n\n## Setup iPyMock\n\n`gmail_address` and `gmail_password` are needed for utilizing chrome automation locally.\n\n`conversation_id` could be found in the url of `chat.openai.com/c/\u003cconversation_id\u003e`.\n\n```bash\nmkdir -p ~/.config/ipymock\n\ncat \u003c\u003c EOF \u003e ~/.config/ipymock/config.json\n{\n  \"email\": \"\u003cgmail_address\u003e\",\n  \"password\": \"\u003cgmail_password\u003e\",\n  \"conversation_id\": \"\u003cconversation_id\u003e\"\n}\nEOF\n\npip install --upgrade ipymock\n```\n\n`access_token` at [openai api session](https://chat.openai.com/api/auth/session) is needed for utilizing a backend api proxy.\n\n```bash\nmkdir -p ~/.config/ipymock\n\ncat \u003c\u003c EOF \u003e ~/.config/ipymock/config.json\n{\n  \"chat_gpt_base_url\": \"\u003cchat_gpt_base_url\u003e\",\n  \"access_token\": \"\u003caccess_token\u003e\",\n  \"conversation_id\": \"\u003cconversation_id\u003e\"\n}\nEOF\n\npip install --upgrade ipymock\n```\n\n## Using the OpenAI Backend API from Browser Side in Jupyter Notebooks\n\n```python\nfrom ipymock.browser import start_conversation\nimport IPython\n\ndef ask(prompt):\n    for response in start_conversation(prompt):\n        IPython.display.display(IPython.core.display.Markdown(response))\n        IPython.display.clear_output(wait=True)\n\nimport ipymock.browser\n# 1. you could initialize chrome automation locally\nipymock.browser.init(['--headless'])\n# 2. or if a proxy is deployed locally\nipymock.browser.common.chat_gpt_base_url = 'http://127.0.0.1:8080'\n# 3. otherwise using a third party proxy\nipymock.browser.common.chat_gpt_base_url = 'https://.../api'\n# the conversation_id which is set in config.json\nprint(ipymock.browser.common.conversation_id)\n\nask('''\nwhat is the meaning of getting patched?\n''')\n```\n\n## Testing AutoGPT\n\nThis is the test function for AutoGPT.\n\n```python\nimport os, sys\nos.chdir(os.path.expanduser('~/Auto-GPT'))\nsys.path.append(os.path.expanduser('~/Auto-GPT'))\n\ndef test_auto_gpt(\n    mock_openai,\n    mock_openai_embed,\n    reset_embed_dimension,\n):\n    from autogpt.main import run_auto_gpt\n    run_auto_gpt(\n        continuous = True,\n        continuous_limit = 10000,\n        ai_settings = None,\n        skip_reprompt = False,\n        speak = True,\n        debug = False,\n        gpt3only = False,\n        gpt4only = True,\n        memory_type = 'local',\n        browser_name = 'safari',\n        allow_downloads = True,\n        skip_news = True,\n        workspace_directory = os.path.expanduser('~/Auto-GPT/andrew_space'),\n        install_plugin_deps = True,\n    )\n    assert True\n```\n\nIt actually run AutoGPT by pytest mock and browser automation.\n\n```python\nimport ipymock\nimport ipymock.browser\nimport ipymock.llm\nimport pytest\n\n# reset conversation_id to empty to start a new chat\nipymock.browser.common.conversation_id = ''\nipymock.browser.init()\n\n@pytest.fixture\ndef reset_embed_dimension(monkeypatch):\n    import autogpt.memory.local\n    monkeypatch.setattr(autogpt.memory.local, 'EMBED_DIM', 1024)\n\nipymock.do(\n    mock_openai = ipymock.browser.mock_openai,\n    mock_openai_embed = ipymock.llm.mock_openai_embed,\n    reset_embed_dimension = reset_embed_dimension,\n    test_auto_gpt = test_auto_gpt,\n)\n```\n\nThis project is still under development and lack of documentation.\n\nThis is [an article](https://seii-saintway.github.io/2023/04/06/Autonomous-Agents/) I wrote that mock openai to test autonomous robots.\n\n## The Mechanism of PyTesting the Python Testfiles\n\n```python\nimport pluggy\npm = pluggy.PluginManager('pytest')\n\nimport _pytest.hookspec\npm.add_hookspecs(_pytest.hookspec)\n\nimport _pytest.main\npm.register(_pytest.main, 'main')\n\nimport _pytest.config\ncfg = _pytest.config.get_config()\ncfg.parse(args=[])\npm.hook.pytest_cmdline_main(config=cfg)\n```\n\n```python\nimport _pytest.config\ncfg = _pytest.config.get_config()\ncfg.parse(args=[])\ncfg.pluginmanager.hook.pytest_cmdline_main(config=cfg)\n```\n\n### PyTesting the Python Testcases within iPyNb Runtimes\n\n```python\n# content of test_time.py\n\nimport pytest\n\nfrom datetime import datetime, timedelta\n\n\ntestdata = [\n    (datetime(2001, 12, 12), datetime(2001, 12, 11), timedelta(1)),\n    (datetime(2001, 12, 11), datetime(2001, 12, 12), timedelta(-1)),\n]\n\n\ndef idfn(val):\n    if isinstance(val, (datetime,)):\n        # note this wouldn't show any hours/minutes/seconds\n        return val.strftime('%Y%m%d')\n\n\n@pytest.mark.parametrize('a,b,expected', testdata)\ndef test_timedistance_v0(a, b, expected):\n    diff = a - b\n    assert diff == expected\n\n\n@pytest.mark.parametrize('a,b,expected', testdata, ids=['forward', 'backward'])\ndef test_timedistance_v1(a, b, expected):\n    diff = a - b\n    assert diff == expected\n\n\n@pytest.mark.parametrize('a,b,expected', testdata, ids=idfn)\ndef test_timedistance_v2(a, b, expected):\n    diff = a - b\n    assert diff == expected\n\n\n@pytest.mark.parametrize(\n    'a,b,expected',\n    [\n        pytest.param(\n            datetime(2001, 12, 12), datetime(2001, 12, 11), timedelta(1), id='forward'\n        ),\n        pytest.param(\n            datetime(2001, 12, 11), datetime(2001, 12, 12), timedelta(-1), id='backward'\n        ),\n    ],\n)\ndef test_timedistance_v3(a, b, expected):\n    diff = a - b\n    assert diff != expected\n```\n\n```python\nimport _pytest.config\ncfg = _pytest.config.get_config()\ncfg.parse(args=[])\n\nimport _pytest.main\nss = _pytest.main.Session.from_config(cfg)\nimport _pytest.runner\nss._setupstate = _pytest.runner.SetupState()\nimport _pytest.fixtures\nss._fixturemanager = _pytest.fixtures.FixtureManager(ss)\n\nimport _pytest.python\nimport py\nm = _pytest.python.Module.from_parent(parent=ss, fspath=py.path.local())\n```\n\n```python\nclass Object(object):\n    def __init__(self, **entries):\n        self.__dict__.update(entries)\nm.obj = Object(**globals())\n```\n\n```python\nimport _pytest.runner\nc = dict(enumerate(m.collect()))\nfor i in c:\n    print(f'idx = {i}')\n    print(_pytest.runner.call_and_report(c[i], 'setup'))\n    print(_pytest.runner.call_and_report(c[i], 'call'))\n    print(_pytest.runner.call_and_report(c[i], 'teardown', nextitem=c.get(i+1)))\n```\n\n    idx = 0\n    \u003cTestReport '::unittests::test_timedistance_v0[a0-b0-expected0]' when='setup' outcome='passed'\u003e\n    \u003cTestReport '::unittests::test_timedistance_v0[a0-b0-expected0]' when='call' outcome='passed'\u003e\n    \u003cTestReport '::unittests::test_timedistance_v0[a0-b0-expected0]' when='teardown' outcome='passed'\u003e\n    idx = 1\n    \u003cTestReport '::unittests::test_timedistance_v0[a1-b1-expected1]' when='setup' outcome='passed'\u003e\n    \u003cTestReport '::unittests::test_timedistance_v0[a1-b1-expected1]' when='call' outcome='passed'\u003e\n    \u003cTestReport '::unittests::test_timedistance_v0[a1-b1-expected1]' when='teardown' outcome='passed'\u003e\n    idx = 2\n    \u003cTestReport '::unittests::test_timedistance_v1[forward]' when='setup' outcome='passed'\u003e\n    \u003cTestReport '::unittests::test_timedistance_v1[forward]' when='call' outcome='passed'\u003e\n    \u003cTestReport '::unittests::test_timedistance_v1[forward]' when='teardown' outcome='passed'\u003e\n    idx = 3\n    \u003cTestReport '::unittests::test_timedistance_v1[backward]' when='setup' outcome='passed'\u003e\n    \u003cTestReport '::unittests::test_timedistance_v1[backward]' when='call' outcome='passed'\u003e\n    \u003cTestReport '::unittests::test_timedistance_v1[backward]' when='teardown' outcome='passed'\u003e\n    idx = 4\n    \u003cTestReport '::unittests::test_timedistance_v2[20011212-20011211-expected0]' when='setup' outcome='passed'\u003e\n    \u003cTestReport '::unittests::test_timedistance_v2[20011212-20011211-expected0]' when='call' outcome='passed'\u003e\n    \u003cTestReport '::unittests::test_timedistance_v2[20011212-20011211-expected0]' when='teardown' outcome='passed'\u003e\n    idx = 5\n    \u003cTestReport '::unittests::test_timedistance_v2[20011211-20011212-expected1]' when='setup' outcome='passed'\u003e\n    \u003cTestReport '::unittests::test_timedistance_v2[20011211-20011212-expected1]' when='call' outcome='passed'\u003e\n    \u003cTestReport '::unittests::test_timedistance_v2[20011211-20011212-expected1]' when='teardown' outcome='passed'\u003e\n    idx = 6\n    \u003cTestReport '::unittests::test_timedistance_v3[forward]' when='setup' outcome='passed'\u003e\n    \u003cTestReport '::unittests::test_timedistance_v3[forward]' when='call' outcome='failed'\u003e\n    \u003cTestReport '::unittests::test_timedistance_v3[forward]' when='teardown' outcome='passed'\u003e\n    idx = 7\n    \u003cTestReport '::unittests::test_timedistance_v3[backward]' when='setup' outcome='passed'\u003e\n    \u003cTestReport '::unittests::test_timedistance_v3[backward]' when='call' outcome='failed'\u003e\n    \u003cTestReport '::unittests::test_timedistance_v3[backward]' when='teardown' outcome='passed'\u003e\n\n\n```python\nfor i, f in enumerate(m.collect()):\n    print(f'idx = {i}')\n    f.setup()\n    f.runtest()\n```\n\n### How to Use the Do-PyTest?\n\n```python\nimport pytest\n\n@pytest.fixture\ndef my_fixture_1(tmpdir_factory):\n    return tmpdir_factory\n\n@pytest.fixture\ndef my_fixture_2(tmpdir_factory):\n    return tmpdir_factory\n\ndef test_fixture(my_fixture_1, my_fixture_2):\n    assert my_fixture_1 == my_fixture_2\n```\n\n```python\nfrom ipymock import do\n```\n\n```python\ndo(\n    my_fixture_1=my_fixture_1,\n    my_fixture_2=my_fixture_2,\n    test_fixture=test_fixture\n)\n```\n\n    \n    =\u003e no.0  nbs::test_fixture  setup  passed\n    \n    =\u003e no.0  nbs::test_fixture  runtest  passed\n    \n\n\n## Troubleshooting Tips of NbDev\n\n-  Make sure you are using the latest version of nbdev with `pip install --upgrade nbdev`\n-  If you are using an older version of this template, see the instructions above on how to upgrade your template. \n-  It is important for you to spell the name of your user and repo correctly in `settings.ini` or the website will not have the correct address from which to source assets like CSS for your site.  When in doubt, you can open your browser's developer console and see if there are any errors related to fetching assets for your website due to an incorrect URL generated by misspelled values from `settings.ini`.\n-  If you change the name of your repo, you have to make the appropriate changes in `settings.ini`\n-  After you make changes to `settings.ini`, run `nbdev_build_lib \u0026\u0026 nbdev_clean_nbs \u0026\u0026 nbdev_build_docs` to make sure all changes are propagated appropriately.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fseii-saintway%2Fipymock","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fseii-saintway%2Fipymock","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fseii-saintway%2Fipymock/lists"}