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
[](https://github.com/vinayak-mehta/conrad/actions) [](https://conference-radar.readthedocs.io/en/latest/) [](https://pypi.org/project/conference-radar/) [](https://pypi.org/project/conference-radar/) [](https://github.com/ambv/black)
`conrad` helps you track conferences and meetups on your terminal.
---
Here's how it works:
<pre>
$ conrad show
</pre>

## 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** , **>10 and < 30 days**  and **< 10 days** .
<pre>
$ conrad remind -i 6bb714
$ conrad remind
</pre>

**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>

Look at conferences using a tag:
<pre>
$ conrad show --tag python
</pre>

Look at conferences using a name:
<pre>
$ conrad show --name pycon
</pre>

Look at conferences in a city, state or country:
<pre>
$ conrad show --location usa
</pre>

Look at conferences based on when they're happening:
<pre>
$ conrad show --date ">= 2019-10-01" --date "<= 2020-01-01"
</pre>

### Refresh event database
You can get the latest events using:
<pre>
$ conrad refresh
</pre>

## 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",
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
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.