Full Code of vinayak-mehta/conrad for AI

master 8812d35c82af cached
55 files
432.3 KB
125.6k tokens
69 symbols
1 requests
Download .txt
Showing preview only (452K chars total). Download the full file or copy to clipboard to get everything.
Repository: vinayak-mehta/conrad
Branch: master
Commit: 8812d35c82af
Files: 55
Total size: 432.3 KB

Directory structure:
gitextract_yyr6quhs/

├── .github/
│   ├── actions/
│   │   └── get-events-action/
│   │       ├── Dockerfile
│   │       ├── action.yml
│   │       └── entrypoint.sh
│   └── workflows/
│       └── main.yml
├── .gitignore
├── .readthedocs.yml
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── HISTORY.md
├── LICENSE
├── README.md
├── conrad/
│   ├── __init__.py
│   ├── __main__.py
│   ├── __version__.py
│   ├── cli.py
│   ├── db.py
│   ├── models.py
│   ├── schema.py
│   └── utils.py
├── crawlers/
│   ├── __init__.py
│   ├── base.py
│   ├── confs_tech/
│   │   ├── __init__.py
│   │   └── confs_tech_crawler.py
│   ├── italy/
│   │   ├── __init__.py
│   │   └── italy_crawler.py
│   ├── papercall/
│   │   ├── __init__.py
│   │   └── papercall_crawler.py
│   ├── pycon/
│   │   ├── __init__.py
│   │   └── pycon_crawler.py
│   ├── pydata/
│   │   ├── __init__.py
│   │   └── pydata_crawler.py
│   └── python/
│       ├── __init__.py
│       └── python_crawler.py
├── data/
│   ├── confstech.json
│   ├── events.json
│   ├── events_v2.json
│   ├── italy.json
│   ├── pycon.json
│   ├── pydata.json
│   └── python.json
├── docs/
│   ├── Makefile
│   ├── _templates/
│   │   ├── hacks.html
│   │   ├── sidebarintro.html
│   │   └── sidebarlogo.html
│   ├── _themes/
│   │   ├── .gitignore
│   │   ├── LICENSE
│   │   └── flask_theme_support.py
│   ├── conf.py
│   ├── dev/
│   │   ├── adding-crawlers.rst
│   │   └── adding-events.rst
│   ├── index.rst
│   └── make.bat
├── setup.py
└── tests/
    ├── test_conrad.py
    └── test_geocoding.py

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/actions/get-events-action/Dockerfile
================================================
FROM python:3.12

COPY entrypoint.sh /entrypoint.sh

ENTRYPOINT ["/entrypoint.sh"]


================================================
FILE: .github/actions/get-events-action/action.yml
================================================
name: "Get events"
description: "Get latest events and raise a PR"
inputs:
  crawler-name: # id of input
    description: "Crawler to run"
    required: true
    default: "PyConCrawler"
runs:
  using: "docker"
  image: "Dockerfile"
  args:
    - ${{ inputs.crawler-name }}


================================================
FILE: .github/actions/get-events-action/entrypoint.sh
================================================
#!/bin/sh -l

python -m pip install ".[all]"

python -m conrad run crawler $1

FILENAME="data/`echo $1 | awk '{print tolower($0)}' | sed -e 's/crawler//g'`.json"
python -m conrad import -f $FILENAME


================================================
FILE: .github/workflows/main.yml
================================================
name: Get events
on:
  schedule:
    - cron: "0 0 * * 1,4"
  workflow_dispatch:

jobs:
  get_events:
    name: Get events
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Save google service account credentials
        shell: bash
        env:
          GOOGLE_SERVICE_ACCOUNT_CREDENTIALS: ${{ secrets.GOOGLE_SERVICE_ACCOUNT_CREDENTIALS }}
        run: 'echo "$GOOGLE_SERVICE_ACCOUNT_CREDENTIALS" > google_service_account_credentials.json'
      - id: python
        name: Get Python events
        uses: ./.github/actions/get-events-action
        with:
          crawler-name: "Python"
      - id: pycon
        name: Get PyCon events
        uses: ./.github/actions/get-events-action
        with:
          crawler-name: "PyCon"
      - id: pydata
        name: Get PyData events
        uses: ./.github/actions/get-events-action
        with:
          crawler-name: "PyData"
      - id: confs_tech
        name: Get confs.tech events
        uses: ./.github/actions/get-events-action
        with:
          crawler-name: "ConfsTech"
      - name: Create pull request
        uses: peter-evans/create-pull-request@v3
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          title: "Update events list"
          body: Here's the latest event list!
          commit-message: Update events list
          branch: "update-events"
          base: master


================================================
FILE: .gitignore
================================================
# VS Code
.vscode/

# Database
*conrad.db

# Secrets
*credentials.json
*token.pickle
*google_service_account_credentials.json

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
#  Usually these files are written by a python script from a template
#  before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
.pytest_cache/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py
db.sqlite3

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
target/

# Jupyter Notebook
.ipynb_checkpoints

# pyenv
.python-version

# celery beat schedule file
celerybeat-schedule

# SageMath parsed files
*.sage.py

# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/


================================================
FILE: .readthedocs.yml
================================================
# .readthedocs.yml
# Read the Docs configuration file
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details

# Required
version: 2

# Build documentation in the docs/ directory with Sphinx
sphinx:
  configuration: docs/conf.py

# Build documentation with MkDocs
#mkdocs:
#  configuration: mkdocs.yml

# Optionally build your docs in additional formats such as PDF
formats:
  - pdf

# Optionally set the version of Python and requirements required to build your docs
python:
  version: 3.8
  install:
    - method: pip
      path: .
      extra_requirements:
        - dev


================================================
FILE: CODE_OF_CONDUCT.md
================================================
Be cordial or be on your way. --Kenneth Reitz

https://www.kennethreitz.org/essays/be-cordial-or-be-on-your-way


================================================
FILE: CONTRIBUTING.md
================================================
# Contributor's Guide

If you're reading this, you're probably looking to contribute to conrad. *Time is the only real currency*, and the fact that you're considering spending some here is *very* generous of you. Thank you very much!

This document will help you get started with contributing code, testing (future) and filing issues. If you have any questions, feel free to reach out to [Vinayak Mehta](https://vinayak-mehta.github.io), the author and maintainer.

## Code Of Conduct

The following quote sums up the **Code Of Conduct**.

   > Be cordial or be on your way. --Kenneth Reitz

As the [Requests Code Of Conduct](https://github.com/psf/requests/blob/master/CODE_OF_CONDUCT.md) states, **all contributions are welcome**, as long as everyone involved is treated with respect.

## Your first contribution

A great way to start contributing to conrad is to pick an issue with the [good first issue](https://github.com/vinayak-mehta/conrad/labels/good%20first%20issue) label. If you're unable to find a good first issue, feel free to contact the maintainer.

## Setting up a development environment

To install the dependencies needed for development, you can use pip:

<pre>
$ pip install conference-radar[dev]
</pre>

Alternatively, you can clone the project repository, and install using pip:

<pre>
$ pip install ".[dev]"
</pre>

## Pull Requests

### Submit a pull request

The preferred workflow for contributing to conrad is to fork the [project repository](https://github.com/vinayak-mehta/conrad) on GitHub, clone, develop on a branch and then finally submit a pull request. Here are the steps:

1. Fork the project repository. Click on the ‘Fork’ button near the top of the page. This creates a copy of the code under your account on the GitHub.

2. Clone your fork of conrad from your GitHub account:

<pre>
$ git clone https://www.github.com/[username]/conrad
</pre>

3. Create a branch to hold your changes:

<pre>
$ git checkout -b my-feature
</pre>

Always branch out from `master` to work on your contribution. It's good practice to never work on the `master` branch!

**Protip: `git stash` is a great way to save the work that you haven't committed yet, to move between branches.**

4. Work on your contribution. Add changed files using `git add` and then `git commit` them:

<pre>
$ git add modified_files
$ git commit
</pre>

5. Finally, push them to your GitHub fork:

<pre>
$ git push -u origin my-feature
</pre>

Now it's time to go to the your fork of conrad and create a pull request! You can [follow these instructions](https://help.github.com/articles/creating-a-pull-request-from-a-fork/) to do this.

### Work on your pull request

It is recommended that your pull request complies with the following rules:

- Make sure your code follows [pep8](http://pep8.org). You should [blacken](https://github.com/psf/black) your code.

- Make sure your commit messages follow [the seven rules of a great git commit message](https://chris.beams.io/posts/git-commit/):
    - Separate subject from body with a blank line
    - Limit the subject line to 50 characters
    - Capitalize the subject line
    - Do not end the subject line with a period
    - Use the imperative mood in the subject line
    - Wrap the body at 72 characters
    - Use the body to explain what and why vs. how

- Please prefix the title of your pull request with [MRG] (Ready for Merge), if the contribution is complete and ready for a detailed review. An incomplete pull request's title should be prefixed with [WIP] (to indicate a work in progress), and changed to [MRG] when it's complete. A good [task list](https://blog.github.com/2013-01-09-task-lists-in-gfm-issues-pulls-comments/) in the PR description will ensure that other people get a better idea of what it proposes to do, which will also increase collaboration.

- If contributing new functionality, make sure that you add a unit test for it, while making sure that all previous tests pass. conrad uses [pytest](https://docs.pytest.org/en/latest/) for testing (future). Tests can be run using:

<pre>
$ python setup.py test
</pre>

## Filing Issues

[GitHub issues](https://github.com/vinayak-mehta/conrad/issues) are used to keep track of all issues and pull requests. Before opening an issue (which asks a question or reports a bug), please use GitHub search to look for existing issues (both open and closed) that may be similar.

### Bug Reports

In bug reports, make sure you include:

- Your operating system type and Python version:

<pre>
import platform; print(platform.platform())
import sys; print('Python', sys.version)
</pre>

- The complete traceback. Just adding the exception message or a part of the traceback won't help the maintainer fix your issue sooner.


================================================
FILE: HISTORY.md
================================================
Release History
===============

master
------

0.10.2 (2024-12-22)
-------------------

* Minor fixes.


0.10.1 (2021-08-01)
-------------------

* Show grid on table and hide state from output.

0.10.0 (2021-08-01)
-------------------

**Improvements**

* [#203](https://github.com/vinayak-mehta/conrad/pull/203) Add rich tables.

**Bugfixes**

* Fix reminder deletion bug on auto refresh.

0.9.1 (2021-06-24)
------------------

**Bugfixes**

* Fix `ImportError` caused by missing crawl requirements.

0.9.0 (2021-06-21)
------------------

**Improvements**

* Add `generate` and `run` commands to make crawler addition easy.

0.8.0 (2020-08-01)
------------------

**Bugfixes**

* New release because 0.7.1 doesn't show up as latest on PyPI.

0.7.1 (2020-08-01)
------------------

**Bugfixes**

* [#147](https://github.com/vinayak-mehta/conrad/issues/147) conrad show throws sqlalchemy.exc.OperationalError on upgrading to 0.7.0. [83f4e3b](https://github.com/vinayak-mehta/conrad/commit/83f4e3b4ebaa0be581418039dfcbb5ce89327194) by Vinayak Mehta.

0.7.0 (2020-08-01)
------------------

**Improvements**

* [#138](https://github.com/vinayak-mehta/conrad/issues/138) Add crawler for [Python events calendar](https://wiki.python.org/moin/PythonEventsCalendar). [#139](https://github.com/vinayak-mehta/conrad/pull/139) by Vinayak Mehta.
* [#142](https://github.com/vinayak-mehta/conrad/issues/142) Add support for multiple event schema versions. [#143](https://github.com/vinayak-mehta/conrad/pull/143) by Vinayak Mehta.
* [#37](https://github.com/vinayak-mehta/conrad/issues/37) Add nominatim geocoder util to standardize location. [#102](https://github.com/vinayak-mehta/conrad/pull/102) by [Sangarshanan](https://github.com/Sangarshanan).
* [#36](https://github.com/vinayak-mehta/conrad/issues/36) Add check for new conrad version. [#61](https://github.com/vinayak-mehta/conrad/pull/61) by [Abhi Baireddy](https://github.com/abhi-baireddy) and Vinayak Mehta.
* Add `--kind` filter for the `show` command. [#137](https://github.com/vinayak-mehta/conrad/pull/137) by Vinayak Mehta.
* [d3db41b](https://github.com/vinayak-mehta/conrad/commit/d3db41b777ab5a0b3d6734bbde33865842304854) Update .readthedocs.yml and remove requirements.txt
* Change auto-refresh interval from 1 day to 1 week.

0.6.2 (2020-07-28)
------------------

* Unpin requirements.

0.6.1 (2020-07-10)
------------------

* Add py38 trove classifier.

0.6.0 (2020-07-10)
------------------

**Improvements**

* [#46](https://github.com/vinayak-mehta/conrad/issues/46) Highlight events on conrad show for which reminders have been set. [225972d](https://github.com/vinayak-mehta/conrad/commit/225972d4ca505832cdcb2009b2c81cd0588d1532) by Vinayak Mehta.

0.5.0 (2020-07-09)
------------------

**Improvements**

* Add `--id` filter for the `show` command.
* Automatically set cfp flag to False if date has passed and don't import old events in the `import` command.

0.4.0 (2020-05-24)
------------------

**Improvements**

* Replace `.format` with f-strings! [5d5a917](https://github.com/vinayak-mehta/conrad/commit/5d5a9172231602427d7a959a7f3bbd3508d62a9a)
* Use [click.get_app_dir](https://github.com/vinayak-mehta/conrad/commit/6f2da95d85a7624568ae47cfe3348adca15629bf) for `CONRAD_HOME`.
* Fix days left [comparison operators](https://github.com/vinayak-mehta/conrad/commit/b4ffc0d54ded8dd9ae94ecd9202715512264583b).
* [#100](https://github.com/vinayak-mehta/conrad/issues/100) Use start date when cfp date has passed. [5d5a917](https://github.com/vinayak-mehta/conrad/commit/5d5a9172231602427d7a959a7f3bbd3508d62a9a) by Vinayak Mehta.
* [#85](https://github.com/vinayak-mehta/conrad/issues/85) Add crawler for awesome-italy-events. [#91](https://github.com/vinayak-mehta/conrad/pull/91) by Vinayak Mehta.

0.3.2 (2019-11-08)
------------------

* Json dump event tags.

0.3.1 (2019-11-08)
------------------

**Bugfixes**

* [#81](https://github.com/vinayak-mehta/conrad/issues/81) FileNotFoundError on first conrad show. [#82](https://github.com/vinayak-mehta/conrad/pull/82) by Vinayak Mehta.

0.3.0 (2019-11-08)
------------------

**Improvements**

* [#10](https://github.com/vinayak-mehta/conrad/issues/10), [#33](https://github.com/vinayak-mehta/conrad/issues/33), [#58](https://github.com/vinayak-mehta/conrad/issues/58) Add auto refresh. [#78](https://github.com/vinayak-mehta/conrad/pull/78) by Vinayak Mehta.
* Remove deprecated fields. [#77](https://github.com/vinayak-mehta/conrad/pull/77) by Vinayak Mehta.
* Update PyCon Crawler. [#73](https://github.com/vinayak-mehta/conrad/pull/73) by Vinayak Mehta.
* Enable GitHub Actions and Add BaseCrawler. [#70](https://github.com/vinayak-mehta/conrad/pull/70) by Vinayak Mehta.
* [#11](https://github.com/vinayak-mehta/conrad/issues/11) Upgrade duplicate finding logic with edit distance. [#68](https://github.com/vinayak-mehta/conrad/pull/68) by [Josemy Duarte](https://github.com/JosemyDuarte).
* [#15](https://github.com/vinayak-mehta/conrad/issues/15) Add PyData crawler. [#49](https://github.com/vinayak-mehta/conrad/pull/49) by [Cristhian Motoche](https://github.com/CristhianMotoche).

**Bugfixes**

* [#66](https://github.com/vinayak-mehta/conrad/pull/57) Initialize conrad context before executing remind. [#67](https://github.com/vinayak-mehta/conrad/pull/67) by [Josemy Duarte](https://github.com/JosemyDuarte).

**Documentation**

* Add docs for extending BaseCrawler.

0.2.0 (2019-10-31)
------------------

**Improvements**

* Remove prettytable and use cli_helpers. [#57](https://github.com/vinayak-mehta/conrad/pull/57) by Vinayak Mehta.
* [#44](https://github.com/vinayak-mehta/conrad/issues/44) Add id column to conrad remind output. [#47](https://github.com/vinayak-mehta/conrad/pull/47) by [Shalini Sreedhar](https://github.com/shalini-s).
* [#23](https://github.com/vinayak-mehta/conrad/issues/23) Add help text to all commands. [#30](https://github.com/vinayak-mehta/conrad/pull/30) by [Josemy Duarte](https://github.com/JosemyDuarte).
* Enable [continous quality](https://deepsource.io/gh/vinayak-mehta/conrad/?ref=repository-badge) by DeepSource.
* Add more conferences.

0.1.2 (2019-10-28)
------------------

**Improvements**

* Add more conferences. [#26](https://github.com/vinayak-mehta/conrad/pull/26) by [Sangarshanan](https://github.com/Sangarshanan).

**Bugfixes**

* [#8](https://github.com/vinayak-mehta/conrad/issues/8) Error in opening database before first refresh. [#14](https://github.com/vinayak-mehta/conrad/pull/14) by Vinayak Mehta.

0.1.1 (2019-10-28)
------------------

**Documentation**

* Add README fixes.

0.1.0 (2019-10-28)
------------------

* Birth!


================================================
FILE: LICENSE
================================================
                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright 2021 Vinayak Mehta

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.


================================================
FILE: README.md
================================================
<p align="center">
   <img src="https://raw.githubusercontent.com/vinayak-mehta/conrad/master/docs/_static/mozilla-satellite-antenna.png" width="200">
</p>

# conrad — Conference Radar

[![Workflow Status](https://github.com/vinayak-mehta/conrad/workflows/Get%20events/badge.svg)](https://github.com/vinayak-mehta/conrad/actions) [![Documentation Status](https://readthedocs.org/projects/conference-radar/badge/?version=latest)](https://conference-radar.readthedocs.io/en/latest/) [![image](https://img.shields.io/pypi/v/conference-radar.svg)](https://pypi.org/project/conference-radar/) [![image](https://img.shields.io/pypi/pyversions/conference-radar.svg)](https://pypi.org/project/conference-radar/) [![image](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black)

`conrad` helps you track conferences and meetups on your terminal.

---

Here's how it works:

<pre>
$ conrad show
</pre>

![show](https://raw.githubusercontent.com/vinayak-mehta/conrad/master/docs/_static/show.png)

## Why conrad?

- 📅 Never miss CFP deadlines again. `conrad remind` can remind you every time you open a terminal!
- 📊 Query and explore events using tags, names, locations, and dates. `conrad show --cfp` will tell you about events where the CFP is open!
- 🤖 Crawlers update events twice a week! (Monday and Thursday at 00:00 UTC)

## Installation

You can simply use pip to install `conrad`:

<pre>
$ pip install conference-radar
</pre>

## Features

### Continuous updates

The event list is maintained in `data/events.json`. This list is continuously updated by the available `crawlers` using GitHub Actions.

Sources:

- https://confs.tech
- https://pydata.org/event-schedule
- https://github.com/python-organizers/conferences
- https://wiki.python.org/moin/PythonEventsCalendar

### Set reminders

You can set CFP reminders so that you never miss a deadline! The color changes based on event proximity; **> 30 days** ![#008000](https://placehold.it/15/008000/000000?text=+), **>10 and < 30 days** ![#ffff00](https://placehold.it/15/ffff00/000000?text=+) and **< 10 days** ![#ff0000](https://placehold.it/15/ff0000/000000?text=+).

<pre>
$ conrad remind -i 6bb714
$ conrad remind
</pre>

![remind](https://raw.githubusercontent.com/vinayak-mehta/conrad/master/docs/_static/remind.png)

**Protip**: Add `conrad remind` to your shell startup file so that you get a reminder every time you open a new terminal!

### Query and explore

You can query and explore the event database using various filters.

Look at events which have an open call for proposals (CFP):

<pre>
$ conrad show --cfp
</pre>

![show-cfp](https://raw.githubusercontent.com/vinayak-mehta/conrad/master/docs/_static/show-cfp.png)

Look at conferences using a tag:

<pre>
$ conrad show --tag python
</pre>

![show-tag](https://raw.githubusercontent.com/vinayak-mehta/conrad/master/docs/_static/show-tag.png)

Look at conferences using a name:

<pre>
$ conrad show --name pycon
</pre>

![show-name](https://raw.githubusercontent.com/vinayak-mehta/conrad/master/docs/_static/show-name.png)

Look at conferences in a city, state or country:

<pre>
$ conrad show --location usa
</pre>

![show-location](https://raw.githubusercontent.com/vinayak-mehta/conrad/master/docs/_static/show-location.png)

Look at conferences based on when they're happening:

<pre>
$ conrad show --date ">= 2019-10-01" --date "<= 2020-01-01"
</pre>

![show-date](https://raw.githubusercontent.com/vinayak-mehta/conrad/master/docs/_static/show-date.png)

### Refresh event database

You can get the latest events using:

<pre>
$ conrad refresh
</pre>

![refresh](https://raw.githubusercontent.com/vinayak-mehta/conrad/master/docs/_static/refresh.png)

## Contributing

The [Contributor's Guide](https://github.com/vinayak-mehta/conrad/blob/master/CONTRIBUTING.md) has detailed information about guidelines around contributions. You can add new crawlers and events to `conrad`:

- [Adding a crawler](https://conference-radar.readthedocs.io/en/latest/dev/adding-crawlers.html)
- [Adding new events](https://conference-radar.readthedocs.io/en/latest/dev/adding-events.html)

## Versioning

`conrad` uses [Semantic Versioning](https://semver.org/). For the available versions, see the tags on this repository.

## License

This project is licensed under the Apache License, see the [LICENSE](https://github.com/vinayak-mehta/conrad/blob/master/LICENSE) file for details.


================================================
FILE: conrad/__init__.py
================================================
# -*- coding: utf-8 -*-

import os

from click import get_app_dir

from .__version__ import __version__


CONRAD_HOME = get_app_dir("conrad")
SQL_ALCHEMY_CONN = f"sqlite:///{CONRAD_HOME}/conrad.db"

if not os.path.exists(CONRAD_HOME):
    os.makedirs(CONRAD_HOME)


================================================
FILE: conrad/__main__.py
================================================
# -*- coding: utf-8 -*-

from .utils import conrad_self_version_check


__all__ = ("main",)


def main():
    from conrad.cli import cli

    conrad_self_version_check()
    cli()


if __name__ == "__main__":
    main()


================================================
FILE: conrad/__version__.py
================================================
# -*- coding: utf-8 -*-

VERSION = (0, 10, 2)
PRERELEASE = None  # alpha, beta or rc
REVISION = None


def generate_version(version, prerelease=None, revision=None):
    version_parts = [".".join(map(str, version))]
    if prerelease is not None:
        version_parts.append(f"-{prerelease}")
    if revision is not None:
        version_parts.append(f".{revision}")
    return "".join(version_parts)


__title__ = "conference-radar"
__description__ = "Track conferences and meetups on your terminal."
__url__ = "https://github.com/vinayak-mehta/conrad"
__version__ = generate_version(VERSION, prerelease=PRERELEASE, revision=REVISION)
__author__ = "Vinayak Mehta"
__author_email__ = "vmehta94@gmail.com"
__license__ = "Apache 2.0"


================================================
FILE: conrad/cli.py
================================================
# -*- coding: utf-8 -*-

import datetime as dt
import hashlib
import inspect
import json
import os
import re
import shutil
import sys

import click
import requests
import sqlalchemy
import textdistance
from rich.console import Console
from rich.table import Table

try:
    import bs4
    import cerberus
    import git
    import googleapiclient
    import pandas
except ImportError:
    _HAS_CRAWL_REQUIREMENTS = False
else:
    _HAS_CRAWL_REQUIREMENTS = True

if _HAS_CRAWL_REQUIREMENTS:
    import crawlers
    from crawlers import *

from . import CONRAD_HOME, __version__
from .db import Session, engine
from .models import Base, Event, Reminder
from .schema import *
from .utils import apply_schema, initialize_database, mkdir, validate_events

DATE_FMT = "%Y-%m-%dT%H:%M:%S"


def has_less():
    return shutil.which("less")


def set_default_pager():
    if has_less() is not None:
        os.environ["LESS"] = "-SRXF"


def get_events():
    click.echo("Fetching latest events.")

    events_filename = eval(f"f{LATEST}")
    response = requests.get(
        f"https://raw.githubusercontent.com/vinayak-mehta/conrad/master/data/{events_filename}",
        timeout=5,
    )
    with open(os.path.join(CONRAD_HOME, events_filename), "w") as f:
        f.write(json.dumps(response.json()))


def rebuild_events_table():
    events_filename = eval(f"f{LATEST}")
    with open(os.path.join(CONRAD_HOME, events_filename), "r") as f:
        events = json.load(f)

    session = Session()
    for event in events:
        event_id = hashlib.md5(
            (event["name"] + event["start_date"]).encode("utf-8")
        ).hexdigest()
        e = Event(
            id=event_id[:6],
            name=event["name"],
            url=event["url"],
            city=event["city"],
            state=event["state"],
            country=event["country"],
            location=event["location"],
            cfp_open=event["cfp_open"],
            cfp_end_date=dt.datetime.strptime(event["cfp_end_date"], "%Y-%m-%d"),
            start_date=dt.datetime.strptime(event["start_date"], "%Y-%m-%d"),
            end_date=dt.datetime.strptime(event["end_date"], "%Y-%m-%d"),
            source=event["source"],
            tags=json.dumps(event["tags"]),
            kind=event["kind"],
            by=event["by"],
        )
        session.add(e)
        session.commit()
    session.close()


def set_update_timestamp(overwrite=False):
    updated_at = os.path.join(CONRAD_HOME, ".updated_at")
    if overwrite or not os.path.exists(updated_at):
        with open(updated_at, "w") as f:
            f.write(dt.datetime.now().strftime(DATE_FMT))


def initialize_conrad():
    set_update_timestamp()

    if not os.path.exists(os.path.join(CONRAD_HOME, "conrad.db")):
        get_events()
        initialize_database()
        rebuild_events_table()


def refresh_conrad():
    get_events()
    if not os.path.exists(os.path.join(CONRAD_HOME, "conrad.db")):
        initialize_database()
    else:
        Event.__table__.drop(engine)
        Base.metadata.tables["event"].create(bind=engine)
    rebuild_events_table()
    set_update_timestamp(overwrite=True)


def clean_old_events():
    session = Session()

    now = dt.datetime.now()
    reminders = list(
        session.query(Event, Reminder)
        .filter(Event.id == Reminder.id, Event.end_date < now)
        .all()
    )
    for r, __ in reminders:
        session.query(Reminder).filter(Reminder.id == r.id).delete()

    events = list(session.query(Event).filter(Event.end_date < now).all())
    for e in events:
        session.query(Event).filter(Event.id == e.id).delete()

    session.commit()
    session.close()


def auto_refresh():
    try:
        updated_at = os.path.join(CONRAD_HOME, ".updated_at")
        with open(updated_at, "r") as f:
            last_updated_at = dt.datetime.strptime(f.read().strip(), DATE_FMT)
    except (IOError, FileNotFoundError):
        last_updated_at = dt.datetime.strptime("1970-01-01T00:00:00", DATE_FMT)

    if (dt.datetime.now() - last_updated_at) > dt.timedelta(days=7):
        refresh_conrad()
        clean_old_events()


# https://stackoverflow.com/a/50889894
def make_exclude_hook_command(callback):
    """for any command that is not decorated, call the callback"""
    hook_attr_name = "hook_" + callback.__name__

    class HookGroup(click.Group):
        """group to hook context invoke to see if the callback is needed"""

        def group(self, *args, **kwargs):
            """new group decorator to make sure sub groups are also hooked"""
            if "cls" not in kwargs:
                kwargs["cls"] = type(self)
            return super(HookGroup, self).group(*args, **kwargs)

        def command(self, *args, **kwargs):
            """new command decorator to monkey patch command invoke"""

            cmd = super(HookGroup, self).command(*args, **kwargs)

            def hook_command_decorate(f):
                # decorate the command
                ret = cmd(f)

                # grab the original command invoke
                orig_invoke = ret.invoke

                def invoke(ctx):
                    """call the call back right before command invoke"""
                    parent = ctx.parent
                    sub_cmd = (
                        parent and parent.command.commands[parent.invoked_subcommand]
                    )
                    if (
                        not sub_cmd
                        or not isinstance(sub_cmd, click.Group)
                        and getattr(sub_cmd, hook_attr_name, True)
                    ):
                        # invoke the callback
                        callback()
                    return orig_invoke(ctx)

                # hook our command invoke to command and return cmd
                ret.invoke = invoke
                return ret

            # return hooked command decorator
            return hook_command_decorate

    def decorator(func=None):
        if func is None:
            # if called other than as decorator, return group class
            return HookGroup

        setattr(func, hook_attr_name, False)

    return decorator


bypass_auto_refresh = make_exclude_hook_command(auto_refresh)


@click.group(name="conrad", cls=bypass_auto_refresh())
@click.version_option(version=__version__)
@click.pass_context
def cli(ctx, *args, **kwargs):
    """conrad: Track conferences and meetups on your terminal."""
    set_default_pager()


@bypass_auto_refresh
@cli.command("refresh", short_help="Refresh event database.")
@click.confirmation_option(prompt="Would you like conrad to look for new events?")
@click.pass_context
def _refresh(ctx, *args, **kwargs):
    # TODO: print("10 new events found.")
    refresh_conrad()

    click.echo("All done! ✨ 🍰 ✨")
    click.echo("Event database updated.")


@cli.command("show", short_help="Show all saved events.")
@click.option(
    "--id",
    "-i",
    help="Show event with a particular id.",
)
@click.option(
    "--kind",
    "-k",
    help="Show kind of event, conference or meetup.",
)
@click.option(
    "--cfp",
    "-c",
    is_flag=True,
    help="Show only events which have an open CFP (call for proposals).",
)
@click.option(
    "--tag", "-t", default="", help="Look at conferences with a specific tag."
)
@click.option(
    "--name",
    "-n",
    default="",
    help="Look at conferences containing a specific word in their name.",
)
@click.option(
    "--location",
    "-l",
    default="",
    help="Look at conferences in a specific city, state or country.",
)
@click.option(
    "--date",
    "-d",
    default=[],
    multiple=True,
    help='Look at conferences based on when they\'re happening. For example: conrad show --date ">= 2019-10-01" --date "<= 2020-01-01".',
)
@click.pass_context
def _show(ctx, *args, **kwargs):
    # TODO: conrad show --new
    initialize_conrad()

    _id = kwargs["id"]
    kind = kwargs["kind"]
    cfp = kwargs["cfp"]
    tag = kwargs["tag"]
    name = kwargs["name"]
    date = list(kwargs["date"])
    location = kwargs["location"]

    filters = []
    if _id:
        filters.append(Event.id == _id)
    if kind:
        filters.append(Event.kind == kind)
    if cfp:
        filters.append(Event.cfp_open.is_(cfp))
    if tag:
        filters.append(Event.tags.contains(tag))
    if name:
        filters.append(Event.name.ilike(f"%{name}%"))
    if date:
        date_filters = []
        for d in date:
            cmp, date = d.split(" ")
            if not (">" in cmp or "<" in cmp):
                raise click.UsageError("Wrong comparison operator.")
            try:
                __ = dt.datetime.strptime(date, "%Y-%m-%d")
            except ValueError:
                raise click.UsageError("Wrong date format.")
            if ">" in cmp:
                date_filters.append(Event.start_date >= date)
            elif "<" in cmp:
                date_filters.append(Event.start_date <= date)
        filters.append(sqlalchemy.and_(*date_filters))
    if location:
        filters.append(
            sqlalchemy.or_(
                Event.name.ilike(f"%{location}%"),
                Event.city.ilike(f"%{location}%"),
                Event.state.ilike(f"%{location}%"),
                Event.country.ilike(f"%{location}%"),
                Event.location.ilike(f"%{location}%"),
            )
        )

    session = Session()
    try:
        events = list(
            session.query(Event).filter(*filters).order_by(Event.start_date).all()
        )
    except sqlalchemy.exc.OperationalError:
        refresh_conrad()
        events = list(
            session.query(Event).filter(*filters).order_by(Event.start_date).all()
        )

    if len(events) > 0:
        console = Console()
        table = Table(show_header=True, header_style="bold magenta", show_lines=True)

        table.add_column("id")
        table.add_column("Name")
        table.add_column("Website")
        table.add_column("City")
        table.add_column("Country")
        table.add_column("Start Date")
        table.add_column("End Date")

        events_output = []

        rids = [r.id for r in session.query(Reminder).all()]
        for event in events:
            event_output = [
                event.id,
                event.name,
                event.url,
                event.city,
                event.country,
                event.start_date.strftime("%Y-%m-%d"),
                event.end_date.strftime("%Y-%m-%d"),
            ]

            # highlight event which has a reminder set
            if event.id in rids:
                event_output = list(
                    map(
                        lambda x: f"[bold][green]{x}[/green][/bold]",
                        event_output,
                    )
                )

            table.add_row(*event_output)

        session.close()

        console_kwargs = {}
        if has_less():
            console_kwargs["styles"] = True

        with console.pager(**console_kwargs):
            console.print(table)
    else:
        click.echo("No events found.")


@cli.command("remind", short_help="Set and display reminders.")
@click.option("--id", "-i", default=None, help="Conference identifier.")
@click.pass_context
def _remind(ctx, *args, **kwargs):
    def get_days_left(event):
        start = dt.datetime.now()
        cfp_days_left = (event.cfp_end_date - start).days
        event_days_left = (event.start_date - start).days

        if event.cfp_open and cfp_days_left >= 0:
            days_left = cfp_days_left
        elif event_days_left >= 0:
            days_left = event_days_left
        else:
            days_left = -1

        return days_left, event.cfp_open

    initialize_conrad()

    _id = kwargs["id"]

    if _id is None:
        session = Session()
        reminders = list(
            session.query(Event, Reminder)
            .filter(Event.id == Reminder.id)
            .order_by(Event.start_date)
            .all()
        )
        if len(reminders) > 0:
            console = Console()
            table = Table(
                show_header=True, header_style="bold magenta", show_lines=True
            )

            table.add_column("id")
            table.add_column("Name")
            table.add_column("Start Date")
            table.add_column("Days Left")

            for reminder, __ in reminders:
                days_left, cfp_open = get_days_left(reminder)

                if cfp_open and days_left >= 0:
                    days_left_output = f"{days_left} days left to cfp deadline"
                elif days_left >= 0:
                    days_left_output = f"{days_left} days left"
                else:
                    days_left_output = "Event ended"

                style = "white"
                if days_left >= 30:
                    style = "green"
                elif 30 > days_left >= 10:
                    style = "yellow"
                elif 10 > days_left >= 0:
                    style = "red"

                days_left_output = f"[bold][{style}]{days_left_output}[/{style}][/bold]"
                reminder_output = [
                    reminder.id,
                    reminder.name,
                    reminder.start_date.strftime("%Y-%m-%d"),
                    days_left_output,
                ]

                table.add_row(*reminder_output)

            session.close()

            console_kwargs = {}
            if has_less():
                console_kwargs["styles"] = True

            with console.pager(**console_kwargs):
                console.print(table)
        else:
            click.echo("No reminders found.")
    else:
        try:
            session = Session()
            event = session.query(Event).filter(Event.id == _id).first()
            if event is None:
                click.echo("Event not found.")
            else:
                days_left, __ = get_days_left(event)

                if days_left == -1:
                    click.echo("Event ended.")
                else:
                    reminder = Reminder(id=event.id)
                    session.add(reminder)
                    session.commit()
                    session.close()

                    click.echo("Reminder set.")
        except sqlalchemy.exc.IntegrityError:
            session.rollback()

            if click.confirm("Do you want to remove this reminder?"):
                session = Session()
                session.query(Reminder).filter(Reminder.id == _id).delete()
                session.commit()
                session.close()

                click.echo("Reminder removed.")


@cli.command("generate", short_help="Generate skeleton crawler code.")
@click.argument("entity")
@click.argument("entity_name")
@click.pass_context
def _generate(ctx, *args, **kwargs):
    SUPPORTED_ENTITIES = ["crawler"]

    entity = kwargs["entity"]

    if entity not in SUPPORTED_ENTITIES:
        click.UsageError(f"Entity '{entity}' not supported")

    entity_name = kwargs["entity_name"]
    entity_name_snake_case = re.sub(r"(?<!^)(?=[A-Z])", "_", entity_name).lower()

    crawler_dir = f"crawlers/{entity_name_snake_case}"
    mkdir(crawler_dir)

    with open(os.path.join(crawler_dir, "__init__.py"), "w") as f:
        f.write("# -*- coding: utf-8 -*-\n")

    crawler_content = f"""# -*- coding: utf-8 -*-

from ..base import BaseCrawler


class {entity_name}Crawler(BaseCrawler):
    def get_events(self):
        # Populate this list of events using your code
        events = []

        # YOUR CODE HERE

        # Extend the self.events list with the new list
        self.events.extend(events)
"""

    crawler_path = os.path.join(crawler_dir, f"{entity_name_snake_case}_crawler.py")
    with open(crawler_path, "w") as f:
        f.write(crawler_content)

    with open("crawlers/__init__.py", "a") as f:
        f.write(
            f"from .{entity_name_snake_case}.{entity_name_snake_case}_crawler import {entity_name}Crawler"
        )

    click.echo(f"\t{click.style('create', fg='green', bold=True)}\t{crawler_path}")


@cli.command("run", short_help="Run crawler code.")
@click.argument("entity")
@click.argument("entity_name")
@click.pass_context
def _run(ctx, *args, **kwargs):
    if not _HAS_CRAWL_REQUIREMENTS:
        raise click.UsageError(
            "To run crawlers, please install the requirements with\n"
            "'pip install --upgrade conference-radar[crawl]'."
        )

    SUPPORTED_ENTITIES = ["crawler"]

    entity = kwargs["entity"]

    if entity not in SUPPORTED_ENTITIES:
        click.UsageError(f"Entity '{entity}' not supported")

    entity_name = kwargs["entity_name"]
    entity_name_snake_case = re.sub(r"(?<!^)(?=[A-Z])", "_", entity_name).lower()

    crawler = [
        m[0]
        for m in inspect.getmembers(crawlers, inspect.isclass)
        if m[1].__module__.startswith("crawlers") and m[0] == f"{entity_name}Crawler"
    ]
    if len(crawler):
        filename = crawler[0].lower().replace("crawler", "")

        Crawler = eval(crawler[0])
        c = Crawler()
        c.get_events()

        crawler_data_path = f"data/{filename}.json"
        c.export(crawler_data_path)

        click.echo(
            f"\t{click.style('save', fg='green', bold=True)}\t{crawler_data_path}"
        )
    else:
        print("Crawler not found.")


@bypass_auto_refresh
@cli.command("import", short_help="Import new events into conrad.")
@click.option("--file", "-f", default=None, help="JSON file to import.")
@click.pass_context
def _import(ctx, *args, **kwargs):
    file = kwargs["file"]

    if file is None:
        raise click.UsageError("No file provided.")

    if not os.path.exists(file):
        raise click.UsageError("File does not exist.")

    with open(file, "r") as f:
        input_events = json.load(f)

    failures = validate_events(input_events, version=LATEST)
    if len(failures) > 0:
        raise click.UsageError(
            "The following validations failed!\n{}".format(
                "".join(
                    list(map(lambda x: "- " + x + "\n", failures[:-1]))
                    + list(map(lambda x: "- " + x, failures[-1:]))
                )
            )
        )

    events_path = os.path.join(os.getcwd(), "data", f"{eval(f'f{LATEST}')}")
    try:
        with open(events_path, "r") as f:
            events = json.load(f)
    except (IOError, ValueError, KeyError, FileNotFoundError):
        events = []

    now = dt.datetime.now()
    old_events = []
    for e in events:
        event_end_date = dt.datetime.strptime(e["end_date"], "%Y-%m-%d")
        if event_end_date < now:
            print(f"Removing {e['name']}")
            continue

        if e["cfp_end_date"] is not None:
            cfp_end_date = dt.datetime.strptime(e["cfp_end_date"], "%Y-%m-%d")
            if cfp_end_date < now:
                e["cfp_open"] = False

        old_events.append(e)

    removed = len(events) - len(old_events)
    s = "s" if removed != 1 else ""
    click.echo(f"Removed {removed} old event{s}.")

    pattern = "[0-9]"
    new_events = []
    for ie in input_events:
        if ie["end_date"] is None:
            continue

        event_end_date = dt.datetime.strptime(ie["end_date"], "%Y-%m-%d")
        if event_end_date < now:
            continue

        if ie["cfp_end_date"] is not None:
            cfp_end_date = dt.datetime.strptime(ie["cfp_end_date"], "%Y-%m-%d")
            if cfp_end_date < now:
                ie["cfp_open"] = False

        match = False
        for oe in old_events:
            input_event_name = ie["name"].replace(" ", "").lower()
            input_event_name = re.sub(pattern, "", input_event_name)

            old_event_name = oe["name"].replace(" ", "").lower()
            old_event_name = re.sub(pattern, "", old_event_name)

            similarity = textdistance.levenshtein.normalized_similarity(
                input_event_name, old_event_name
            )
            if similarity > 0.9:
                click.echo(f"Updating {oe['name']}")
                oe.update(ie)
                match = True
        if not match:
            click.echo(f"Adding {ie['name']}")
            new_events.append(ie)
    old_events.extend(new_events)

    s = "s" if len(new_events) != 1 else ""
    click.echo(f"Added {len(new_events)} new event{s}.")
    with open(events_path, "w") as f:
        f.write(json.dumps(old_events, indent=4, sort_keys=True))

    for version in reversed(range(1, int(LATEST))):
        events = old_events.copy()
        events = apply_schema(events, version=version)

        events_path = os.path.join(os.getcwd(), "data", f"{eval(f'f{version}')}")
        with open(events_path, "w") as f:
            f.write(json.dumps(events, indent=4, sort_keys=True))


================================================
FILE: conrad/db.py
================================================
# -*- coding: utf-8 -*-

import atexit

from sqlalchemy import create_engine
from sqlalchemy.pool import NullPool
from sqlalchemy.orm import scoped_session, sessionmaker

from . import SQL_ALCHEMY_CONN


engine = None
Session = None


def configure_orm():
    global engine
    global Session

    engine_args = {"poolclass": NullPool}
    engine = create_engine(SQL_ALCHEMY_CONN, **engine_args)
    Session = scoped_session(
        sessionmaker(
            autocommit=False, autoflush=False, bind=engine, expire_on_commit=False
        )
    )


def dispose_orm():
    global engine
    global Session

    if Session is not None:
        Session.remove()
        Session = None
    if engine is not None:
        engine.dispose()
        engine = None


configure_orm()
atexit.register(dispose_orm)


================================================
FILE: conrad/models.py
================================================
# -*- coding: utf-8 -*-

from sqlalchemy import Boolean, Column, DateTime, String, Text, ForeignKey
from sqlalchemy.ext.declarative import declarative_base


Base = declarative_base()
ID_LEN = 100
STR_LEN = 1024


class Event(Base):
    __tablename__ = "event"

    id = Column(String(ID_LEN), primary_key=True)
    name = Column(String(STR_LEN))
    url = Column(String(STR_LEN))
    city = Column(String(STR_LEN))
    state = Column(String(STR_LEN))
    country = Column(String(STR_LEN))
    location = Column(String(STR_LEN))
    cfp_open = Column(Boolean, default=False)
    cfp_end_date = Column(DateTime)
    start_date = Column(DateTime)
    end_date = Column(DateTime)
    source = Column(String(STR_LEN))
    tags = Column(Text)
    kind = Column(String(STR_LEN))
    by = Column(String(STR_LEN))


class Reminder(Base):
    __tablename__ = "reminder"

    id = Column(String(ID_LEN), ForeignKey("event.id"), primary_key=True)


================================================
FILE: conrad/schema.py
================================================
# -*- coding: utf-8 -*-

LATEST = "2"

f1 = "events.json"
v1 = {
    "name": {"type": "string", "minlength": 1, "required": True},
    "url": {"type": "string", "minlength": 1, "required": True},
    "city": {"type": "string", "minlength": 1, "required": True},
    "state": {"type": "string", "required": True, "nullable": True},
    "country": {"type": "string", "minlength": 1, "required": True},
    "cfp_open": {"type": "boolean", "required": True},
    "cfp_end_date": {"is_date": True, "type": "string", "required": True},
    "start_date": {"is_date": True, "type": "string", "required": True},
    "end_date": {"is_date": True, "type": "string", "required": True},
    "source": {"type": "string", "minlength": 1, "required": True},
    "tags": {"type": "list", "minlength": 1, "required": True},
    "kind": {"type": "string", "allowed": ["conference", "meetup"], "required": True},
    "by": {"type": "string", "allowed": ["human", "bot"], "required": True},
}

f2 = "events_v2.json"
v2 = {
    "name": {"type": "string", "minlength": 1, "required": True},
    "url": {"type": "string", "minlength": 1, "required": True},
    "city": {"type": "string", "required": True, "nullable": True},
    "state": {"type": "string", "required": True, "nullable": True},
    "country": {"type": "string", "required": True, "nullable": True},
    "location": {"type": "string", "required": True, "nullable": True},
    "cfp_open": {"type": "boolean", "required": True},
    "cfp_end_date": {"is_date": True, "type": "string", "required": True},
    "start_date": {"is_date": True, "type": "string", "required": True},
    "end_date": {"is_date": True, "type": "string", "required": True},
    "source": {"type": "string", "minlength": 1, "required": True},
    "tags": {"type": "list", "minlength": 1, "required": True},
    "kind": {"type": "string", "allowed": ["conference", "meetup"], "required": True},
    "by": {"type": "string", "allowed": ["human", "bot"], "required": True},
}

latest = eval(f"v{LATEST}")


================================================
FILE: conrad/utils.py
================================================
# -*- coding: utf-8 -*-

import datetime as dt
import json
import logging
import os
import sys
from collections import Counter

import geopy.exc as geopyexceptions
import requests
from geopy.extra.rate_limiter import RateLimiter
from geopy.geocoders import Nominatim
from packaging import version

from . import CONRAD_HOME, __version__
from .db import engine
from .schema import *

SELFCHECK_DATE_FMT = "%Y-%m-%dT%H:%M:%SZ"


logger = logging.getLogger(__name__)


# https://github.com/pypa/pip/blob/master/src/pip/_internal/self_outdated_check.py
class SelfCheckState(object):
    def __init__(self, cache_dir):
        self.state = {}
        self.statefile_path = os.path.join(cache_dir, "selfcheck.json")

        # Try to load the existing state
        try:
            with open(self.statefile_path, "r") as f:
                self.state = json.load(f)
        except (IOError, ValueError, KeyError, FileNotFoundError):
            # Explicitly suppressing exceptions, since we don't want to
            # error out if the cache file is invalid.
            pass

    def save(self, pypi_version, current_time):
        # If we do not have a path to cache in, don't bother saving.
        if not self.statefile_path:
            return

        state = {
            "last_check": current_time.strftime(SELFCHECK_DATE_FMT),
            "pypi_version": pypi_version,
        }

        text = json.dumps(state, sort_keys=True, separators=(",", ":"))

        with open(self.statefile_path, "w") as f:
            f.write(text)


def get_pypi_version():
    url = "https://pypi.org/pypi/conference-radar/json"
    response = requests.get(url)
    if response:
        data = response.json()
        pypi_version = data["info"]["version"]
        return pypi_version


def conrad_self_version_check():
    pypi_version = None

    try:
        state = SelfCheckState(cache_dir=CONRAD_HOME)

        current_time = dt.datetime.utcnow()
        # Determine if we need to refresh the state
        if "last_check" in state.state and "pypi_version" in state.state:
            last_check = dt.datetime.strptime(
                state.state["last_check"], SELFCHECK_DATE_FMT
            )
            if (current_time - last_check).total_seconds() < 7 * 24 * 60 * 60:
                pypi_version = state.state["pypi_version"]

        # Refresh the version if we need to or just see if we need to warn
        if pypi_version is None:
            pypi_version = get_pypi_version()

            # Save that we've performed a check
            state.save(pypi_version, current_time)

        conrad_version = version.parse(__version__)
        remote_version = version.parse(pypi_version)

        if conrad_version < remote_version:
            pip_cmd = "{} -m pip".format(sys.executable)
            logger.warning(
                f"You are using conrad version {__version__}; however,"
                f" version {pypi_version} is available.\n"
                "You should consider upgrading with"
                f" '{pip_cmd} install --upgrade conference-radar'."
            )
    except Exception:
        logger.debug(
            "There was an error checking the latest version of conrad",
            exc_info=True,
        )


def initialize_database():
    from .models import Base

    Base.metadata.create_all(engine)


def reset_database():
    from .models import Base

    Base.metadata.drop_all(engine)
    initialize_database()


def get_address(place):
    geolocator = Nominatim(user_agent="conrad")
    geocode = RateLimiter(geolocator.geocode, min_delay_seconds=5)

    address = None
    try:
        location = geolocator.geocode(place)
        if location is not None:
            address = geolocator.reverse(
                "{lat}, {lon}".format(lat=location.latitude, lon=location.longitude)
            ).raw["address"]
            address["latitude"] = location.latitude
            address["longitude"] = location.longitude
    except geopyexceptions.GeocoderTimedOut:
        # TODO: add 2 retries using tenacity
        print(f"Geocoder timed out for {place}!")

    return address


def apply_schema(events, version=LATEST):
    schema = eval(f"v{version}")
    _events = []

    for event in events:
        _event = dict({k: v for k, v in event.items() if k in schema.keys()})
        _events.append(_event)

    return _events


def validate_events(input_events, version=LATEST):
    schema = eval(f"v{version}")
    failures = []

    # check for duplicates (name + start_date to allow same conference in different years)
    ie_identifiers = [
        (ie["name"].replace(" ", "").lower(), ie["start_date"]) for ie in input_events
    ]
    duplicate_events = [
        event for event, count in Counter(ie_identifiers).items() if count > 1
    ]
    if duplicate_events:
        failures.append(f"Duplicate events found: {duplicate_events}")

    # check if keys exist
    for ie in input_events:
        if set(schema.keys()).difference(set(ie.keys())):
            failures.append("Required fields not found")
            break

    return failures


def mkdir(directory):
    if not os.path.exists(directory):
        os.makedirs(directory)


================================================
FILE: crawlers/__init__.py
================================================
# -*- coding: utf-8 -*-

from .pycon.pycon_crawler import PyConCrawler
from .python.python_crawler import PythonCrawler
from .pydata.pydata_crawler import PyDataCrawler
from .confs_tech.confs_tech_crawler import ConfsTechCrawler
from .italy.italy_crawler import ItalyCrawler
from .papercall.papercall_crawler import PapercallCrawler


================================================
FILE: crawlers/base.py
================================================
# -*- coding: utf-8 -*-

import json
import datetime as dt

from cerberus import Validator

from conrad.schema import latest


class EventValidator(Validator):
    def _validate_is_date(self, is_date, field, value):
        """Test if a date is valid.
        The rule's arguments are validated against this schema:
        {'type': 'boolean'}
        """
        if is_date:
            valid = True
            try:
                dt.datetime.strptime(value, "%Y-%m-%d")
            except:
                valid = False
            if not valid:
                self._error(field, "must be valid date")


class BaseCrawler(object):
    def __init__(self):
        self.events = []

    def get_events(self):
        pass

    def export(self, filename):
        v = EventValidator(latest)
        for event in self.events:
            v.validate(event)
            if v.errors:
                for key, val in v.errors.items():
                    print(f"{event['name']} - {key}: {val}")

        with open(filename, "w") as f:
            f.write(json.dumps(self.events, indent=4, sort_keys=True))


================================================
FILE: crawlers/confs_tech/__init__.py
================================================
# -*- coding: utf-8 -*-


================================================
FILE: crawlers/confs_tech/confs_tech_crawler.py
================================================
# -*- coding: utf-8 -*-

import os
import json
from pathlib import Path

import git

from ..base import BaseCrawler


def mkdir(directory):
    if not os.path.exists(directory):
        os.makedirs(directory)


class ConfsTechCrawler(BaseCrawler):
    def get_events(self):
        # Populate this list of events using your code
        events = []

        git.Git("/tmp").clone(
            "https://github.com/tech-conferences/conference-data.git", depth=1
        )

        data_path = "/tmp/conference-data"
        mkdir(data_path)

        p = Path(data_path)
        years = ["2021", "2022"]
        conference_names = []

        for year in years:
            conferences_for_year_path = p / "conferences" / years[0]
            for tagfile in os.listdir(conferences_for_year_path):
                tag = tagfile.replace(".json", "")
                conferences_for_tag_for_year_path = conferences_for_year_path / tagfile

                with open(conferences_for_tag_for_year_path, "r") as f:
                    conferences = json.load(f)

                for conference in conferences:
                    conference_name = conference.get("name", "").lower()
                    if conference_name in conference_names:
                        continue
                    conference_names.append(conference_name)

                    city = conference.get("city")
                    country = conference.get("country")

                    cfp_end_date = (
                        conference.get("cfpEndDate")
                        if conference.get("cfpEndDate") is not None
                        else "1970-01-01"
                    )

                    conference_data = {
                        "name": conference.get("name"),
                        "url": conference.get("url"),
                        "city": city,
                        "state": conference.get("state"),
                        "country": country,
                        "location": ", ".join(
                            filter(lambda x: x is not None, [city, country])
                        ),
                        "cfp_open": False,
                        "cfp_end_date": cfp_end_date,
                        "start_date": conference.get("startDate"),
                        "end_date": conference.get("endDate"),
                        "source": "https://confs.tech",
                        "tags": [tag],
                        "kind": "conference",
                        "by": "bot",
                    }

                    self.events.append(conference_data)


================================================
FILE: crawlers/italy/__init__.py
================================================


================================================
FILE: crawlers/italy/italy_crawler.py
================================================
# -*- coding: utf-8 -*-

import json

import requests

from ..base import BaseCrawler


class ItalyCrawler(BaseCrawler):
    """
    Crawler for Italy events from the Awesome Italy Events dataset.

    Fetches conferences in Italy (except PyCon) and formats them
    according to Conrad's event schema.
    """
    def __init__(self, year = 2020):
        super().__init__()
        self.year = year
    
    def get_events(self):
        url = f"https://raw.githubusercontent.com/ildoc/awesome-italy-events/master/data/{self.year}.json"
        try:
            response = requests.get(url, timeout = 10)
            response.raise_for_status() # Raises an HTTP error for bad status codes
            data = json.loads(response.content.decode("utf-8-sig")) # Convert response to JSON
        except requests.exceptions.RequestException as e:
            print(f"Failed to fetch events for {self.year}: {e}")
            return
        except json.JSONDecodeError as e:
            print(f"Invalid JSON for {self.year}: {e}")
            return

        for event in data:
            if "pycon" in event.get("title", "").lower():
                continue

            # Skip if required fields are missing
            required_fields = ["title", "url", "location", "startDate", "endDate"]
            if not all(field in event for field in required_fields):
                continue
            
            e = {
                "name": event.get("title", "Untitled Event"),
                "url": event.get("url", ""),
                "city": event.get("location", None),
                "state": None,
                "country": "Italy",
                "location": event.get("location", ""),
                "cfp_open": False,
                "cfp_end_date": "1970-01-01",
                "start_date": event.get("startDate", "1970-01-01"),
                "end_date": event.get("endDate", "1970-01-01"),
                "source": "https://github.com/ildoc/awesome-italy-events",
                "tags": ["technology"],
                "kind": "conference",
                "by": "bot",
            }
            self.events.append(e)


================================================
FILE: crawlers/papercall/__init__.py
================================================
# -*- coding: utf-8 -*-


================================================
FILE: crawlers/papercall/papercall_crawler.py
================================================
# -*- coding: utf-8 -*-
# https://github.com/coderanger/cfp-scraper/blob/master/papercall.py

import requests
import dateparser
import dateparser.search
from bs4 import BeautifulSoup

from ..base import BaseCrawler


URL = "https://www.papercall.io/events?open-cfps=true&page={page}"


def get(page):
    res = requests.get(URL.format(page=page))
    return BeautifulSoup(res.text, "html.parser")


def maybe_int(s):
    try:
        return int(s)
    except ValueError:
        return 0


def num_pages():
    pagination = get(1).find(class_="pagination")
    return max(maybe_int(elm.string) for elm in pagination.find_all("a"))


def parse_page(root):
    for event in root.select(".event-list-detail"):
        title_line = event.select(".event__title a")[-1]
        title_parts = title_line.string.split(" - ", 1)
        if len(title_parts) == 1:
            title = title_parts[0]
            location = ""
        elif len(title_parts) == 2:
            title = title_parts[0]
            location = title_parts[1]
        try:
            url = event.select(".fa-external-link")[0]["title"]
        except IndexError:
            url = ""
        cfp_close_label = event.find(
            lambda elm: elm.name == "strong" and "CFP closes at" in elm.string
        )
        if not cfp_close_label:
            # No real point.
            continue
        cfp_close = dateparser.parse(
            cfp_close_label.parent.find_next_sibling("td").string.strip()
        )
        start_date = end_date = None
        dates = event.find(
            lambda elm: elm.name == "strong" and "Event Dates" in elm.string
        )
        if dates:
            dates = dates.next_sibling.string.strip()
        if dates:
            parsed_dates = [d for _, d in dateparser.search.search_dates(dates)]
            if parsed_dates:
                start_date = parsed_dates[0].date()
                end_date = parsed_dates[-1].date()
        tags = [t.string for t in event.select('a[href^="/events?keywords=tags"]')]

        today = dateparser.parse("now UTC")
        cfp_open = False if today > cfp_close else True
        try:
            city = location.split(",")[0]
            country = location.split(",")[1]
        except IndexError:
            city = country = location

        yield {
            "name": title,
            "url": url,
            "city": city,
            "state": None,
            "country": country,
            "cfp_open": cfp_open,
            "cfp_end_date": cfp_close.strftime("%Y-%m-%d")
            if cfp_close is not None
            else "1970-01-01",
            "start_date": start_date.strftime("%Y-%m-%d")
            if start_date is not None
            else "1970-01-01",
            "end_date": end_date.strftime("%Y-%m-%d") if end_date is not None else None,
            "source": "http://papercall.io",
            "tags": tags,
            "kind": "conference",
            "by": "bot",
        }


def parse_all():
    count = num_pages()
    for n in range(count):
        yield from parse_page(get(n + 1))


class PapercallCrawler(BaseCrawler):
    def get_events(self):
        for event in parse_all():
            self.events.append(event)


================================================
FILE: crawlers/pycon/__init__.py
================================================
# -*- coding: utf-8 -*-


================================================
FILE: crawlers/pycon/pycon_crawler.py
================================================
# -*- coding: utf-8 -*-

import datetime as dt

import pandas

from ..base import BaseCrawler


class PyConCrawler(BaseCrawler):
    def get_events(self):
        current_year = dt.datetime.now().year
        next_year = current_year + 1

        # Fetch events for both current and next year
        for year in [current_year, next_year]:
            try:
                df = pandas.read_csv(
                    f"https://raw.githubusercontent.com/python-organizers/conferences/refs/heads/main/{year}.csv",
                    quoting=1,
                    encoding="utf-8",
                    dtype=str,
                )
                df = df.fillna("")
            except Exception:
                # Skip if the year's CSV doesn't exist
                continue

            for event in df.to_dict(orient="records"):
                location = event["Location"].split(",")
                city = state = country = None
                if len(location) == 2:
                    city = location[0].strip()
                    country = location[1].strip()
                elif len(location) == 3:
                    city = location[0].strip()
                    state = location[1].strip()
                    country = event["Country"]

                cfp_end_date = (
                    event["Talk Deadline"] if event["Talk Deadline"] else "1970-01-01"
                )
                cfp_open = (
                    True
                    if dt.datetime.now()
                    <= dt.datetime.strptime(cfp_end_date, "%Y-%m-%d").replace(
                        hour=23, minute=59, second=59, microsecond=999999
                    )
                    else False
                )
                e = {
                    "name": event["Subject"],
                    "url": event["Website URL"],
                    "city": city,
                    "state": state,
                    "country": country,
                    "location": ", ".join(
                        filter(lambda x: x is not None, [city, state, country])
                    ),
                    "cfp_open": cfp_open,
                    "cfp_end_date": cfp_end_date,
                    "start_date": event["Start Date"],
                    "end_date": event["End Date"],
                    "source": "https://github.com/python-organizers/conferences",
                    "tags": ["python"],
                    "kind": "conference",
                    "by": "bot",
                }
                self.events.append(e)


================================================
FILE: crawlers/pydata/__init__.py
================================================
# -*- coding: utf-8 -*-


================================================
FILE: crawlers/pydata/pydata_crawler.py
================================================
# -*- coding: utf-8 -*-

import datetime as dt

import json
import requests
from bs4 import BeautifulSoup

from ..base import BaseCrawler


class PyDataEvent:
    def __init__(self, name, city, country, location, start_date, end_date, url):
        self.name = name
        self.url = url
        self.city = city
        self.state = None
        self.country = country
        self.location = location
        self.cfp_open = False
        self.cfp_end_date = "1970-01-01"
        self.start_date = start_date
        self.end_date = end_date
        self.source = PyDataCrawler.URL
        self.tags = ["python", "pydata"]
        self.kind = "conference"
        self.by = "bot"

    def to_json(self):
        return {
            "name": self.name,
            "url": self.url,
            "city": self.city,
            "state": self.state,
            "country": self.country,
            "location": self.location,
            "cfp_open": self.cfp_open,
            "cfp_end_date": self.cfp_end_date,
            "start_date": self.start_date.strftime(PyDataCrawler.DATE_FORMAT),
            "end_date": self.end_date.strftime(PyDataCrawler.DATE_FORMAT),
            "source": self.source,
            "tags": self.tags,
            "kind": self.kind,
            "by": self.by,
        }


class PyDataCrawler(BaseCrawler):
    URL = "https://pydata.org/event-schedule/"
    HEADERS = {
        "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) "
        "AppleWebKit/537.36 (KHTML, like Gecko) "
        "Chrome/50.0.2661.102 Safari/537.36"
    }
    SELECTOR = 'div.mec-event-list-classic > script[type="application/ld+json"]'
    DATE_FORMAT = "%Y-%m-%d"

    def _format_date(self, date_str):
        return dt.datetime.strptime(date_str, self.DATE_FORMAT).date()

    def _parse_pydata_event(self, event_article):
        content = json.loads(event_article.decode_contents())

        try:
            location = content.get("location", {}).get("name")
            city, country = location.split(", ")
        except (KeyError, ValueError, AttributeError):
            city = country = None

        return PyDataEvent(
            name=content["name"],
            url=content["url"],
            city=city,
            country=country,
            location=location,
            start_date=self._format_date(content["startDate"]),
            end_date=self._format_date(content["endDate"]),
        )

    def _parse_pydata_events(self, event_articles):
        return list(map(self._parse_pydata_event, event_articles))

    def get_events(self):
        resp = requests.get(self.URL, headers=self.HEADERS)
        page = BeautifulSoup(resp.content, features="html.parser")
        pydata_events = self._parse_pydata_events(page.select(self.SELECTOR))
        self.events = [event.to_json() for event in pydata_events]


================================================
FILE: crawlers/python/__init__.py
================================================
# -*- coding: utf-8 -*-


================================================
FILE: crawlers/python/python_crawler.py
================================================
# -*- coding: utf-8 -*-

import os
import json
import datetime as dt

from bs4 import BeautifulSoup
from googleapiclient.discovery import build
from google.oauth2.service_account import Credentials

from ..base import BaseCrawler


class PythonCrawler(BaseCrawler):
    def get_events(self):
        credentials = Credentials.from_service_account_file(
            "google_service_account_credentials.json",
            scopes=[
                "https://www.googleapis.com/auth/calendar",
                "https://www.googleapis.com/auth/calendar.readonly",
            ],
        )
        service = build("calendar", "v3", credentials=credentials)

        start_time = dt.datetime.now().strftime("%Y-%m-%dT00:00:00.000Z")
        end_time = None
        events = []

        try:
            page_token = None
            while True:
                event_page = (
                    service.events()
                    .list(
                        singleEvents="False",
                        orderBy="startTime",
                        calendarId="j7gov1cmnqr9tvg14k621j7t5c@group.calendar.google.com",
                        pageToken=page_token,
                        timeMin=start_time,
                        timeMax=end_time,
                    )
                    .execute()
                )
                events.extend([event for event in event_page["items"]])

                page_token = event_page.get("nextPageToken")
                if not page_token:
                    break
        except AccessTokenRefreshError:
            print(
                "The credentials have been revoked or expired, please re-run"
                " the application to re-authorize."
            )

        for event in events:
            if any(
                [word in event["summary"].lower() for word in ["cancel", "postpone"]]
            ):
                continue

            try:
                soup = BeautifulSoup(event["description"], "html.parser")
                event_url = soup.find_all("a", href=True)[0]["href"]
            except (KeyError, IndexError):
                event_url = None

            if "date" in event["start"]:
                start_date = event["start"]["date"]
                end_date = event["end"]["date"]
            elif "dateTime" in event["start"]:
                start_date = event["start"]["dateTime"].split("T")[0]
                end_date = event["end"]["dateTime"].split("T")[0]
            else:
                raise ValueError("Event date not found!")

            e = {
                "name": event["summary"],
                "url": event_url,
                "city": None,
                "state": None,
                "country": None,
                "location": event.get("location"),
                "cfp_open": False,
                "cfp_end_date": "1970-01-01",
                "start_date": start_date,
                "end_date": end_date,
                "source": "https://wiki.python.org/moin/PythonEventsCalendar",
                "tags": ["python"],
                "kind": "conference",
                "by": "bot",
            }
            self.events.append(e)


================================================
FILE: data/confstech.json
================================================
[
    {
        "by": "bot",
        "cfp_end_date": "2021-01-24",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-05-28",
        "kind": "conference",
        "location": "",
        "name": "GopherCon EU",
        "source": "https://confs.tech",
        "start_date": "2021-05-26",
        "state": null,
        "tags": [
            "golang"
        ],
        "url": "https://gophercon.eu"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-06-24",
        "kind": "conference",
        "location": "",
        "name": "Conf42: Golang",
        "source": "https://confs.tech",
        "start_date": "2021-06-24",
        "state": null,
        "tags": [
            "golang"
        ],
        "url": "https://www.conf42.com/golang2021"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-09-15",
        "kind": "conference",
        "location": "",
        "name": "GopherCon Poland",
        "source": "https://confs.tech",
        "start_date": "2021-09-15",
        "state": null,
        "tags": [
            "golang"
        ],
        "url": "https://gophercon.pl"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "London",
        "country": "U.K.",
        "end_date": "2021-10-27",
        "kind": "conference",
        "location": "London, U.K.",
        "name": "GopherCon UK",
        "source": "https://confs.tech",
        "start_date": "2021-10-25",
        "state": null,
        "tags": [
            "golang"
        ],
        "url": "https://www.gophercon.co.uk"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-11-10",
        "kind": "conference",
        "location": "",
        "name": "betterCode() Go",
        "source": "https://confs.tech",
        "start_date": "2021-11-10",
        "state": null,
        "tags": [
            "golang"
        ],
        "url": "https://go.bettercode.eu"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-12-08",
        "kind": "conference",
        "location": "",
        "name": "GopherCon",
        "source": "https://confs.tech",
        "start_date": "2021-12-06",
        "state": null,
        "tags": [
            "golang"
        ],
        "url": "https://gophercon.com"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Singapore",
        "country": "Singapore",
        "end_date": "2021-01-21",
        "kind": "conference",
        "location": "Singapore, Singapore",
        "name": "iOS Conf SG",
        "source": "https://confs.tech",
        "start_date": "2021-01-20",
        "state": null,
        "tags": [
            "ios"
        ],
        "url": "https://iosconf.sg"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-04-16",
        "kind": "conference",
        "location": "",
        "name": "Swift Heroes",
        "source": "https://confs.tech",
        "start_date": "2021-04-16",
        "state": null,
        "tags": [
            "ios"
        ],
        "url": "https://swiftheroes.com/2021"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-06-11",
        "kind": "conference",
        "location": "",
        "name": "WWDC - Apple Developer Conference",
        "source": "https://confs.tech",
        "start_date": "2021-06-07",
        "state": null,
        "tags": [
            "ios"
        ],
        "url": "https://developer.apple.com/wwdc21"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-06-24",
        "kind": "conference",
        "location": "",
        "name": "ADDC - App Design & Development",
        "source": "https://confs.tech",
        "start_date": "2021-06-23",
        "state": null,
        "tags": [
            "ios"
        ],
        "url": "https://addconf.com"
    },
    {
        "by": "bot",
        "cfp_end_date": "2021-08-27",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-09-28",
        "kind": "conference",
        "location": "",
        "name": "iConf",
        "source": "https://confs.tech",
        "start_date": "2021-09-27",
        "state": null,
        "tags": [
            "ios"
        ],
        "url": "https://geekle.us/ios"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Leeds",
        "country": "U.K.",
        "end_date": "2021-10-07",
        "kind": "conference",
        "location": "Leeds, U.K.",
        "name": "SwiftLeeds",
        "source": "https://confs.tech",
        "start_date": "2021-10-07",
        "state": null,
        "tags": [
            "ios"
        ],
        "url": "https://www.swiftleeds.co.uk"
    },
    {
        "by": "bot",
        "cfp_end_date": "2021-07-12",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-10-08",
        "kind": "conference",
        "location": "",
        "name": "Mobiconf",
        "source": "https://confs.tech",
        "start_date": "2021-10-07",
        "state": null,
        "tags": [
            "ios"
        ],
        "url": "https://2021.mobiconf.org"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-02-17",
        "kind": "conference",
        "location": "",
        "name": "DevNexus",
        "source": "https://confs.tech",
        "start_date": "2021-02-17",
        "state": null,
        "tags": [
            "java"
        ],
        "url": "https://devnexus.com"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Tel Aviv",
        "country": "Israel",
        "end_date": "2021-03-10",
        "kind": "conference",
        "location": "Tel Aviv, Israel",
        "name": "Node.TLV",
        "source": "https://confs.tech",
        "start_date": "2021-03-10",
        "state": null,
        "tags": [
            "java"
        ],
        "url": "https://www.nodetlv.com"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-03-25",
        "kind": "conference",
        "location": "",
        "name": "Conf42: Java",
        "source": "https://confs.tech",
        "start_date": "2021-03-25",
        "state": null,
        "tags": [
            "java"
        ],
        "url": "https://www.conf42.com/enterprise2021"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-06-25",
        "kind": "conference",
        "location": "",
        "name": "Extreme Java Camp",
        "source": "https://confs.tech",
        "start_date": "2021-06-21",
        "state": null,
        "tags": [
            "java"
        ],
        "url": "https://extreme-java-camp.de"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-06-26",
        "kind": "conference",
        "location": "",
        "name": "jLove",
        "source": "https://confs.tech",
        "start_date": "2021-06-25",
        "state": null,
        "tags": [
            "java"
        ],
        "url": "https://jlove.konfy.care"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "London",
        "country": "U.K.",
        "end_date": "2021-10-07",
        "kind": "conference",
        "location": "London, U.K.",
        "name": "JAX London",
        "source": "https://confs.tech",
        "start_date": "2021-10-04",
        "state": null,
        "tags": [
            "java"
        ],
        "url": "https://jaxlondon.com"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-10-08",
        "kind": "conference",
        "location": "",
        "name": "JCON",
        "source": "https://confs.tech",
        "start_date": "2021-10-05",
        "state": null,
        "tags": [
            "java"
        ],
        "url": "https://jcon.one"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Denver, CO",
        "country": "U.S.A.",
        "end_date": "2021-10-08",
        "kind": "conference",
        "location": "Denver, CO, U.S.A.",
        "name": "UberConf",
        "source": "https://confs.tech",
        "start_date": "2021-10-05",
        "state": null,
        "tags": [
            "java"
        ],
        "url": "http://uberconf.com"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-10-12",
        "kind": "conference",
        "location": "",
        "name": "I Code Java Africa",
        "source": "https://confs.tech",
        "start_date": "2021-10-12",
        "state": null,
        "tags": [
            "java"
        ],
        "url": "https://j-sa.co"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-11-20",
        "kind": "conference",
        "location": "",
        "name": "Devoxx Ukraine",
        "source": "https://confs.tech",
        "start_date": "2021-11-19",
        "state": null,
        "tags": [
            "java"
        ],
        "url": "https://devoxx.com.ua"
    },
    {
        "by": "bot",
        "cfp_end_date": "2021-08-05",
        "cfp_open": false,
        "city": "Oslo",
        "country": "Norway",
        "end_date": "2021-12-09",
        "kind": "conference",
        "location": "Oslo, Norway",
        "name": "JavaZone",
        "source": "https://confs.tech",
        "start_date": "2021-12-08",
        "state": null,
        "tags": [
            "java"
        ],
        "url": "https://javazone.no"
    },
    {
        "by": "bot",
        "cfp_end_date": "2021-08-01",
        "cfp_open": false,
        "city": "Chicago, IL",
        "country": "U.S.A.",
        "end_date": "2021-12-10",
        "kind": "conference",
        "location": "Chicago, IL, U.S.A.",
        "name": "jConf.dev",
        "source": "https://confs.tech",
        "start_date": "2021-12-08",
        "state": null,
        "tags": [
            "java"
        ],
        "url": "https://2021.jconf.dev"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Clearwater, FL",
        "country": "U.S.A.",
        "end_date": "2021-12-16",
        "kind": "conference",
        "location": "Clearwater, FL, U.S.A.",
        "name": "ArchConf",
        "source": "https://confs.tech",
        "start_date": "2021-12-13",
        "state": null,
        "tags": [
            "java"
        ],
        "url": "https://archconf.com"
    },
    {
        "by": "bot",
        "cfp_end_date": "2021-01-10",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-02-13",
        "kind": "conference",
        "location": "",
        "name": "Scala Love in the City",
        "source": "https://confs.tech",
        "start_date": "2021-02-13",
        "state": null,
        "tags": [
            "scala"
        ],
        "url": "https://inthecity.scala.love"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-02-04",
        "kind": "conference",
        "location": "",
        "name": "UX & Product Conference",
        "source": "https://confs.tech",
        "start_date": "2021-02-04",
        "state": null,
        "tags": [
            "product"
        ],
        "url": "http://conference.uxandproduct.com"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "London",
        "country": "U.K.",
        "end_date": "2021-02-09",
        "kind": "conference",
        "location": "London, U.K.",
        "name": "#ProductCon",
        "source": "https://confs.tech",
        "start_date": "2021-02-09",
        "state": null,
        "tags": [
            "product"
        ],
        "url": "https://www.productschool.com/productcon/london"
    },
    {
        "by": "bot",
        "cfp_end_date": "2020-12-11",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-02-19",
        "kind": "conference",
        "location": "",
        "name": "ProductWorld",
        "source": "https://confs.tech",
        "start_date": "2021-02-17",
        "state": null,
        "tags": [
            "product"
        ],
        "url": "https://productworld.co"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Singapore",
        "country": "Singapore",
        "end_date": "2021-03-19",
        "kind": "conference",
        "location": "Singapore, Singapore",
        "name": "Mind the Product",
        "source": "https://confs.tech",
        "start_date": "2021-03-18",
        "state": null,
        "tags": [
            "product"
        ],
        "url": "https://www.mindtheproduct.com/mtpcon/singapore"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-03-24",
        "kind": "conference",
        "location": "",
        "name": "ABBYY Reimagine",
        "source": "https://confs.tech",
        "start_date": "2021-03-23",
        "state": null,
        "tags": [
            "product"
        ],
        "url": "https://www.abbyy.com/abbyy-reimagine-2021"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-04-15",
        "kind": "conference",
        "location": "",
        "name": "#mtpcon Digital APAC",
        "source": "https://confs.tech",
        "start_date": "2021-04-14",
        "state": null,
        "tags": [
            "product"
        ],
        "url": "https://www.mindtheproduct.com/mtpcon/digital/apac"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-06-03",
        "kind": "conference",
        "location": "",
        "name": "Integrate Remote - Microsoft Integration Conference",
        "source": "https://confs.tech",
        "start_date": "2021-06-01",
        "state": null,
        "tags": [
            "product"
        ],
        "url": "https://www.biztalk360.com/integrate-2021-remote"
    },
    {
        "by": "bot",
        "cfp_end_date": "2021-04-09",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-06-17",
        "kind": "conference",
        "location": "",
        "name": "GrafanaCONline",
        "source": "https://confs.tech",
        "start_date": "2021-06-07",
        "state": null,
        "tags": [
            "product"
        ],
        "url": "https://grafana.com/about/events/grafanacon/2021"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Zurich",
        "country": "Switzerland",
        "end_date": "2021-06-23",
        "kind": "conference",
        "location": "Zurich, Switzerland",
        "name": "European Product Owner & Requirements Engineering Day",
        "source": "https://confs.tech",
        "start_date": "2021-06-23",
        "state": null,
        "tags": [
            "product"
        ],
        "url": "https://www.europeanporeday.com"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-07-15",
        "kind": "conference",
        "location": "",
        "name": "#mtpcon Digital Americas",
        "source": "https://confs.tech",
        "start_date": "2021-07-14",
        "state": null,
        "tags": [
            "product"
        ],
        "url": "https://www.mindtheproduct.com/mtpcon/digital/#americas"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-09-09",
        "kind": "conference",
        "location": "",
        "name": "P3X: People Process Product eXchange",
        "source": "https://confs.tech",
        "start_date": "2021-09-08",
        "state": null,
        "tags": [
            "product"
        ],
        "url": "http://p3x.io"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-09-15",
        "kind": "conference",
        "location": "",
        "name": "ProductCamp",
        "source": "https://confs.tech",
        "start_date": "2021-09-14",
        "state": null,
        "tags": [
            "product"
        ],
        "url": "https://productcamp.pl"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-09-29",
        "kind": "conference",
        "location": "",
        "name": "Business of Software",
        "source": "https://confs.tech",
        "start_date": "2021-09-27",
        "state": null,
        "tags": [
            "product"
        ],
        "url": "https://businessofsoftware.org"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-11-11",
        "kind": "conference",
        "location": "",
        "name": "Product Owner Day",
        "source": "https://confs.tech",
        "start_date": "2021-11-11",
        "state": null,
        "tags": [
            "product"
        ],
        "url": "https://pod.inside-agile.de"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Birmingham",
        "country": "U.K.",
        "end_date": "2021-11-18",
        "kind": "conference",
        "location": "Birmingham, U.K.",
        "name": "Canvas X",
        "source": "https://confs.tech",
        "start_date": "2021-11-18",
        "state": null,
        "tags": [
            "product"
        ],
        "url": "https://canvasconference.co.uk"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-12-01",
        "kind": "conference",
        "location": "",
        "name": "Postgres Build",
        "source": "https://confs.tech",
        "start_date": "2021-11-30",
        "state": null,
        "tags": [
            "product"
        ],
        "url": "https://www.postgresbuild.com"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-03-24",
        "kind": "conference",
        "location": "",
        "name": "2nd IT Security Virtual Strategy Meeting",
        "source": "https://confs.tech",
        "start_date": "2021-03-24",
        "state": null,
        "tags": [
            "iot"
        ],
        "url": "https://itsecapac.com"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-03-25",
        "kind": "conference",
        "location": "",
        "name": "buildingt IoT",
        "source": "https://confs.tech",
        "start_date": "2021-03-24",
        "state": null,
        "tags": [
            "iot"
        ],
        "url": "https://www.buildingiot.de"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-04-29",
        "kind": "conference",
        "location": "",
        "name": "Embedded IoT World",
        "source": "https://confs.tech",
        "start_date": "2021-04-28",
        "state": null,
        "tags": [
            "iot"
        ],
        "url": "https://tmt.knect365.com/embedded-iot-world"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-05-04",
        "kind": "conference",
        "location": "",
        "name": "Kubernetes on Edge Day",
        "source": "https://confs.tech",
        "start_date": "2021-05-04",
        "state": null,
        "tags": [
            "iot"
        ],
        "url": "https://events.linuxfoundation.org/kubernetes-on-edge-day"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-06-23",
        "kind": "conference",
        "location": "",
        "name": "Internet of Things",
        "source": "https://confs.tech",
        "start_date": "2021-06-21",
        "state": null,
        "tags": [
            "iot"
        ],
        "url": "https://iotcon.de"
    },
    {
        "by": "bot",
        "cfp_end_date": "2021-05-15",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-07-10",
        "kind": "conference",
        "location": "",
        "name": "Hardwear.io Security Trainings & Conference USA",
        "source": "https://confs.tech",
        "start_date": "2021-07-05",
        "state": null,
        "tags": [
            "iot"
        ],
        "url": "https://hardwear.io/usa-2021"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Wall, NJ",
        "country": "U.S.A.",
        "end_date": "2021-09-10",
        "kind": "conference",
        "location": "Wall, NJ, U.S.A.",
        "name": "Vintage Computer Festival East",
        "source": "https://confs.tech",
        "start_date": "2021-09-08",
        "state": null,
        "tags": [
            "iot"
        ],
        "url": "https://vcfed.org/wp/festivals/vintage-computer-festival-east"
    },
    {
        "by": "bot",
        "cfp_end_date": "2021-06-13",
        "cfp_open": false,
        "city": "Seattle, WA",
        "country": "U.S.A.",
        "end_date": "2021-09-30",
        "kind": "conference",
        "location": "Seattle, WA, U.S.A.",
        "name": "Embedded Linux Conference",
        "source": "https://confs.tech",
        "start_date": "2021-09-27",
        "state": null,
        "tags": [
            "iot"
        ],
        "url": "https://events.linuxfoundation.org/embedded-linux-conference-north-america"
    },
    {
        "by": "bot",
        "cfp_end_date": "2021-08-20",
        "cfp_open": false,
        "city": "The Hague",
        "country": "Netherlands",
        "end_date": "2021-10-29",
        "kind": "conference",
        "location": "The Hague, Netherlands",
        "name": "Hardwear.io Security Trainings and Conference Netherlands",
        "source": "https://confs.tech",
        "start_date": "2021-10-25",
        "state": null,
        "tags": [
            "iot"
        ],
        "url": "https://hardwear.io/netherlands-2021"
    },
    {
        "by": "bot",
        "cfp_end_date": "2021-01-07",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-02-25",
        "kind": "conference",
        "location": "",
        "name": "GraphQL Asia",
        "source": "https://confs.tech",
        "start_date": "2021-02-22",
        "state": null,
        "tags": [
            "graphql"
        ],
        "url": "https://graphql.asia"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "The Hague",
        "country": "Netherlands",
        "end_date": "2021-04-14",
        "kind": "conference",
        "location": "The Hague, Netherlands",
        "name": "API Conference",
        "source": "https://confs.tech",
        "start_date": "2021-04-12",
        "state": null,
        "tags": [
            "graphql"
        ],
        "url": "https://apiconference.net/thehague"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-06-17",
        "kind": "conference",
        "location": "",
        "name": "NODES",
        "source": "https://confs.tech",
        "start_date": "2021-06-17",
        "state": null,
        "tags": [
            "graphql"
        ],
        "url": "https://neo4j.com/nodes-2021"
    },
    {
        "by": "bot",
        "cfp_end_date": "2021-07-11",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-09-10",
        "kind": "conference",
        "location": "",
        "name": "Haskell Love",
        "source": "https://confs.tech",
        "start_date": "2021-09-10",
        "state": null,
        "tags": [
            "haskell"
        ],
        "url": "https://haskell.love"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-12-10",
        "kind": "conference",
        "location": "",
        "name": "GraphQL Galaxy",
        "source": "https://confs.tech",
        "start_date": "2021-12-09",
        "state": null,
        "tags": [
            "api"
        ],
        "url": "https://graphqlgalaxy.com"
    },
    {
        "by": "bot",
        "cfp_end_date": "2021-01-31",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-03-11",
        "kind": "conference",
        "location": "",
        "name": "cssday Digital Edition",
        "source": "https://confs.tech",
        "start_date": "2021-03-11",
        "state": null,
        "tags": [
            "css"
        ],
        "url": "https://2021.cssday.it"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Munich",
        "country": "Germany",
        "end_date": "2021-03-25",
        "kind": "conference",
        "location": "Munich, Germany",
        "name": "HTML & CSS Days",
        "source": "https://confs.tech",
        "start_date": "2021-03-22",
        "state": null,
        "tags": [
            "css"
        ],
        "url": "https://javascript-days.de/html-css"
    },
    {
        "by": "bot",
        "cfp_end_date": "2021-01-31",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-04-30",
        "kind": "conference",
        "location": "",
        "name": "hover",
        "source": "https://confs.tech",
        "start_date": "2021-04-23",
        "state": null,
        "tags": [
            "css"
        ],
        "url": "https://www.webdirections.org/hover"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Yerevan",
        "country": "Armenia",
        "end_date": "2021-11-13",
        "kind": "conference",
        "location": "Yerevan, Armenia",
        "name": "CSS Conf Armenia",
        "source": "https://confs.tech",
        "start_date": "2021-11-13",
        "state": null,
        "tags": [
            "css"
        ],
        "url": "https://cssconf.am"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-01-29",
        "kind": "conference",
        "location": "",
        "name": "Deep Learning 2.0 Virtual Summit",
        "source": "https://confs.tech",
        "start_date": "2021-01-28",
        "state": null,
        "tags": [
            "data"
        ],
        "url": "https://www.re-work.co/summits/deep-learning-summit-san-francisco-2021"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-02-04",
        "kind": "conference",
        "location": "",
        "name": "DataOps Champions",
        "source": "https://confs.tech",
        "start_date": "2021-02-02",
        "state": null,
        "tags": [
            "data"
        ],
        "url": "https://dco-dataops.coriniumintelligence.com"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-02-03",
        "kind": "conference",
        "location": "",
        "name": "AI+",
        "source": "https://confs.tech",
        "start_date": "2021-02-03",
        "state": null,
        "tags": [
            "data"
        ],
        "url": "https://getaiplus.com/event"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-02-18",
        "kind": "conference",
        "location": "",
        "name": "Darwin's Circle",
        "source": "https://confs.tech",
        "start_date": "2021-02-18",
        "state": null,
        "tags": [
            "data"
        ],
        "url": "https://darwins-circle.com"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-03-04",
        "kind": "conference",
        "location": "",
        "name": "Chief Data & Analytics Officers Financial Services",
        "source": "https://confs.tech",
        "start_date": "2021-03-02",
        "state": null,
        "tags": [
            "data"
        ],
        "url": "https://cdaofs.coriniumintelligence.com"
    },
    {
        "by": "bot",
        "cfp_end_date": "2021-03-03",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-03-05",
        "kind": "conference",
        "location": "",
        "name": "Reinforce",
        "source": "https://confs.tech",
        "start_date": "2021-03-03",
        "state": null,
        "tags": [
            "data"
        ],
        "url": "https://reinforceconf.com"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-03-11",
        "kind": "conference",
        "location": "",
        "name": "Pharma AI, IoT & Blockchain",
        "source": "https://confs.tech",
        "start_date": "2021-03-11",
        "state": null,
        "tags": [
            "data"
        ],
        "url": "https://www.virtueinsight.com/pharma/4th-Annual-Pharma-AI-IoT--Blockchain-2021-Virtual-Conference"
    },
    {
        "by": "bot",
        "cfp_end_date": "2021-03-23",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-04-01",
        "kind": "conference",
        "location": "",
        "name": "ODSC East",
        "source": "https://confs.tech",
        "start_date": "2021-03-30",
        "state": null,
        "tags": [
            "data"
        ],
        "url": "https://odsc.com/boston"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-04-01",
        "kind": "conference",
        "location": "",
        "name": "ODSC Mini-Bootcamp",
        "source": "https://confs.tech",
        "start_date": "2021-03-30",
        "state": null,
        "tags": [
            "data"
        ],
        "url": "https://odsc.com/bootcamp"
    },
    {
        "by": "bot",
        "cfp_end_date": "2021-03-07",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-04-16",
        "kind": "conference",
        "location": "",
        "name": "Data Love",
        "source": "https://confs.tech",
        "start_date": "2021-04-16",
        "state": null,
        "tags": [
            "data"
        ],
        "url": "https://datalove.konfy.care"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-04-17",
        "kind": "conference",
        "location": "",
        "name": "DataYap Virtual Conference",
        "source": "https://confs.tech",
        "start_date": "2021-04-17",
        "state": null,
        "tags": [
            "data"
        ],
        "url": "https://conference.datayap.com"
    },
    {
        "by": "bot",
        "cfp_end_date": "2021-03-15",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-04-24",
        "kind": "conference",
        "location": "",
        "name": "Data Science fwdays",
        "source": "https://confs.tech",
        "start_date": "2021-04-24",
        "state": null,
        "tags": [
            "data"
        ],
        "url": "https://fwdays.com/en/event/data-science-fwdays-2021"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-04-24",
        "kind": "conference",
        "location": "",
        "name": "Global AI Student Conference",
        "source": "https://confs.tech",
        "start_date": "2021-04-24",
        "state": null,
        "tags": [
            "data"
        ],
        "url": "https://aiconf.education"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-04-28",
        "kind": "conference",
        "location": "",
        "name": "Minds Mastering Machines",
        "source": "https://confs.tech",
        "start_date": "2021-04-27",
        "state": null,
        "tags": [
            "data"
        ],
        "url": "https://m3-konferenz.de"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-05-04",
        "kind": "conference",
        "location": "",
        "name": "Kubernetes AI Day",
        "source": "https://confs.tech",
        "start_date": "2021-05-04",
        "state": null,
        "tags": [
            "data"
        ],
        "url": "https://events.linuxfoundation.org/kubernetes-ai-day"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-05-12",
        "kind": "conference",
        "location": "",
        "name": "Kafka Summit Europe",
        "source": "https://confs.tech",
        "start_date": "2021-05-11",
        "state": null,
        "tags": [
            "data"
        ],
        "url": "https://www.kafka-summit.org"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-05-28",
        "kind": "conference",
        "location": "",
        "name": "DATA+AI Summit",
        "source": "https://confs.tech",
        "start_date": "2021-05-24",
        "state": null,
        "tags": [
            "data"
        ],
        "url": "https://databricks.com/dataaisummit"
    },
    {
        "by": "bot",
        "cfp_end_date": "2021-05-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-06-10",
        "kind": "conference",
        "location": "",
        "name": "ODSC Europe Virtual Conference",
        "source": "https://confs.tech",
        "start_date": "2021-06-08",
        "state": null,
        "tags": [
            "data"
        ],
        "url": "https://odsc.com/europe"
    },
    {
        "by": "bot",
        "cfp_end_date": "2021-01-18",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-06-23",
        "kind": "conference",
        "location": "",
        "name": "ML Conference",
        "source": "https://confs.tech",
        "start_date": "2021-06-21",
        "state": null,
        "tags": [
            "data"
        ],
        "url": "https://mlconference.ai/munich"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-06-23",
        "kind": "conference",
        "location": "",
        "name": "Postgres Vision",
        "source": "https://confs.tech",
        "start_date": "2021-06-22",
        "state": null,
        "tags": [
            "data"
        ],
        "url": "https://www.postgresvision.com"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Las Vegas, NV",
        "country": "U.S.A.",
        "end_date": "2021-06-25",
        "kind": "conference",
        "location": "Las Vegas, NV, U.S.A.",
        "name": "Intercon Conference",
        "source": "https://confs.tech",
        "start_date": "2021-06-23",
        "state": null,
        "tags": [
            "data"
        ],
        "url": "https://www.intercon.world"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-07-16",
        "kind": "conference",
        "location": "",
        "name": "Apache Airflow Summit",
        "source": "https://confs.tech",
        "start_date": "2021-07-08",
        "state": null,
        "tags": [
            "data"
        ],
        "url": "https://airflowsummit.org"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-07-14",
        "kind": "conference",
        "location": "",
        "name": "MongoDB.Live",
        "source": "https://confs.tech",
        "start_date": "2021-07-13",
        "state": null,
        "tags": [
            "data"
        ],
        "url": "https://www.mongodb.com/live"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Columbus, OH",
        "country": "U.S.A.",
        "end_date": "2021-07-23",
        "kind": "conference",
        "location": "Columbus, OH, U.S.A.",
        "name": "Women in Analytics Conference",
        "source": "https://confs.tech",
        "start_date": "2021-07-21",
        "state": null,
        "tags": [
            "data"
        ],
        "url": "https://womeninanalytics.com/conference"
    },
    {
        "by": "bot",
        "cfp_end_date": "2021-04-05",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-07-28",
        "kind": "conference",
        "location": "",
        "name": "Kafka Summit APAC",
        "source": "https://confs.tech",
        "start_date": "2021-07-27",
        "state": null,
        "tags": [
            "data"
        ],
        "url": "https://www.kafka-summit.org/events/kafka-summit-apac-2021"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-07-29",
        "kind": "conference",
        "location": "",
        "name": "Conf42: Machine Learning",
        "source": "https://confs.tech",
        "start_date": "2021-07-29",
        "state": null,
        "tags": [
            "data"
        ],
        "url": "https://www.conf42.com/ml2021"
    },
    {
        "by": "bot",
        "cfp_end_date": "2021-05-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-08-26",
        "kind": "conference",
        "location": "",
        "name": "IEEE Big Data Service",
        "source": "https://confs.tech",
        "start_date": "2021-08-23",
        "state": null,
        "tags": [
            "data"
        ],
        "url": "http://www.big-dataservice.net"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-08-26",
        "kind": "conference",
        "location": "",
        "name": "IEEE Mobile Cloud",
        "source": "https://confs.tech",
        "start_date": "2021-08-23",
        "state": null,
        "tags": [
            "data"
        ],
        "url": "https://www.mobile-cloud.net"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-09-16",
        "kind": "conference",
        "location": "",
        "name": "ODSC APAC Virtual Conference",
        "source": "https://confs.tech",
        "start_date": "2021-09-15",
        "state": null,
        "tags": [
            "data"
        ],
        "url": "https://odsc.com/apac"
    },
    {
        "by": "bot",
        "cfp_end_date": "2021-08-31",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-10-05",
        "kind": "conference",
        "location": "",
        "name": "PostgresConf South Africa",
        "source": "https://confs.tech",
        "start_date": "2021-10-05",
        "state": null,
        "tags": [
            "data"
        ],
        "url": "https://postgresconf.org/conferences/SouthAfrica2021"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-10-14",
        "kind": "conference",
        "location": "",
        "name": "Big Data and AI Toronto",
        "source": "https://confs.tech",
        "start_date": "2021-10-13",
        "state": null,
        "tags": [
            "data"
        ],
        "url": "https://www.bigdata-toronto.com"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Lisbon",
        "country": "Portugal",
        "end_date": "2021-11-04",
        "kind": "conference",
        "location": "Lisbon, Portugal",
        "name": "Web Summit; Developers & Data",
        "source": "https://confs.tech",
        "start_date": "2021-11-01",
        "state": null,
        "tags": [
            "data"
        ],
        "url": "https://websummit.com/themes/developers-and-data"
    },
    {
        "by": "bot",
        "cfp_end_date": "2021-10-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-11-02",
        "kind": "conference",
        "location": "",
        "name": "OSA Con \u2014 Open Source Analytics Conference",
        "source": "https://confs.tech",
        "start_date": "2021-11-02",
        "state": null,
        "tags": [
            "data"
        ],
        "url": "https://altinity.com/osa-con-2021"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Dubai",
        "country": "United Arab Emirates",
        "end_date": "2021-11-04",
        "kind": "conference",
        "location": "Dubai, United Arab Emirates",
        "name": "Big Data Analytics and Data Science",
        "source": "https://confs.tech",
        "start_date": "2021-11-03",
        "state": null,
        "tags": [
            "data"
        ],
        "url": "https://crgconferences.com/datascience"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Burlingame, CA",
        "country": "U.S.A.",
        "end_date": "2021-11-16",
        "kind": "conference",
        "location": "Burlingame, CA, U.S.A.",
        "name": "ODSC West AIx Summit",
        "source": "https://confs.tech",
        "start_date": "2021-11-16",
        "state": null,
        "tags": [
            "data"
        ],
        "url": "https://odsc.com/california/aix-west"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "San Francisco, CA",
        "country": "U.S.A.",
        "end_date": "2021-11-18",
        "kind": "conference",
        "location": "San Francisco, CA, U.S.A.",
        "name": "ODSC West",
        "source": "https://confs.tech",
        "start_date": "2021-11-16",
        "state": null,
        "tags": [
            "data"
        ],
        "url": "https://odsc.com/california"
    },
    {
        "by": "bot",
        "cfp_end_date": "2021-06-30",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-11-20",
        "kind": "conference",
        "location": "",
        "name": "IT NonStop",
        "source": "https://confs.tech",
        "start_date": "2021-11-18",
        "state": null,
        "tags": [
            "data"
        ],
        "url": "https://it-nonstop.net"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Berlin",
        "country": "Germany",
        "end_date": "2021-11-24",
        "kind": "conference",
        "location": "Berlin, Germany",
        "name": "API Summit, DDD Summit & Microservices Summit",
        "source": "https://confs.tech",
        "start_date": "2021-11-22",
        "state": null,
        "tags": [
            "data"
        ],
        "url": "https://api-summit.de/berlin"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-11-25",
        "kind": "conference",
        "location": "",
        "name": "ML Conference Singapore",
        "source": "https://confs.tech",
        "start_date": "2021-11-23",
        "state": null,
        "tags": [
            "data"
        ],
        "url": "https://mlconference.ai/singapore"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-11-24",
        "kind": "conference",
        "location": "",
        "name": "Minds Mastering Machines \u2013 Special Day MLOps",
        "source": "https://confs.tech",
        "start_date": "2021-11-24",
        "state": null,
        "tags": [
            "data"
        ],
        "url": "https://m3-konferenz.de/mlops.php"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Berlin",
        "country": "Germany",
        "end_date": "2021-12-08",
        "kind": "conference",
        "location": "Berlin, Germany",
        "name": "ML Conference Berlin",
        "source": "https://confs.tech",
        "start_date": "2021-12-06",
        "state": null,
        "tags": [
            "data"
        ],
        "url": "https://mlconference.ai/berlin"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Berlin",
        "country": "Germany",
        "end_date": "2021-12-08",
        "kind": "conference",
        "location": "Berlin, Germany",
        "name": "Voice Conference",
        "source": "https://confs.tech",
        "start_date": "2021-12-06",
        "state": null,
        "tags": [
            "data"
        ],
        "url": "https://voicecon.net"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-12-08",
        "kind": "conference",
        "location": "",
        "name": "data2day",
        "source": "https://confs.tech",
        "start_date": "2021-12-08",
        "state": null,
        "tags": [
            "data"
        ],
        "url": "https://www.data2day.de"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-04-28",
        "kind": "conference",
        "location": "",
        "name": "Rust Day",
        "source": "https://confs.tech",
        "start_date": "2021-04-28",
        "state": null,
        "tags": [
            "rust"
        ],
        "url": "https://kiosk.entwickler.de/rust-day"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-05-03",
        "kind": "conference",
        "location": "",
        "name": "Cloud Native Rust Day",
        "source": "https://confs.tech",
        "start_date": "2021-05-03",
        "state": null,
        "tags": [
            "rust"
        ],
        "url": "https://events.linuxfoundation.org/cloud-native-rust-day"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-10-13",
        "kind": "conference",
        "location": "",
        "name": "betterCode Rust",
        "source": "https://confs.tech",
        "start_date": "2021-10-13",
        "state": null,
        "tags": [
            "rust"
        ],
        "url": "https://rust.bettercode.eu"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-12-07",
        "kind": "conference",
        "location": "",
        "name": "Rust Summit",
        "source": "https://confs.tech",
        "start_date": "2021-12-06",
        "state": null,
        "tags": [
            "rust"
        ],
        "url": "https://entwickler.de/rust-summit"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-05-07",
        "kind": "conference",
        "location": "",
        "name": "C++Now",
        "source": "https://confs.tech",
        "start_date": "2021-05-02",
        "state": null,
        "tags": [
            "cpp"
        ],
        "url": "https://cppnow.org"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Aurora, CO",
        "country": "U.S.A.",
        "end_date": "2021-10-29",
        "kind": "conference",
        "location": "Aurora, CO, U.S.A.",
        "name": "CppCon",
        "source": "https://confs.tech",
        "start_date": "2021-10-24",
        "state": null,
        "tags": [
            "cpp"
        ],
        "url": "https://cppcon.org"
    },
    {
        "by": "bot",
        "cfp_end_date": "2021-06-30",
        "cfp_open": false,
        "city": "Houston, TX",
        "country": "U.S.A.",
        "end_date": "2021-09-24",
        "kind": "conference",
        "location": "Houston, TX, U.S.A.",
        "name": "Into the Box",
        "source": "https://confs.tech",
        "start_date": "2021-09-23",
        "state": null,
        "tags": [
            "cfml"
        ],
        "url": "https://intothebox.org"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-12-08",
        "kind": "conference",
        "location": "",
        "name": "CFSummit",
        "source": "https://confs.tech",
        "start_date": "2021-12-07",
        "state": null,
        "tags": [
            "cfml"
        ],
        "url": "https://cfsummit2021.com"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-02-25",
        "kind": "conference",
        "location": "",
        "name": "SKILup Day: Cloud Native and Serverless",
        "source": "https://confs.tech",
        "start_date": "2021-02-25",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://devopsinstitute.com/cns-2021"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-03-03",
        "kind": "conference",
        "location": "",
        "name": "Devopsdays Texas",
        "source": "https://confs.tech",
        "start_date": "2021-03-02",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://devopsdays.org/events/2021-texas/welcome"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Birmingham",
        "country": "U.K.",
        "end_date": "2021-03-05",
        "kind": "conference",
        "location": "Birmingham, U.K.",
        "name": "Devopsdays Birmingham",
        "source": "https://confs.tech",
        "start_date": "2021-03-04",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://devopsdays.org/events/2021-birmingham/welcome"
    },
    {
        "by": "bot",
        "cfp_end_date": "2021-02-28",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-03-18",
        "kind": "conference",
        "location": "",
        "name": "ProgressiveDelivery & SLO Conf",
        "source": "https://confs.tech",
        "start_date": "2021-03-18",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://progressivedeliveryconf21.heysummit.com"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-03-18",
        "kind": "conference",
        "location": "",
        "name": "SKILup Day: Value Stream Management",
        "source": "https://confs.tech",
        "start_date": "2021-03-18",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://devopsinstitute.com/vsm-2021"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-03-24",
        "kind": "conference",
        "location": "",
        "name": "Solocon",
        "source": "https://confs.tech",
        "start_date": "2021-03-23",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://solocon.io"
    },
    {
        "by": "bot",
        "cfp_end_date": "2021-01-31",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-03-24",
        "kind": "conference",
        "location": "",
        "name": "The DEVOPS Conference",
        "source": "https://confs.tech",
        "start_date": "2021-03-23",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://www.thedevopsconference.com"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Sydney",
        "country": "Australia",
        "end_date": "2021-03-26",
        "kind": "conference",
        "location": "Sydney, Australia",
        "name": "DevOps Talks Conference",
        "source": "https://confs.tech",
        "start_date": "2021-03-25",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://devops.talksplus.com/sydney/devops.html"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Boise, ID",
        "country": "U.S.A.",
        "end_date": "2021-04-07",
        "kind": "conference",
        "location": "Boise, ID, U.S.A.",
        "name": "Devopsdays Boise",
        "source": "https://confs.tech",
        "start_date": "2021-04-06",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://devopsdays.org/events/2021-boise/welcome"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Raleigh, NC",
        "country": "U.S.A.",
        "end_date": "2021-04-08",
        "kind": "conference",
        "location": "Raleigh, NC, U.S.A.",
        "name": "Devopsdays Raleigh",
        "source": "https://confs.tech",
        "start_date": "2021-04-08",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://devopsdays.org/events/2021-raleigh/welcome"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "London",
        "country": "U.K.",
        "end_date": "2021-04-23",
        "kind": "conference",
        "location": "London, U.K.",
        "name": "DevOpsCon London",
        "source": "https://confs.tech",
        "start_date": "2021-04-20",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://devopscon.io/london"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-04-22",
        "kind": "conference",
        "location": "",
        "name": "SKILup Day: Agile Transformation",
        "source": "https://confs.tech",
        "start_date": "2021-04-22",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://devopsinstitute.com/at-2021"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-05-04",
        "kind": "conference",
        "location": "",
        "name": "Cloud Native Wasm Day",
        "source": "https://confs.tech",
        "start_date": "2021-05-04",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://events.linuxfoundation.org/cloud-native-wasm-day"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-05-04",
        "kind": "conference",
        "location": "",
        "name": "Devopsdays Seattle",
        "source": "https://confs.tech",
        "start_date": "2021-05-04",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://devopsdays.org/events/2021-seattle/welcome"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-05-04",
        "kind": "conference",
        "location": "",
        "name": "ServiceMeshCon",
        "source": "https://confs.tech",
        "start_date": "2021-05-04",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://events.linuxfoundation.org/servicemeshcon-europe"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-05-04",
        "kind": "conference",
        "location": "",
        "name": "fluentcon",
        "source": "https://confs.tech",
        "start_date": "2021-05-04",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://events.linuxfoundation.org/fluentcon"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-05-07",
        "kind": "conference",
        "location": "",
        "name": "KubeCon + CloudNativeCon EU",
        "source": "https://confs.tech",
        "start_date": "2021-05-04",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://events.linuxfoundation.org/kubecon-cloudnativecon-europe"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-05-13",
        "kind": "conference",
        "location": "",
        "name": "DevOps Pro Europe",
        "source": "https://confs.tech",
        "start_date": "2021-05-11",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://devopspro.lt"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Paris",
        "country": "France",
        "end_date": "2021-05-18",
        "kind": "conference",
        "location": "Paris, France",
        "name": "Devopsdays Paris",
        "source": "https://confs.tech",
        "start_date": "2021-05-18",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://devopsdays.org/events/2021-paris/welcome"
    },
    {
        "by": "bot",
        "cfp_end_date": "2021-02-19",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-05-20",
        "kind": "conference",
        "location": "",
        "name": "DevOps Enterprise Summit Virtual - Europe",
        "source": "https://confs.tech",
        "start_date": "2021-05-18",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://events.itrevolution.com/virtual"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-05-20",
        "kind": "conference",
        "location": "",
        "name": "SKILup Day: Site Reliability Engineering (SRE)",
        "source": "https://confs.tech",
        "start_date": "2021-05-20",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://devopsinstitute.com/sre-2021"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Porto",
        "country": "Portugal",
        "end_date": "2021-05-25",
        "kind": "conference",
        "location": "Porto, Portugal",
        "name": "Devopsdays Portugal",
        "source": "https://confs.tech",
        "start_date": "2021-05-24",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://devopsdays.org/events/2021-portugal/welcome"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Porto",
        "country": "Portugal",
        "end_date": "2021-05-25",
        "kind": "conference",
        "location": "Porto, Portugal",
        "name": "Devopsdays Poznan",
        "source": "https://confs.tech",
        "start_date": "2021-05-24",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://devopsdays.org/events/2021-poznan/welcome"
    },
    {
        "by": "bot",
        "cfp_end_date": "2021-02-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-05-27",
        "kind": "conference",
        "location": "",
        "name": "swampUP",
        "source": "https://confs.tech",
        "start_date": "2021-05-25",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://swampup.jfrog.com"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-05-27",
        "kind": "conference",
        "location": "",
        "name": "DockerCon Live",
        "source": "https://confs.tech",
        "start_date": "2021-05-27",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://www.docker.com/dockercon"
    },
    {
        "by": "bot",
        "cfp_end_date": "2021-02-23",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-06-03",
        "kind": "conference",
        "location": "",
        "name": "LISA",
        "source": "https://confs.tech",
        "start_date": "2021-06-01",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://www.usenix.org/conference/lisa21"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Prague",
        "country": "Czech Republic",
        "end_date": "2021-06-03",
        "kind": "conference",
        "location": "Prague, Czech Republic",
        "name": "Devopsdays Prague",
        "source": "https://confs.tech",
        "start_date": "2021-06-02",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://devopsdays.org/events/2021-prague/welcome"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-06-09",
        "kind": "conference",
        "location": "",
        "name": "DDD Summit",
        "source": "https://confs.tech",
        "start_date": "2021-06-07",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://ddd-summit.de/muenchen"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Munich",
        "country": "Germany",
        "end_date": "2021-06-09",
        "kind": "conference",
        "location": "Munich, Germany",
        "name": "Microservices Summit",
        "source": "https://confs.tech",
        "start_date": "2021-06-07",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://microservices-summit.de"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "London",
        "country": "U.K.",
        "end_date": "2021-06-09",
        "kind": "conference",
        "location": "London, U.K.",
        "name": "Lead Dev London",
        "source": "https://confs.tech",
        "start_date": "2021-06-08",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://theleaddeveloper.com"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Berlin",
        "country": "Germany",
        "end_date": "2021-06-17",
        "kind": "conference",
        "location": "Berlin, Germany",
        "name": "DevOps Conference Hybrid Edition",
        "source": "https://confs.tech",
        "start_date": "2021-06-14",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://devopscon.io/berlin"
    },
    {
        "by": "bot",
        "cfp_end_date": "2021-02-28",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-06-16",
        "kind": "conference",
        "location": "",
        "name": "stackconf online",
        "source": "https://confs.tech",
        "start_date": "2021-06-15",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://stackconf.eu"
    },
    {
        "by": "bot",
        "cfp_end_date": "2021-04-30",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-06-17",
        "kind": "conference",
        "location": "",
        "name": "{unscripted}",
        "source": "https://confs.tech",
        "start_date": "2021-06-16",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://www.unscriptedconf.io"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-06-24",
        "kind": "conference",
        "location": "",
        "name": "PagerDuty Summit",
        "source": "https://confs.tech",
        "start_date": "2021-06-22",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://www.summit.pagerduty.com"
    },
    {
        "by": "bot",
        "cfp_end_date": "2021-03-05",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-06-24",
        "kind": "conference",
        "location": "",
        "name": "cdCon",
        "source": "https://confs.tech",
        "start_date": "2021-06-23",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://events.linuxfoundation.org/cdcon"
    },
    {
        "by": "bot",
        "cfp_end_date": "2021-05-31",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-06-29",
        "kind": "conference",
        "location": "",
        "name": "Devopsdays NL",
        "source": "https://confs.tech",
        "start_date": "2021-06-29",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://devopsdays.org/events/2021-amsterdam/welcome"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Zurich",
        "country": "Switzerland",
        "end_date": "2021-06-30",
        "kind": "conference",
        "location": "Zurich, Switzerland",
        "name": "DevOps Fusion",
        "source": "https://confs.tech",
        "start_date": "2021-06-30",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://devops-fusion.com"
    },
    {
        "by": "bot",
        "cfp_end_date": "2021-04-30",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-07-08",
        "kind": "conference",
        "location": "",
        "name": "ContainerDays",
        "source": "https://confs.tech",
        "start_date": "2021-07-06",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://www.containerdays.io"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-07-10",
        "kind": "conference",
        "location": "",
        "name": "Devopsdays Porto Alegre",
        "source": "https://confs.tech",
        "start_date": "2021-07-10",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://devopsdays.org/events/2021-porto-alegre/welcome"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Minneapolis, MN",
        "country": "U.S.A.",
        "end_date": "2021-07-21",
        "kind": "conference",
        "location": "Minneapolis, MN, U.S.A.",
        "name": "Devopsdays Minneapolis",
        "source": "https://confs.tech",
        "start_date": "2021-07-20",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://devopsdays.org/events/2021-minneapolis/welcome"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-07-21",
        "kind": "conference",
        "location": "",
        "name": "Devopsdays Portland",
        "source": "https://confs.tech",
        "start_date": "2021-07-20",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://devopsdays.org/events/2021-portland/welcome"
    },
    {
        "by": "bot",
        "cfp_end_date": "2021-05-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-07-31",
        "kind": "conference",
        "location": "",
        "name": "Devopsdays Medell\u00edn",
        "source": "https://confs.tech",
        "start_date": "2021-07-30",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://devopsdays.org/events/2021-medellin/welcome"
    },
    {
        "by": "bot",
        "cfp_end_date": "2021-04-30",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-08-04",
        "kind": "conference",
        "location": "",
        "name": "GitLab Commit",
        "source": "https://confs.tech",
        "start_date": "2021-08-03",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://about.gitlab.com/events/commit"
    },
    {
        "by": "bot",
        "cfp_end_date": "2021-06-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-08-05",
        "kind": "conference",
        "location": "",
        "name": "Cloud-Native Days with Kubernetes",
        "source": "https://confs.tech",
        "start_date": "2021-08-04",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://www.mediaopsevents.com/cloudnative2021"
    },
    {
        "by": "bot",
        "cfp_end_date": "2021-05-31",
        "cfp_open": false,
        "city": "Zurich",
        "country": "Switzerland",
        "end_date": "2021-09-08",
        "kind": "conference",
        "location": "Zurich, Switzerland",
        "name": "Devopsdays Zurich",
        "source": "https://confs.tech",
        "start_date": "2021-09-07",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://devopsdays.org/events/2021-zurich/welcome"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-09-10",
        "kind": "conference",
        "location": "",
        "name": "Devopsdays Blumenau",
        "source": "https://confs.tech",
        "start_date": "2021-09-09",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://devopsdays.org/events/2021-blumenau/welcome"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Berlin",
        "country": "Germany",
        "end_date": "2021-09-15",
        "kind": "conference",
        "location": "Berlin, Germany",
        "name": "Das gro\u00dfe Trainingsevent f\u00fcr Softwarearchitektur",
        "source": "https://confs.tech",
        "start_date": "2021-09-13",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://software-architecture-summit.de/berlin"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Washington, DC",
        "country": "U.S.A.",
        "end_date": "2021-09-17",
        "kind": "conference",
        "location": "Washington, DC, U.S.A.",
        "name": "Devopsdays Washington, DC",
        "source": "https://confs.tech",
        "start_date": "2021-09-16",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://devopsdays.org/events/2021-washington-dc/welcome"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-09-18",
        "kind": "conference",
        "location": "",
        "name": "Devopsdays Istanbul",
        "source": "https://confs.tech",
        "start_date": "2021-09-18",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://devopsdays.org/events/2021-istanbul/welcome"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Houston, TX",
        "country": "U.S.A.",
        "end_date": "2021-09-22",
        "kind": "conference",
        "location": "Houston, TX, U.S.A.",
        "name": "Devopsdays Houston",
        "source": "https://confs.tech",
        "start_date": "2021-09-21",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://devopsdays.org/events/2021-houston/welcome"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Dublin",
        "country": "Ireland",
        "end_date": "2021-09-29",
        "kind": "conference",
        "location": "Dublin, Ireland",
        "name": "Linux Plumbers Conference",
        "source": "https://confs.tech",
        "start_date": "2021-09-27",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://linuxplumbersconf.org"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "New York, NY",
        "country": "U.S.A.",
        "end_date": "2021-09-30",
        "kind": "conference",
        "location": "New York, NY, U.S.A.",
        "name": "DevOpsCon New York",
        "source": "https://confs.tech",
        "start_date": "2021-09-27",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://devopscon.io/new-york"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-09-30",
        "kind": "conference",
        "location": "",
        "name": "Conf42: SRE",
        "source": "https://confs.tech",
        "start_date": "2021-09-30",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://www.conf42.com/sre2021"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-10-05",
        "kind": "conference",
        "location": "",
        "name": "Devopsdays Pozna\u0144",
        "source": "https://confs.tech",
        "start_date": "2021-10-04",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://devopsdays.org/events/2021-poznan/welcome"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "San Francisco, CA",
        "country": "U.S.A.",
        "end_date": "2021-10-07",
        "kind": "conference",
        "location": "San Francisco, CA, U.S.A.",
        "name": "Demuxed",
        "source": "https://confs.tech",
        "start_date": "2021-10-05",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://2021.demuxed.com"
    },
    {
        "by": "bot",
        "cfp_end_date": "2021-02-26",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-10-07",
        "kind": "conference",
        "location": "",
        "name": "DevOps Enterprise Summit Virtual - US",
        "source": "https://confs.tech",
        "start_date": "2021-10-05",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://events.itrevolution.com/virtual"
    },
    {
        "by": "bot",
        "cfp_end_date": "2021-07-31",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-10-08",
        "kind": "conference",
        "location": "",
        "name": "containerday Digital Edition",
        "source": "https://confs.tech",
        "start_date": "2021-10-08",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://2021.containerday.it"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-10-15",
        "kind": "conference",
        "location": "",
        "name": "KubeCon + CloudNativeCon North America",
        "source": "https://confs.tech",
        "start_date": "2021-10-12",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://events.linuxfoundation.org/kubecon-cloudnativecon-north-america"
    },
    {
        "by": "bot",
        "cfp_end_date": "2021-07-31",
        "cfp_open": false,
        "city": "Buffalo, NY",
        "country": "U.S.A.",
        "end_date": "2021-10-14",
        "kind": "conference",
        "location": "Buffalo, NY, U.S.A.",
        "name": "Devopsdays Buffalo",
        "source": "https://confs.tech",
        "start_date": "2021-10-13",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://devopsdays.org/events/2021-buffalo/welcome"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-10-22",
        "kind": "conference",
        "location": "",
        "name": "HashiConf Global",
        "source": "https://confs.tech",
        "start_date": "2021-10-19",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://hashiconf.com"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-10-27",
        "kind": "conference",
        "location": "",
        "name": "Dash",
        "source": "https://confs.tech",
        "start_date": "2021-10-26",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://www.dashcon.io"
    },
    {
        "by": "bot",
        "cfp_end_date": "2021-09-12",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-10-29",
        "kind": "conference",
        "location": "",
        "name": "Cloud Nein",
        "source": "https://confs.tech",
        "start_date": "2021-10-28",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://cloudne.in"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Melbourne",
        "country": "Australia",
        "end_date": "2021-10-29",
        "kind": "conference",
        "location": "Melbourne, Australia",
        "name": "Devopsdays Melbourne",
        "source": "https://confs.tech",
        "start_date": "2021-10-28",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://devopsdays.org/events/2021-melbourne/welcome"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Nashville, TN",
        "country": "U.S.A.",
        "end_date": "2021-10-29",
        "kind": "conference",
        "location": "Nashville, TN, U.S.A.",
        "name": "Devopsdays Nashville",
        "source": "https://confs.tech",
        "start_date": "2021-10-28",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://devopsdays.org/events/2021-nashville/welcome"
    },
    {
        "by": "bot",
        "cfp_end_date": "2021-09-30",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-10-30",
        "kind": "conference",
        "location": "",
        "name": "Software Architecture fwdays conference",
        "source": "https://confs.tech",
        "start_date": "2021-10-30",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://fwdays.com/en/event/architecture-fwdays-2021"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Nashville, TN",
        "country": "U.S.A.",
        "end_date": "2021-11-04",
        "kind": "conference",
        "location": "Nashville, TN, U.S.A.",
        "name": "Automation + DevOps Summit",
        "source": "https://confs.tech",
        "start_date": "2021-11-02",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://www.automationsummit.org"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "D\u00fcsseldorf",
        "country": "Germany",
        "end_date": "2021-11-10",
        "kind": "conference",
        "location": "D\u00fcsseldorf, Germany",
        "name": "EKON",
        "source": "https://confs.tech",
        "start_date": "2021-11-08",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://entwickler-konferenz.de/de"
    },
    {
        "by": "bot",
        "cfp_end_date": "2021-09-22",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-11-10",
        "kind": "conference",
        "location": "",
        "name": "Grafana ObservabilityCon",
        "source": "https://confs.tech",
        "start_date": "2021-11-08",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://grafana.com/about/events/observabilitycon/2021"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Potsdam",
        "country": "Germany",
        "end_date": "2021-11-18",
        "kind": "conference",
        "location": "Potsdam, Germany",
        "name": "Agile Testing Days",
        "source": "https://confs.tech",
        "start_date": "2021-11-15",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://agiletestingdays.com"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-11-17",
        "kind": "conference",
        "location": "",
        "name": "deploy",
        "source": "https://confs.tech",
        "start_date": "2021-11-16",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://deploy.digitalocean.com"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-11-18",
        "kind": "conference",
        "location": "",
        "name": "Continuous Lifecycle",
        "source": "https://confs.tech",
        "start_date": "2021-11-17",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://www.continuouslifecycle.de"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-11-25",
        "kind": "conference",
        "location": "",
        "name": "DevOpsCon Singapore",
        "source": "https://confs.tech",
        "start_date": "2021-11-22",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://devopscon.io/singapore"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Tel Aviv",
        "country": "Israel",
        "end_date": "2021-11-25",
        "kind": "conference",
        "location": "Tel Aviv, Israel",
        "name": "DevOpsDays Tel Aviv",
        "source": "https://confs.tech",
        "start_date": "2021-11-24",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://tlvcommunity.dev/devopsdays"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Bogot\u00e1",
        "country": "Colombia",
        "end_date": "2021-11-25",
        "kind": "conference",
        "location": "Bogot\u00e1, Colombia",
        "name": "Devopsdays Bogot\u00e1",
        "source": "https://confs.tech",
        "start_date": "2021-11-24",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://devopsdays.org/events/2021-bogota/welcome"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Munich",
        "country": "Germany",
        "end_date": "2021-12-02",
        "kind": "conference",
        "location": "Munich, Germany",
        "name": "DevOps Conference Munich",
        "source": "https://confs.tech",
        "start_date": "2021-11-29",
        "state": null,
        "tags": [
            "devops"
        ],
        "url": "https://devopscon.io/munich"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-02-18",
        "kind": "conference",
        "location": "",
        "name": "HackOn",
        "source": "https://confs.tech",
        "start_date": "2021-02-18",
        "state": null,
        "tags": [
            "security"
        ],
        "url": "https://hackon.es"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-02-25",
        "kind": "conference",
        "location": "",
        "name": "sec4dev",
        "source": "https://confs.tech",
        "start_date": "2021-02-22",
        "state": null,
        "tags": [
            "security"
        ],
        "url": "https://sec4dev.io"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Tampa, FL",
        "country": "U.S.A.",
        "end_date": "2021-02-27",
        "kind": "conference",
        "location": "Tampa, FL, U.S.A.",
        "name": "B-Sides Tampa",
        "source": "https://confs.tech",
        "start_date": "2021-02-27",
        "state": null,
        "tags": [
            "security"
        ],
        "url": "https://bsidestampa.net"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-03-19",
        "kind": "conference",
        "location": "",
        "name": "Virtual Security Operation Center Summit Budapest",
        "source": "https://confs.tech",
        "start_date": "2021-03-18",
        "state": null,
        "tags": [
            "security"
        ],
        "url": "https://www.socsummit.eu"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-04-07",
        "kind": "conference",
        "location": "",
        "name": "CAW-Cyber awareness week",
        "source": "https://confs.tech",
        "start_date": "2021-04-01",
        "state": null,
        "tags": [
            "security"
        ],
        "url": "https://www.caw.asia"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-05-05",
        "kind": "conference",
        "location": "",
        "name": "IT Security Camp",
        "source": "https://confs.tech",
        "start_date": "2021-05-03",
        "state": null,
        "tags": [
            "security"
        ],
        "url": "https://it-security-camp.de"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-05-04",
        "kind": "conference",
        "location": "",
        "name": "Cloud Native Security Day",
        "source": "https://confs.tech",
        "start_date": "2021-05-04",
        "state": null,
        "tags": [
            "security"
        ],
        "url": "https://events.linuxfoundation.org/cloud-native-security-day-europe"
    },
    {
        "by": "bot",
        "cfp_end_date": "2021-03-10",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-05-06",
        "kind": "conference",
        "location": "",
        "name": "Qubit Conference New York",
        "source": "https://confs.tech",
        "start_date": "2021-05-05",
        "state": null,
        "tags": [
            "security"
        ],
        "url": "https://nyc.qubitconference.com"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Bochum",
        "country": "Germany",
        "end_date": "2021-05-21",
        "kind": "conference",
        "location": "Bochum, Germany",
        "name": "RuhrSec",
        "source": "https://confs.tech",
        "start_date": "2021-05-18",
        "state": null,
        "tags": [
            "security"
        ],
        "url": "https://www.ruhrsec.de"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Munich",
        "country": "Germany",
        "end_date": "2021-05-21",
        "kind": "conference",
        "location": "Munich, Germany",
        "name": "IT Security Summit",
        "source": "https://confs.tech",
        "start_date": "2021-05-19",
        "state": null,
        "tags": [
            "security"
        ],
        "url": "https://it-security-summit.de/muenchen"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Jasna",
        "country": "Slovakia",
        "end_date": "2021-05-27",
        "kind": "conference",
        "location": "Jasna, Slovakia",
        "name": "QuBit Conference",
        "source": "https://confs.tech",
        "start_date": "2021-05-26",
        "state": null,
        "tags": [
            "security"
        ],
        "url": "https://tatry.qubitconference.com"
    },
    {
        "by": "bot",
        "cfp_end_date": "2021-06-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-06-03",
        "kind": "conference",
        "location": "",
        "name": "IdentityNORTH Annual Summit",
        "source": "https://confs.tech",
        "start_date": "2021-06-02",
        "state": null,
        "tags": [
            "security"
        ],
        "url": "https://www.identitynorth.ca/events/identitynorth2021"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Las Vegas, NV",
        "country": "U.S.A.",
        "end_date": "2021-08-05",
        "kind": "conference",
        "location": "Las Vegas, NV, U.S.A.",
        "name": "BlackHat USA",
        "source": "https://confs.tech",
        "start_date": "2021-07-31",
        "state": null,
        "tags": [
            "security"
        ],
        "url": "https://blackhat.com/us-21"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-08-08",
        "kind": "conference",
        "location": "",
        "name": "DEF CON",
        "source": "https://confs.tech",
        "start_date": "2021-08-05",
        "state": null,
        "tags": [
            "security"
        ],
        "url": "https://defcon.org"
    },
    {
        "by": "bot",
        "cfp_end_date": "2021-03-01",
        "cfp_open": false,
        "city": "Denver, CO",
        "country": "U.S.A.",
        "end_date": "2021-09-10",
        "kind": "conference",
        "location": "Denver, CO, U.S.A.",
        "name": "Women in CyberSecurity (WiCyS)",
        "source": "https://confs.tech",
        "start_date": "2021-09-08",
        "state": null,
        "tags": [
            "security"
        ],
        "url": "https://www.wicys.org/events/wicys-2021"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-09-23",
        "kind": "conference",
        "location": "",
        "name": "HexCon",
        "source": "https://confs.tech",
        "start_date": "2021-09-21",
        "state": null,
        "tags": [
            "security"
        ],
        "url": "https://www.hexnode.com/events/hexcon21"
    },
    {
        "by": "bot",
        "cfp_end_date": "2021-06-27",
        "cfp_open": false,
        "city": "Dublin",
        "country": "Ireland",
        "end_date": "2021-09-29",
        "kind": "conference",
        "location": "Dublin, Ireland",
        "name": "Linux Security Summit Europe",
        "source": "https://confs.tech",
        "start_date": "2021-09-27",
        "state": null,
        "tags": [
            "security"
        ],
        "url": "https://events.linuxfoundation.org/linux-security-summit-europe"
    },
    {
        "by": "bot",
        "cfp_end_date": "2021-07-11",
        "cfp_open": false,
        "city": "Seattle, WA",
        "country": "U.S.A.",
        "end_date": "2021-10-01",
        "kind": "conference",
        "location": "Seattle, WA, U.S.A.",
        "name": "Linux Security Summit",
        "source": "https://confs.tech",
        "start_date": "2021-09-29",
        "state": null,
        "tags": [
            "security"
        ],
        "url": "https://events.linuxfoundation.org/linux-security-summit-north-america"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Augusta, GA",
        "country": "U.S.A.",
        "end_date": "2021-10-01",
        "kind": "conference",
        "location": "Augusta, GA, U.S.A.",
        "name": "Security Onion Conference",
        "source": "https://confs.tech",
        "start_date": "2021-10-01",
        "state": null,
        "tags": [
            "security"
        ],
        "url": "https://securityonionsolutions.com/conference"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Augusta, GA",
        "country": "U.S.A.",
        "end_date": "2021-10-02",
        "kind": "conference",
        "location": "Augusta, GA, U.S.A.",
        "name": "BSides",
        "source": "https://confs.tech",
        "start_date": "2021-10-02",
        "state": null,
        "tags": [
            "security"
        ],
        "url": "https://bsidesaugusta.org"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-10-29",
        "kind": "conference",
        "location": "",
        "name": "Ory Summit",
        "source": "https://confs.tech",
        "start_date": "2021-10-28",
        "state": null,
        "tags": [
            "security"
        ],
        "url": "https://ory.sh/summit21"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-11-05",
        "kind": "conference",
        "location": "",
        "name": "CyberSec&AI Connected",
        "source": "https://confs.tech",
        "start_date": "2021-11-04",
        "state": null,
        "tags": [
            "security"
        ],
        "url": "https://cybersecai.com"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-01-22",
        "kind": "conference",
        "location": "",
        "name": "OLX D'Light",
        "source": "https://confs.tech",
        "start_date": "2021-01-21",
        "state": null,
        "tags": [
            "ux"
        ],
        "url": "https://olxdlight.com"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Tulsa, OK",
        "country": "U.S.A.",
        "end_date": "2021-02-05",
        "kind": "conference",
        "location": "Tulsa, OK, U.S.A.",
        "name": "UXOK",
        "source": "https://confs.tech",
        "start_date": "2021-02-05",
        "state": null,
        "tags": [
            "ux"
        ],
        "url": "https://uxok.org"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-02-12",
        "kind": "conference",
        "location": "",
        "name": "UXLx Masters",
        "source": "https://confs.tech",
        "start_date": "2021-02-10",
        "state": null,
        "tags": [
            "ux"
        ],
        "url": "https://masters.ux-lx.com"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Chandigarh",
        "country": "India",
        "end_date": "2021-02-12",
        "kind": "conference",
        "location": "Chandigarh, India",
        "name": "Outcome",
        "source": "https://confs.tech",
        "start_date": "2021-02-11",
        "state": null,
        "tags": [
            "ux"
        ],
        "url": "https://outcomeconf.com"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-02-19",
        "kind": "conference",
        "location": "",
        "name": "World-class Designer Conference",
        "source": "https://confs.tech",
        "start_date": "2021-02-18",
        "state": null,
        "tags": [
            "ux"
        ],
        "url": "http://conf.wcd.school"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Birmingham",
        "country": "U.K.",
        "end_date": "2021-03-18",
        "kind": "conference",
        "location": "Birmingham, U.K.",
        "name": "Canvas",
        "source": "https://confs.tech",
        "start_date": "2021-03-18",
        "state": null,
        "tags": [
            "ux"
        ],
        "url": "https://www.canvasconference.co.uk"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-04-15",
        "kind": "conference",
        "location": "",
        "name": "The BAD Conference",
        "source": "https://confs.tech",
        "start_date": "2021-04-14",
        "state": null,
        "tags": [
            "ux"
        ],
        "url": "https://thebadconference.com"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-04-27",
        "kind": "conference",
        "location": "",
        "name": "Smashing Meets",
        "source": "https://confs.tech",
        "start_date": "2021-04-27",
        "state": null,
        "tags": [
            "ux"
        ],
        "url": "https://smashingconf.com/meets-actions"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-04-30",
        "kind": "conference",
        "location": "",
        "name": "IAC",
        "source": "https://confs.tech",
        "start_date": "2021-04-28",
        "state": null,
        "tags": [
            "ux"
        ],
        "url": "https://www.theiaconference.com"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-05-27",
        "kind": "conference",
        "location": "",
        "name": "Global FinTech Design Summit",
        "source": "https://confs.tech",
        "start_date": "2021-05-25",
        "state": null,
        "tags": [
            "ux"
        ],
        "url": "https://fintechdesignsummit.com"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-06-06",
        "kind": "conference",
        "location": "",
        "name": "UXcamp Europe",
        "source": "https://confs.tech",
        "start_date": "2021-06-05",
        "state": null,
        "tags": [
            "ux"
        ],
        "url": "https://www.uxcampeurope.org"
    },
    {
        "by": "bot",
        "cfp_end_date": "2021-01-14",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-06-11",
        "kind": "conference",
        "location": "",
        "name": "webinale",
        "source": "https://confs.tech",
        "start_date": "2021-06-07",
        "state": null,
        "tags": [
            "ux"
        ],
        "url": "https://webinale.de/en"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-06-09",
        "kind": "conference",
        "location": "",
        "name": "DDDx: Domain-Driven Design eXchange",
        "source": "https://confs.tech",
        "start_date": "2021-06-08",
        "state": null,
        "tags": [
            "ux"
        ],
        "url": "http://ddd-exchange.com"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-07-14",
        "kind": "conference",
        "location": "",
        "name": "CSSCAMP",
        "source": "https://confs.tech",
        "start_date": "2021-07-14",
        "state": null,
        "tags": [
            "ux"
        ],
        "url": "https://csscamp.tech"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-09-19",
        "kind": "conference",
        "location": "",
        "name": "Savvy UX Summit",
        "source": "https://confs.tech",
        "start_date": "2021-09-17",
        "state": null,
        "tags": [
            "ux"
        ],
        "url": "https://www.savvyuxsummit.com"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-09-24",
        "kind": "conference",
        "location": "",
        "name": "UX Y'all",
        "source": "https://confs.tech",
        "start_date": "2021-09-23",
        "state": null,
        "tags": [
            "ux"
        ],
        "url": "https://www.uxyall.org"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Budapest",
        "country": "Hungary",
        "end_date": "2021-10-06",
        "kind": "conference",
        "location": "Budapest, Hungary",
        "name": "Amuse",
        "source": "https://confs.tech",
        "start_date": "2021-10-04",
        "state": null,
        "tags": [
            "ux"
        ],
        "url": "https://amuseconf.com"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Graz",
        "country": "Austria",
        "end_date": "2021-10-14",
        "kind": "conference",
        "location": "Graz, Austria",
        "name": "World Usability Congress",
        "source": "https://confs.tech",
        "start_date": "2021-10-13",
        "state": null,
        "tags": [
            "ux"
        ],
        "url": "https://worldusabilitycongress.com"
    },
    {
        "by": "bot",
        "cfp_end_date": "2021-05-07",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-10-22",
        "kind": "conference",
        "location": "",
        "name": "PUSH UX",
        "source": "https://confs.tech",
        "start_date": "2021-10-21",
        "state": null,
        "tags": [
            "ux"
        ],
        "url": "https://push-conference.com"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Ottawa",
        "country": "Canada",
        "end_date": "2021-11-07",
        "kind": "conference",
        "location": "Ottawa, Canada",
        "name": "CanUX",
        "source": "https://confs.tech",
        "start_date": "2021-11-04",
        "state": null,
        "tags": [
            "ux"
        ],
        "url": "https://canux.io"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "London",
        "country": "U.K.",
        "end_date": "2021-11-26",
        "kind": "conference",
        "location": "London, U.K.",
        "name": "UX Live",
        "source": "https://confs.tech",
        "start_date": "2021-11-25",
        "state": null,
        "tags": [
            "ux"
        ],
        "url": "https://uxliveconference.com"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Tokyo",
        "country": "Japan",
        "end_date": "2021-01-05",
        "kind": "conference",
        "location": "Tokyo, Japan",
        "name": "International Conference on Computational Mathematics and Applied Physics",
        "source": "https://confs.tech",
        "start_date": "2021-01-04",
        "state": null,
        "tags": [
            "general"
        ],
        "url": "http://www.iccmap.iisrc.org"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-01-23",
        "kind": "conference",
        "location": "",
        "name": "Global Diversity CfP Day",
        "source": "https://confs.tech",
        "start_date": "2021-01-23",
        "state": null,
        "tags": [
            "general"
        ],
        "url": "https://www.globaldiversitycfpday.com"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Bremen",
        "country": "Germany",
        "end_date": "2021-01-28",
        "kind": "conference",
        "location": "Bremen, Germany",
        "name": "Univention Summit",
        "source": "https://confs.tech",
        "start_date": "2021-01-28",
        "state": null,
        "tags": [
            "general"
        ],
        "url": "https://www.univention-summit.com"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-02-07",
        "kind": "conference",
        "location": "",
        "name": "FOSDEM",
        "source": "https://confs.tech",
        "start_date": "2021-02-06",
        "state": null,
        "tags": [
            "general"
        ],
        "url": "https://fosdem.org/2021"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": "Amsterdam",
        "country": "Netherlands",
        "end_date": "2021-02-12",
        "kind": "conference",
        "location": "Amsterdam, Netherlands",
        "name": "Frontend Love",
        "source": "https://confs.tech",
        "start_date": "2021-02-08",
        "state": null,
        "tags": [
            "general"
        ],
        "url": "https://www.frontenddeveloperlove.com"
    },
    {
        "by": "bot",
        "cfp_end_date": "2020-12-31",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-02-16",
        "kind": "conference",
        "location": "",
        "name": "InfoQ Live",
        "source": "https://confs.tech",
        "start_date": "2021-02-16",
        "state": null,
        "tags": [
            "general"
        ],
        "url": "https://live.infoq.com"
    },
    {
        "by": "bot",
        "cfp_end_date": "2020-12-11",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-02-19",
        "kind": "conference",
        "location": "",
        "name": "CloudWorld",
        "source": "https://confs.tech",
        "start_date": "2021-02-17",
        "state": null,
        "tags": [
            "general"
        ],
        "url": "https://cloudworldconf.com"
    },
    {
        "by": "bot",
        "cfp_end_date": "2020-10-30",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-02-19",
        "kind": "conference",
        "location": "",
        "name": "DeveloperWeek",
        "source": "https://confs.tech",
        "start_date": "2021-02-17",
        "state": null,
        "tags": [
            "general"
        ],
        "url": "https://www.developerweek.com"
    },
    {
        "by": "bot",
        "cfp_end_date": "1970-01-01",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-02-25",
        "kind": "conference",
        "location": "",
        "name": "Conf42: Chaos Engineering",
        "source": "https://confs.tech",
        "start_date": "2021-02-25",
        "state": null,
        "tags": [
            "general"
        ],
        "url": "https://www.conf42.com/ce2021"
    },
    {
        "by": "bot",
        "cfp_end_date": "2021-02-26",
        "cfp_open": false,
        "city": null,
        "country": null,
        "end_date": "2021-02-26",
        "kind": "conference",
       
Download .txt
gitextract_yyr6quhs/

├── .github/
│   ├── actions/
│   │   └── get-events-action/
│   │       ├── Dockerfile
│   │       ├── action.yml
│   │       └── entrypoint.sh
│   └── workflows/
│       └── main.yml
├── .gitignore
├── .readthedocs.yml
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── HISTORY.md
├── LICENSE
├── README.md
├── conrad/
│   ├── __init__.py
│   ├── __main__.py
│   ├── __version__.py
│   ├── cli.py
│   ├── db.py
│   ├── models.py
│   ├── schema.py
│   └── utils.py
├── crawlers/
│   ├── __init__.py
│   ├── base.py
│   ├── confs_tech/
│   │   ├── __init__.py
│   │   └── confs_tech_crawler.py
│   ├── italy/
│   │   ├── __init__.py
│   │   └── italy_crawler.py
│   ├── papercall/
│   │   ├── __init__.py
│   │   └── papercall_crawler.py
│   ├── pycon/
│   │   ├── __init__.py
│   │   └── pycon_crawler.py
│   ├── pydata/
│   │   ├── __init__.py
│   │   └── pydata_crawler.py
│   └── python/
│       ├── __init__.py
│       └── python_crawler.py
├── data/
│   ├── confstech.json
│   ├── events.json
│   ├── events_v2.json
│   ├── italy.json
│   ├── pycon.json
│   ├── pydata.json
│   └── python.json
├── docs/
│   ├── Makefile
│   ├── _templates/
│   │   ├── hacks.html
│   │   ├── sidebarintro.html
│   │   └── sidebarlogo.html
│   ├── _themes/
│   │   ├── .gitignore
│   │   ├── LICENSE
│   │   └── flask_theme_support.py
│   ├── conf.py
│   ├── dev/
│   │   ├── adding-crawlers.rst
│   │   └── adding-events.rst
│   ├── index.rst
│   └── make.bat
├── setup.py
└── tests/
    ├── test_conrad.py
    └── test_geocoding.py
Download .txt
SYMBOL INDEX (69 symbols across 16 files)

FILE: conrad/__main__.py
  function main (line 9) | def main():

FILE: conrad/__version__.py
  function generate_version (line 8) | def generate_version(version, prerelease=None, revision=None):

FILE: conrad/cli.py
  function has_less (line 43) | def has_less():
  function set_default_pager (line 47) | def set_default_pager():
  function get_events (line 52) | def get_events():
  function rebuild_events_table (line 64) | def rebuild_events_table():
  function set_update_timestamp (line 96) | def set_update_timestamp(overwrite=False):
  function initialize_conrad (line 103) | def initialize_conrad():
  function refresh_conrad (line 112) | def refresh_conrad():
  function clean_old_events (line 123) | def clean_old_events():
  function auto_refresh (line 143) | def auto_refresh():
  function make_exclude_hook_command (line 157) | def make_exclude_hook_command(callback):
  function cli (line 220) | def cli(ctx, *args, **kwargs):
  function _refresh (line 229) | def _refresh(ctx, *args, **kwargs):
  function _show (line 277) | def _show(ctx, *args, **kwargs):
  function _remind (line 389) | def _remind(ctx, *args, **kwargs):
  function _generate (line 499) | def _generate(ctx, *args, **kwargs):
  function _run (line 548) | def _run(ctx, *args, **kwargs):
  function _import (line 591) | def _import(ctx, *args, **kwargs):

FILE: conrad/db.py
  function configure_orm (line 16) | def configure_orm():
  function dispose_orm (line 29) | def dispose_orm():

FILE: conrad/models.py
  class Event (line 12) | class Event(Base):
  class Reminder (line 32) | class Reminder(Base):

FILE: conrad/utils.py
  class SelfCheckState (line 27) | class SelfCheckState(object):
    method __init__ (line 28) | def __init__(self, cache_dir):
    method save (line 41) | def save(self, pypi_version, current_time):
  function get_pypi_version (line 57) | def get_pypi_version():
  function conrad_self_version_check (line 66) | def conrad_self_version_check():
  function initialize_database (line 106) | def initialize_database():
  function reset_database (line 112) | def reset_database():
  function get_address (line 119) | def get_address(place):
  function apply_schema (line 139) | def apply_schema(events, version=LATEST):
  function validate_events (line 150) | def validate_events(input_events, version=LATEST):
  function mkdir (line 173) | def mkdir(directory):

FILE: crawlers/base.py
  class EventValidator (line 11) | class EventValidator(Validator):
    method _validate_is_date (line 12) | def _validate_is_date(self, is_date, field, value):
  class BaseCrawler (line 27) | class BaseCrawler(object):
    method __init__ (line 28) | def __init__(self):
    method get_events (line 31) | def get_events(self):
    method export (line 34) | def export(self, filename):

FILE: crawlers/confs_tech/confs_tech_crawler.py
  function mkdir (line 12) | def mkdir(directory):
  class ConfsTechCrawler (line 17) | class ConfsTechCrawler(BaseCrawler):
    method get_events (line 18) | def get_events(self):

FILE: crawlers/italy/italy_crawler.py
  class ItalyCrawler (line 10) | class ItalyCrawler(BaseCrawler):
    method __init__ (line 17) | def __init__(self, year = 2020):
    method get_events (line 21) | def get_events(self):

FILE: crawlers/papercall/papercall_crawler.py
  function get (line 15) | def get(page):
  function maybe_int (line 20) | def maybe_int(s):
  function num_pages (line 27) | def num_pages():
  function parse_page (line 32) | def parse_page(root):
  function parse_all (line 97) | def parse_all():
  class PapercallCrawler (line 103) | class PapercallCrawler(BaseCrawler):
    method get_events (line 104) | def get_events(self):

FILE: crawlers/pycon/pycon_crawler.py
  class PyConCrawler (line 10) | class PyConCrawler(BaseCrawler):
    method get_events (line 11) | def get_events(self):

FILE: crawlers/pydata/pydata_crawler.py
  class PyDataEvent (line 12) | class PyDataEvent:
    method __init__ (line 13) | def __init__(self, name, city, country, location, start_date, end_date...
    method to_json (line 29) | def to_json(self):
  class PyDataCrawler (line 48) | class PyDataCrawler(BaseCrawler):
    method _format_date (line 58) | def _format_date(self, date_str):
    method _parse_pydata_event (line 61) | def _parse_pydata_event(self, event_article):
    method _parse_pydata_events (line 80) | def _parse_pydata_events(self, event_articles):
    method get_events (line 83) | def get_events(self):

FILE: crawlers/python/python_crawler.py
  class PythonCrawler (line 14) | class PythonCrawler(BaseCrawler):
    method get_events (line 15) | def get_events(self):

FILE: docs/_themes/flask_theme_support.py
  class FlaskyStyle (line 19) | class FlaskyStyle(Style):

FILE: setup.py
  function setup_package (line 42) | def setup_package():

FILE: tests/test_geocoding.py
  function test_bad_place (line 23) | def test_bad_place():
  function test_good_place (line 29) | def test_good_place():
Condensed preview — 55 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (497K chars).
[
  {
    "path": ".github/actions/get-events-action/Dockerfile",
    "chars": 83,
    "preview": "FROM python:3.12\n\nCOPY entrypoint.sh /entrypoint.sh\n\nENTRYPOINT [\"/entrypoint.sh\"]\n"
  },
  {
    "path": ".github/actions/get-events-action/action.yml",
    "chars": 273,
    "preview": "name: \"Get events\"\ndescription: \"Get latest events and raise a PR\"\ninputs:\n  crawler-name: # id of input\n    description"
  },
  {
    "path": ".github/actions/get-events-action/entrypoint.sh",
    "chars": 199,
    "preview": "#!/bin/sh -l\n\npython -m pip install \".[all]\"\n\npython -m conrad run crawler $1\n\nFILENAME=\"data/`echo $1 | awk '{print tol"
  },
  {
    "path": ".github/workflows/main.yml",
    "chars": 1405,
    "preview": "name: Get events\non:\n  schedule:\n    - cron: \"0 0 * * 1,4\"\n  workflow_dispatch:\n\njobs:\n  get_events:\n    name: Get event"
  },
  {
    "path": ".gitignore",
    "chars": 1330,
    "preview": "# VS Code\n.vscode/\n\n# Database\n*conrad.db\n\n# Secrets\n*credentials.json\n*token.pickle\n*google_service_account_credentials"
  },
  {
    "path": ".readthedocs.yml",
    "chars": 594,
    "preview": "# .readthedocs.yml\n# Read the Docs configuration file\n# See https://docs.readthedocs.io/en/stable/config-file/v2.html fo"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "chars": 112,
    "preview": "Be cordial or be on your way. --Kenneth Reitz\n\nhttps://www.kennethreitz.org/essays/be-cordial-or-be-on-your-way\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 4741,
    "preview": "# Contributor's Guide\n\nIf you're reading this, you're probably looking to contribute to conrad. *Time is the only real c"
  },
  {
    "path": "HISTORY.md",
    "chars": 6637,
    "preview": "Release History\n===============\n\nmaster\n------\n\n0.10.2 (2024-12-22)\n-------------------\n\n* Minor fixes.\n\n\n0.10.1 (2021-0"
  },
  {
    "path": "LICENSE",
    "chars": 11343,
    "preview": "                                 Apache License\n                           Version 2.0, January 2004\n                   "
  },
  {
    "path": "README.md",
    "chars": 4432,
    "preview": "<p align=\"center\">\n   <img src=\"https://raw.githubusercontent.com/vinayak-mehta/conrad/master/docs/_static/mozilla-satel"
  },
  {
    "path": "conrad/__init__.py",
    "chars": 264,
    "preview": "# -*- coding: utf-8 -*-\n\nimport os\n\nfrom click import get_app_dir\n\nfrom .__version__ import __version__\n\n\nCONRAD_HOME = "
  },
  {
    "path": "conrad/__main__.py",
    "chars": 220,
    "preview": "# -*- coding: utf-8 -*-\n\nfrom .utils import conrad_self_version_check\n\n\n__all__ = (\"main\",)\n\n\ndef main():\n    from conra"
  },
  {
    "path": "conrad/__version__.py",
    "chars": 733,
    "preview": "# -*- coding: utf-8 -*-\n\nVERSION = (0, 10, 2)\nPRERELEASE = None  # alpha, beta or rc\nREVISION = None\n\n\ndef generate_vers"
  },
  {
    "path": "conrad/cli.py",
    "chars": 20766,
    "preview": "# -*- coding: utf-8 -*-\n\nimport datetime as dt\nimport hashlib\nimport inspect\nimport json\nimport os\nimport re\nimport shut"
  },
  {
    "path": "conrad/db.py",
    "chars": 803,
    "preview": "# -*- coding: utf-8 -*-\n\nimport atexit\n\nfrom sqlalchemy import create_engine\nfrom sqlalchemy.pool import NullPool\nfrom s"
  },
  {
    "path": "conrad/models.py",
    "chars": 936,
    "preview": "# -*- coding: utf-8 -*-\n\nfrom sqlalchemy import Boolean, Column, DateTime, String, Text, ForeignKey\nfrom sqlalchemy.ext."
  },
  {
    "path": "conrad/schema.py",
    "chars": 2014,
    "preview": "# -*- coding: utf-8 -*-\n\nLATEST = \"2\"\n\nf1 = \"events.json\"\nv1 = {\n    \"name\": {\"type\": \"string\", \"minlength\": 1, \"require"
  },
  {
    "path": "conrad/utils.py",
    "chars": 5187,
    "preview": "# -*- coding: utf-8 -*-\n\nimport datetime as dt\nimport json\nimport logging\nimport os\nimport sys\nfrom collections import C"
  },
  {
    "path": "crawlers/__init__.py",
    "chars": 333,
    "preview": "# -*- coding: utf-8 -*-\n\nfrom .pycon.pycon_crawler import PyConCrawler\nfrom .python.python_crawler import PythonCrawler\n"
  },
  {
    "path": "crawlers/base.py",
    "chars": 1104,
    "preview": "# -*- coding: utf-8 -*-\n\nimport json\nimport datetime as dt\n\nfrom cerberus import Validator\n\nfrom conrad.schema import la"
  },
  {
    "path": "crawlers/confs_tech/__init__.py",
    "chars": 24,
    "preview": "# -*- coding: utf-8 -*-\n"
  },
  {
    "path": "crawlers/confs_tech/confs_tech_crawler.py",
    "chars": 2584,
    "preview": "# -*- coding: utf-8 -*-\n\nimport os\nimport json\nfrom pathlib import Path\n\nimport git\n\nfrom ..base import BaseCrawler\n\n\nde"
  },
  {
    "path": "crawlers/italy/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "crawlers/italy/italy_crawler.py",
    "chars": 2140,
    "preview": "# -*- coding: utf-8 -*-\n\nimport json\n\nimport requests\n\nfrom ..base import BaseCrawler\n\n\nclass ItalyCrawler(BaseCrawler):"
  },
  {
    "path": "crawlers/papercall/__init__.py",
    "chars": 24,
    "preview": "# -*- coding: utf-8 -*-\n"
  },
  {
    "path": "crawlers/papercall/papercall_crawler.py",
    "chars": 3204,
    "preview": "# -*- coding: utf-8 -*-\n# https://github.com/coderanger/cfp-scraper/blob/master/papercall.py\n\nimport requests\nimport dat"
  },
  {
    "path": "crawlers/pycon/__init__.py",
    "chars": 24,
    "preview": "# -*- coding: utf-8 -*-\n"
  },
  {
    "path": "crawlers/pycon/pycon_crawler.py",
    "chars": 2532,
    "preview": "# -*- coding: utf-8 -*-\n\nimport datetime as dt\n\nimport pandas\n\nfrom ..base import BaseCrawler\n\n\nclass PyConCrawler(BaseC"
  },
  {
    "path": "crawlers/pydata/__init__.py",
    "chars": 24,
    "preview": "# -*- coding: utf-8 -*-\n"
  },
  {
    "path": "crawlers/pydata/pydata_crawler.py",
    "chars": 2850,
    "preview": "# -*- coding: utf-8 -*-\n\nimport datetime as dt\n\nimport json\nimport requests\nfrom bs4 import BeautifulSoup\n\nfrom ..base i"
  },
  {
    "path": "crawlers/python/__init__.py",
    "chars": 24,
    "preview": "# -*- coding: utf-8 -*-\n"
  },
  {
    "path": "crawlers/python/python_crawler.py",
    "chars": 3160,
    "preview": "# -*- coding: utf-8 -*-\n\nimport os\nimport json\nimport datetime as dt\n\nfrom bs4 import BeautifulSoup\nfrom googleapiclient"
  },
  {
    "path": "data/confstech.json",
    "chars": 250535,
    "preview": "[\n    {\n        \"by\": \"bot\",\n        \"cfp_end_date\": \"2021-01-24\",\n        \"cfp_open\": false,\n        \"city\": null,\n    "
  },
  {
    "path": "data/events.json",
    "chars": 13811,
    "preview": "[\n    {\n        \"by\": \"bot\",\n        \"cfp_end_date\": \"1970-01-01\",\n        \"cfp_open\": false,\n        \"city\": \"Bologna\","
  },
  {
    "path": "data/events_v2.json",
    "chars": 14935,
    "preview": "[\n    {\n        \"by\": \"bot\",\n        \"cfp_end_date\": \"1970-01-01\",\n        \"cfp_open\": false,\n        \"city\": \"Bologna\","
  },
  {
    "path": "data/italy.json",
    "chars": 28275,
    "preview": "[\n    {\n        \"by\": \"bot\",\n        \"cfp_end_date\": \"1970-01-01\",\n        \"cfp_open\": false,\n        \"city\": \"Milano\",\n"
  },
  {
    "path": "data/pycon.json",
    "chars": 10993,
    "preview": "[\n    {\n        \"by\": \"bot\",\n        \"cfp_end_date\": \"2026-01-15\",\n        \"cfp_open\": false,\n        \"city\": \"Hyderabad"
  },
  {
    "path": "data/pydata.json",
    "chars": 2518,
    "preview": "[\n    {\n        \"by\": \"bot\",\n        \"cfp_end_date\": \"1970-01-01\",\n        \"cfp_open\": false,\n        \"city\": null,\n    "
  },
  {
    "path": "data/python.json",
    "chars": 11668,
    "preview": "[\n    {\n        \"by\": \"bot\",\n        \"cfp_end_date\": \"1970-01-01\",\n        \"cfp_open\": false,\n        \"city\": null,\n    "
  },
  {
    "path": "docs/Makefile",
    "chars": 634,
    "preview": "# Minimal makefile for Sphinx documentation\n#\n\n# You can set these variables from the command line, and also\n# from the "
  },
  {
    "path": "docs/_templates/hacks.html",
    "chars": 611,
    "preview": "<style type=\"text/css\">\n  div.section h1 {font-size: 210%;}\n  /* \"Quick Search\" should be capitalized. */\n  div#searchbo"
  },
  {
    "path": "docs/_templates/sidebarintro.html",
    "chars": 653,
    "preview": "<p class=\"logo\">\n  <a href=\"{{ pathto(master_doc) }}\">\n    <img class=\"logo\" src=\"{{ pathto('_static/mozilla-satellite-a"
  },
  {
    "path": "docs/_templates/sidebarlogo.html",
    "chars": 370,
    "preview": "<p class=\"logo\">\n  <a href=\"{{ pathto(master_doc) }}\">\n    <img class=\"logo\" src=\"{{ pathto('_static/mozilla-satellite-a"
  },
  {
    "path": "docs/_themes/.gitignore",
    "chars": 11,
    "preview": "*.pyc\n*.pyo"
  },
  {
    "path": "docs/_themes/LICENSE",
    "chars": 1788,
    "preview": "Copyright (c) 2010 by Armin Ronacher.\n\nSome rights reserved.\n\nRedistribution and use in source and binary forms of the t"
  },
  {
    "path": "docs/_themes/flask_theme_support.py",
    "chars": 3884,
    "preview": "# flasky pygments style based on tango style\nfrom pygments.style import Style\nfrom pygments.token import (\n    Keyword,\n"
  },
  {
    "path": "docs/conf.py",
    "chars": 10429,
    "preview": "# -*- coding: utf-8 -*-\n#\n# conrad documentation build configuration file, created by\n# sphinx-quickstart on Tue Jul 19 "
  },
  {
    "path": "docs/dev/adding-crawlers.rst",
    "chars": 2479,
    "preview": ".. _adding-crawlers:\n\nAdding a crawler\n================\n\n``conrad``'s event database is updated every Monday and Thursda"
  },
  {
    "path": "docs/dev/adding-events.rst",
    "chars": 1543,
    "preview": ".. _adding-events:\n\nAdding new events\n=================\n\nYou can also add new events to ``conrad`` without writing a cra"
  },
  {
    "path": "docs/index.rst",
    "chars": 3841,
    "preview": ".. conference-radar documentation master file, created by\n   sphinx-quickstart on Tue Oct 29 12:04:29 2019.\n   You can a"
  },
  {
    "path": "docs/make.bat",
    "chars": 795,
    "preview": "@ECHO OFF\r\n\r\npushd %~dp0\r\n\r\nREM Command file for Sphinx documentation\r\n\r\nif \"%SPHINXBUILD%\" == \"\" (\r\n\tset SPHINXBUILD=sp"
  },
  {
    "path": "setup.py",
    "chars": 2129,
    "preview": "# -*- coding: utf-8 -*-\n\nimport os\n\nfrom setuptools import find_packages\n\nhere = os.path.abspath(os.path.dirname(__file_"
  },
  {
    "path": "tests/test_conrad.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "tests/test_geocoding.py",
    "chars": 713,
    "preview": "# -*- coding: utf-8 -*-\n\nfrom conrad.utils import get_address\n\n\nNYC_ADDRESS = {\n    \"amenity\": \"New York City Hall\",\n   "
  }
]

About this extraction

This page contains the full source code of the vinayak-mehta/conrad GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 55 files (432.3 KB), approximately 125.6k tokens, and a symbol index with 69 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!