From 6cccdb8f03376692961c70221936f491b8bfadf6 Mon Sep 17 00:00:00 2001 From: Shauna Date: Thu, 7 Sep 2023 16:02:53 -0400 Subject: [PATCH] Update docs to point to website (#851) Co-authored-by: sharinetmc <128429303+sharinetmc@users.noreply.github.com> --- CONTRIBUTING.md | 170 +--------------- docs/build_a_connector.rst | 399 +------------------------------------ docs/contributing.rst | 4 +- 3 files changed, 12 insertions(+), 561 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 78c471e33..e34f0872c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,167 +1,15 @@ We're thrilled that you're thinking about contributing to Parsons! Welcome to our contributor community. -Here are some ways you can contribute: +You can find a detailed version of this guide [on our website](https://www.parsonsproject.org/pub/contributing-guide/). -* [submit an issue](#submitting-issues) -* [contribute code](#contributing-code-to-parsons) -* [contribute documentation](#documentation) -* [add sample code to our library of examples](#contributing-sample-code) +The best way to get involved is by joining our Slack. To join, email engineering@movementcooperative.org. In addition to all the great discussions that happen on our Slack, we also have virtual events including trainings, pairing sessions, social hangouts, discussions, and more. Every other Thursday afternoon we host 🎉 Parsons Parties 🎉 on Zoom where we work on contributions together. -Every other Thursday afternoon we host 🎉 Parsons Parties 🎉 on Zoom where we work on contributions together. Reach out if you'd like to join - it's a great way to get involved. +You can contribute by: -## Submitting Issues +* [submitting issues](https://www.parsonsproject.org/pub/contributing-guide#submitting-issues) +* [contributing code](https://www.parsonsproject.org/pub/contributing-guide/) +* [updating our documentation](https://www.parsonsproject.org/pub/updating-documentation/) +* [teaching and mentoring](https://www.parsonsproject.org/pub/contributing-guide#teaching-and-mentoring) +* [helping "triage" issues and review pull requests](https://www.parsonsproject.org/pub/contributing-guide#maintainer-tasks) -We encourage folks to review existing issues before starting a new issue. - -* If the issue you want exists, feel free to use the *thumbs up* emoji to up vote the issue. -* If you have additional documentation or context that would be helpful, please add using comments. -* If you have code snippets, but don’t have time to do the full write, please add to the issue! - -We use labels to help us classify issues. They include: -* **bug** - something in Parsons isn’t working the way it should -* **enhancement** - new feature or request (e.g. a new API connector) -* **good first issue** - an issue that would be good for someone who is new to Parsons - -## Contributing Code to Parsons - -Generally, code contributions to Parsons will be either enhancements or bug requests (or contributions of [sample code](#sample-code), discussed below). All changes to the repository are made [via pull requests](#submitting-a-pull-request). - -If you would like to contribute code to Parsons, please review the issues in the repository and find one you would like to work on. If you are new to Parsons or to open source projects, look for issues with the [**good first issue**](https://github.com/move-coop/parsons/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) label. Once you have found your issue, please add a comment to the issue that lets others know that you are interested in working on it. If you're having trouble finding something to work on, please ask us for help on Slack. - -The bulk of Parsons is made up of Connector classes, which are Python classes that help move data in and out of third party services. When you feel ready, you may want to contribute by [adding a new Connector class](https://move-coop.github.io/parsons/html/build_a_connector.html). - -### Making Changes to Parsons - -To make code changes to Parsons, you'll need to set up your development environment, make your changes, and then submit a pull request. - -To set up your development environment: - -* Fork the Parsons project using [the “Fork” button in GitHub](https://guides.github.com/activities/forking/) -* Clone your fork to your local computer -* Set up a [virtual environment](#virtual-environments) -* Install the [dependencies](#installing-dependencies) -* Check that everything's working by [running the unit tests](#unit-tests) and the [linter](#linting) - -Now it's time to make your changes. We suggest taking a quick look at our [coding conventions](#coding-conventions) - it'll make the review process easier down the line. In addition to any code changes, make sure to update the documentation and the unit tests if necessary. Not sure if your changes require test or documentation updates? Just ask in Slack or through a comment on the relevant issue. When you're done, make sure to run the [unit tests](#unit-tests) and the [linter](#linting) again. - -Finally, you'll want to [submit a pull request](#submitting-a-pull-request). And that's it! - -#### Virtual Environments - -If required dependencies conflict with packages or modules you need for other projects, you can create and use a [virtual environment](https://docs.python.org/3/library/venv.html). - -``` -python3 -m venv .venv # Creates a virtual environment in the .venv folder -source .venv/bin/activate # Activate in Unix or MacOS -.venv/Scripts/activate.bat # Activate in Windows -``` - -#### Installing Dependencies - -Before running or testing your code changes, be sure to install all of the required Python libraries that Parsons depends on. - -From the root of the parsons repository, use the run the following command: - -```bash -> pip install -r requirements.txt -``` - -#### Unit Tests - -When contributing code, we ask you to add to tests that can be used to verify that the code is working as expected. All of our unit tests are located in the `test/` folder at the root of the repository. - -We use the pytest tool to run our suite of automated unit tests. The pytest command line tool is installed as part of the Parsons dependencies. - -To run all the entire suite of unit tests, execute the following command: - -```bash -> pytest -rf test/ -``` - -Once the pytest tool has finished running all of the tests, it will output details around any errors or test failures it encountered. If no failures are identified, then you are good to go! - -**Note:*** Some tests are written to call out to external API’s, and will be skipped as part of standard unit testing. This is expected. - -See the [pytest documentation](https://docs.pytest.org/en/latest/contents.html) for more info and many more options. - -#### Linting - -We use the [black](https://github.com/psf/black) and [flake8](http://flake8.pycqa.org/en/latest/) tools to [lint](https://en.wikipedia.org/wiki/Lint_(software)) the code in the repository to make sure it matches our preferred style. Both tools are installed as part of the Parsons dependencies. - -Run the following commands from the root of the Parsons repository to lint your code changes: - -```bash -> flake8 --max-line-length=100 --extend-ignore=E203,W503 parsons -> black parsons -``` - -Pre-commit hooks are available to enforce black and isort formatting on -commit. You can also set up your IDE to reformat using black and/or isort on -save. - -To set up the pre-commit hooks, install pre-commit with `pip install -pre-commit`, and then run `pre-commit install`. - -#### Coding Conventions - -The following is a list of best practices to consider when writing code for the Parsons project: - -* Each tool connector should be its own unique class (e.g. ActionKit, VAN) in its own Python package. Use existing connectors as examples when deciding how to layout your code. - -* Methods should be named using a verb_noun structure, such as `get_activist()` or `update_event()`. - -* Methods should reflect the vocabulary utilized by the original tool where possible to mantain transparency. For example, Google Cloud Storage refers to file like objects as blobs. The methods are called `get_blob()` rather than `get_file()`. - -* Methods that can work with arbitrarily large data (e.g. database or API queries) should use of Parson Tables to hold the data instead of standard Python collections (e.g. lists, dicts). - -* You should avoid abbreviations for method names and variable names where possible. - -* Inline comments explaining complex codes and methods are appreciated. - -* Capitalize the word Parsons for consistency where possible, especially in documentation. - -If you are building a new connector or extending an existing connector, there are more best practices in the [How to Build a Connector](https://move-coop.github.io/parsons/html/build_a_connector.html) documentation. - -## Documentation - -Parsons documentation is built using the Python Sphinx tool. Sphinx uses the `docs/*.rst` files in the repository to create the documentation. - -We have a [documentation label](https://github.com/move-coop/parsons/issues?q=is%3Aissue+is%3Aopen+label%3Adocumentation) that may help you find good docs issues to work on. If you are adding a new connector, you will need to add a reference to the connector to one of the .rst files. Please use the existing documentation as an example. - -When editing documentation, make sure you are editing the source files (with .md or .rst extension) and not the build files (.html extension). - -The workflow for documentation changes is a bit simpler than for code changes: - -* Fork the Parsons project using [the “Fork” button in GitHub](https://guides.github.com/activities/forking/) -* Clone your fork to your local computer -* Change into the `docs` folder and install the requirements with `pip install -r requirements.txt` (you may want to set up a [virtual environment](#virtual-environments) first) -* Make your changes and re-build the docs by running `make html`. (Note: this builds only a single version of the docs, from the current files. To create docs with multiple versions like our publicly hosted docs, run `make deploy_docs`.) -* Open these files in your web browser to check that they look as you expect. -* [Submit a pull request](#submitting-a-pull-request) - -When you make documentation changes, you only need to track the source files with git. The docs built by the html folder should not be included. - -You should not need to worry about the unit tests or the linter if you are making documentation changes only. - -## Contributing Sample Code - -One important way to contribute to the Parsons project is to submit sample code that provides recipes and patterns for how to use the Parsons library. - -We have a folder called `useful_resources/` in the root of the repository. If you have scripts that incorporate Parsons, we encourage you to add them there! - -The workflow for adding sample code is: - -* Fork the Parsons project using [the “Fork” button in GitHub](https://guides.github.com/activities/forking/) -* Clone your fork to your local computer -* Add your sample code into the `useful_resources/` folder -* [Submit a pull request](#submitting-a-pull-request) - -You should not need to worry about the unit tests or the linter if you are only adding sample code. - -## Submitting a Pull Request - -To submit a pull request, follow [these instructions to create a Pull Request from your fork](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request-from-a-fork) back to the original Parsons repository. - -The Parsons team will review your pull request and provide feedback. Please feel free to ping us if no one's responded to your Pull Request after a few days. We may not be able to review it right away, but we should be able to tell you when we'll get to it. - -Once your pull request has been approved, the Parsons team will merge your changes into the Parsons repository +If you're not sure how to get started, please ask for help! We're happy to chat and help you find the best way to get involved. \ No newline at end of file diff --git a/docs/build_a_connector.rst b/docs/build_a_connector.rst index 9aabc9260..f70436833 100644 --- a/docs/build_a_connector.rst +++ b/docs/build_a_connector.rst @@ -2,401 +2,4 @@ How to Build a Connector ======================== -Connector classes are at the heart of the Parsons project. When we want to add a new service for users to connect to with Parsons, we build a new Connector class for that service. - -The documentation contains `a complete list `_ of existing connectors. Requests for new connectors are made and discussed in `our issue tracker `_. Before starting to build a new connector, check to see if there’s any discussion about it in the tracker. Ideally, you’ll have a good sense of what you and/or other users want the connector to do before you start trying to build it. Remember, you can always reach out to the community and ask for advice! - -When you’re ready to get started, make sure you have Parsons installed and that the tests run successfully. - ---------------- -Getting Started ---------------- - -The first thing you’ll need to do is create a new folder for your connector. This folder should have the same name as the module (file) within the folder, and the same name as the connector class. For example, the airtable connector is in the “airtable” folder, and the hustle connector is in the “hustle” folder. - -Inside the folder, create two files. The first should be named __init__.py and should be empty. The second will have the same name as your folder - this is the file which will have your connector’s code. For example, in the airtable folder this file is called airtable.py and in the hustle folder it’s called hustle.py. - -The directory should look like this: - -.. code-block:: python - - yourconnectorname/ - __init__.py - yourconnectorname.py - -Next, add the reference to your connector to `parsons/__init__.py`. Specifically, open `parsons/__init__.py`, scroll to the end of the other imports, and add the following: - -.. code-block:: python - - from parsons.yourconnectorname.yourconnectorname import yourconnectorname - -Also, in `parsons/__init__.py` add 'yourconnectorname' to the end of the list `__all__`. - -Once this is done, open the yourconnectorname.py file. At the top of the file, add the following code to enable logging for our connector: - -.. code-block:: python - - import logging - - - logger = logging.getLogger(__name__) - -You’ll also want to create the Connector class itself: - -.. code-block:: python - - class YourConnectorName(object): - """ - Instantiate class. - - `Args:` - """ - - def __init__(self, api_key=None): - pass - -The text enclosed in triple quotes “”” “”” is called a DocString, and is used to provide information about the class. Typically, it includes the arguments accepted by the __init__ method of the class. - -The __init__ method defines how the class is instantiated. For instance, if you want to get an instance of the Connector class by writing `connector = YourConnectorName(table_name, api_key)` you’d have to add a table_name argument to go with the api_key argument. Your connector’s init statement will probably require a different set of arguments than we’ve written here, but this makes for a good start. - -In our Parsons connector classes, the __init__ method should handle authentication. That is, when we initialize our Connector, we should give it credentials so that it can connect to the third-party service. Then we won’t have to worry about authenticating in the other methods. How exactly you authenticate to the service will depend on the service, but it typically involves getting an api_key or access_token, and it almost always involves creating an account on the service. - -(Users of your connector class will need to know how to authenticate too! Take notes of where you signed up for an account and how you got the api key, access token, etc so you can include it in the documentation for your connector.) - -We like to give users two different options for getting api keys and other authentication to the connector - passing them as arguments to the __init__ method, and storing them as environmental variables. Use the Parsons utility checkenv to allow for either possibility with code that looks like this: - -.. code-block:: python - - import logging - from parsons.utilities import check_env - - logger = logging.getLogger(__name__) - - - class YourConnectorName(object): - """ - Instantiate class. - - `Args:` - """ - - def __init__(self, api_key=None): - self.api_key = check_env.check('YOURCONNECTORNAME_API_KEY', api_key) - -This code looks in the environmental variables for the api key and, if it doesn’t find it, uses the api_key passed in. - -Most connectors make extensive use of existing client/providers. Most likely, your next step will be to instantiate one of those existing clients using the authentication data, and add it to the class. You can see an example of this in the `Airtable Connector `_. - --------- -Patterns --------- - -Parsons has a number of patterns that should be used when developing a connector to ensure that connectors look alike, which makes them easier to use and modify. Not all patterns apply to all connectors, but when reviewing pull requests, the maintainers will be looking to see if you adhere to the patterns described in this document. - -In the sections below, we will attempt to enumerate the established patterns. We will use the `parsons.mailchimp.mailchimp.Mailchimp` connector as an example of how to implement the patterns. - -^^^^^^^^^^^^^^^^^^^^ -Class initialization -^^^^^^^^^^^^^^^^^^^^ - -**Allow configuration of a connector with environment variables as well as arguments passed to the class initializer.** Make use of `parsons.utilities.check_env.check` function to check that the value was provided either as an argument to the initializer, or in the environment. - -**When calling into a web API, use the `parsons.utilities.APIConnector` class.** The `APIConnector` class has a number of methods for making web requests, and using the `APIConnector` helps enforce consistency across connectors. The `APIConnector` is a wrapper around the Python `requests` library. - - -Mailchimp example: - -.. code-block:: python - - from parsons.utilities import check_env - from parsons.utilities.api_connector import APIConnector - - - class Mailchimp(): - """ - Instantiate Mailchimp Class - - `Args:` - api_key: - The Mailchimp-provided application key. Not required if - ``MAILCHIMP_API_KEY`` env variable set. - `Returns:` - Mailchimp Class - """ - - def __init__(self, api_key=None): - self.api_key = check_env.check('MAILCHIMP_API_KEY', api_key) - self.domain = re.findall("(?<=-).+$", self.api_key)[0] - self.uri = f'https://{self.domain}.api.mailchimp.com/3.0/' - self.client = APIConnector(self.uri, auth=('x', self.api_key)) - -In the `__init__` method above, the Mailchimp class takes one argument: `api_key`. The argument has a default value of `None`, which allows for a user to initialize the connector without any arguments (ie `Mailchimp()`. If no value is passed for `api_key` as an argument to the `__init__` method, then the `check_env.check` function will attempt to retrieve the value from the `MAILCHIMP_API_KEY` environment variable. If the value is neither passed in as argument nor in the environment, the `check_env.check` method will raise a `KeyError` exception. - -In the last line of the code snippet above, the `Mailchimp` class creates an `APIConnector` class, providing the root URL for the API (`self.uri`). The Mailchimp API accepts basic authentication as an authentication mechanism, so the `Mailchimp` connector is able to pass the `api_key` to the `APIConnector` via the `auth` keyword argument. If the API for your connector does not support basic authentication, you may need to implement your own authentication (e.g. via request headers). - -^^^^^^^^^^^^^^^^^^^^^^^^ -Your connector’s methods -^^^^^^^^^^^^^^^^^^^^^^^^ - -**The methods of your connector should generally mirror the endpoints of the API.** Every API is different, but the connector should generally look like the API it is connecting to. Methods of your connector should reference the resources the API is using (e.g. “people”, “members”, “events”). - -The following lists rules for naming common endpoints: - -* GET - single record - *get_* (e.g. get_event, get_person) -* GET - multiple records - *get_s* (e.g. get_members, get_people) -* POST - single record - *create_* (e.g. create_person, create_tag) -* PUT - single record - *update_* (e.g. update_person, update_event) -* DELETE - single record - *delete_* (e.g. delete_member) - -**A method’s arguments should mirror the parameters of the API endpoint it is calling.** Optional parameters should be optional in your method signature (i.e. default to `None`). - -**Use Python docstrings to document every public method of your class.** The docstrings for your public methods are used to automatically generate documentation for your connector. Having this documentation for every method makes it easier for users to pick up your connector. - -**Methods returning multiple values should return a Parsons Table.** If the list of results is empty, return an empty Parsons `Table` (not `None`). Methods returning a single value should just return the value. If the API could not find the value (eg, the ID provided for a resource was not found), return a `None` value from the method. - -Mailchimp example: - -.. code-block:: python - - class Mailchimp(): - - def get_lists(self, fields=None, exclude_fields=None, - count=None, offset=None, before_date_created=None, - since_date_created=None, before_campaign_last_sent=None, - since_campaign_last_sent=None, email=None, sort_field=None, - sort_dir=None): - """ - Get a table of lists under the account based on query parameters. Note - that argument descriptions here are sourced from Mailchimp's official - API documentation. - - `Args:` - fields: list of strings - A comma-separated list of fields to return. Reference - parameters of sub-objects with dot notation. - exclude_fields: list of strings - A comma-separated list of fields to exclude. Reference - parameters of sub-objects with dot notation. - count: int - The number of records to return. Default value is 10. Maximum - value is 1000. - offset: int - The number of records from a collection to skip. Iterating over - large collections with this parameter can be slow. Default - value is 0. - before_date_created: string - Restrict response to lists created before the set date. We - recommend ISO 8601 time format: 2015-10-21T15:41:36+00:00. - since_date_created: string - Restrict results to lists created after the set date. We - recommend ISO 8601 time format: 2015-10-21T15:41:36+00:00. - before_campaign_last_sent: string - Restrict results to lists created before the last campaign send - date. We recommend ISO 8601 time format: - 2015-10-21T15:41:36+00:00. - since_campaign_last_sent: string - Restrict results to lists created after the last campaign send - date. We recommend ISO 8601 time format: - 2015-10-21T15:41:36+00:00. - email: string - Restrict results to lists that include a specific subscriber's - email address. - sort_field: string, can only be 'date_created' or None - Returns files sorted by the specified field. - sort_dir: string, can only be 'ASC', 'DESC', or None - Determines the order direction for sorted results. - - `Returns:` - Table Class - """ - params = {'fields': fields, - 'exclude_fields': exclude_fields, - 'count': count, - 'offset': offset, - 'before_date_created': before_date_created, - 'since_date_created': since_date_created, - 'before_campaign_last_sent': before_campaign_last_sent, - 'since_campaign_last_sent': since_campaign_last_sent, - 'email': email, - 'sort_field': sort_field, - 'sort_dir': sort_dir} - - response = self.get_request('lists', params=params) - tbl = Table(response['lists']) - logger.info(f'Found {tbl.num_rows} lists.') - if tbl.num_rows > 0: - return tbl - else: - return Table() - - -The `get_lists` method corresponds to the `GET /lists `_ endpoint on the Mailchimp API. The method has a number of arguments (all optional), all of which are described in the docstring. The arguments are then mapped to the name of the endpoints’ parameters, and passed to the `APIConnector`’s `get_request` method. - -The method can return more than one record, so the results of the call to the API are wrapped in a Parsons `Table`. If there are no results from the call, an empty table is returned. - --------------- -Sandbox Access --------------- - -When developing a Parsons connector, it's helpful to be able to test your changes against a non-production account. We have set up test accounts with some vendors which you can use for testing by following the steps below. We also maintain :ref:`a list of vendors with free accounts` that you can use as sandboxes. - -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Accessing and Using Credentials -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -**Step 1: Request Access** - -Request access to the test account (usually in the form of an API key) by emailing engineering@movementcooperative.org. Please provide your GitHub username and some context for your request. Why do you need the account credentials? What are you testing? If a community member recommended you request an account from us, you can include their name here. See :ref:`connector-specific-guidance` for additional information we may need to give you access to a specific sandbox. - -An example request might look something like "Hi, I'm Ana (abc123 on github), I want to work on the ActionNetwork connector but I don't know how to test it. At the contributor meeting Betty linked me here and said I should ask you." - -**Step 2: Save and Use the Credentials** - -When using your credentials, please store them as environmental variables rather than including them directly in your code. If you use them in your code and accidentally include them as part of a pull request, we will need to generate new credentials. Let's try to avoid that hassle! - -You can set environmental variables with the following commands:: - - set VARIABLE_NAME=VARIABLE_VALUE # Windows - export VARIABLE_NAME=VARIABLE_VALUE # Linux/Mac - -Some environmental variables may need to be explicitly loaded into scripts for use, but most will not. This is because each Parsons connector automatically looks in the environment for specific variables and uses them when initializing the connector. For example, the Zoom connector looks for ZOOM_API_KEY and ZOOM_API_SECRET. Check the documentation for the precise names of the environmental variables it looks for. - -In rare cases you may need to load the environmental variables yourself within the script. You can do so with the following code:: - - import os - ENV_VARIABLE = os.getenv('ENV_VARIABLE') - -^^^^^^^^^^^^^^^^^^^^^^ -General Best Practices -^^^^^^^^^^^^^^^^^^^^^^ - -Since the sandbox accounts are shared with multiple people, we ask contributors to observe some guidelines: - -* Use clear naming conventions when creating test data. Either prefix or suffix data with your initials or use another identifier. -* Only add mock data to the test account, never real data (especially if there are fields for contact information). -* Try to limit the amount of data you push in/pull out of the account to only the amount that you need. -* Leave test data that looks like it was created by someone else in the same state that you found it. -* Delete test data when you finish testing. -* Be mindful when sending requests to third party platforms. We don’t want to burden them or to have our account suspended and rate-limited. If you accidentally over-requested from the third-party platform and have been suspended or rate-limited in a way that does not expire after a day or less, please reach out to us so we can try to get access again. - -.. _connector-specific-guidance: - -^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Connector-Specific Guidance -^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -################## -API Keys Available -################## - -The following connectors have sandbox API keys available. Some connectors have specific best practices or additional information to send along when you request the key from us. - -**ActionKit**: No additional information needed, but please be mindful that this sandbox is shared across many organizations, not just Parsons-affiliated organizations. Be extra careful not to modify existing data. - -**ActionNetwork**: In order to access the ActionNetwork sandbox account, we’ll need the email address associated with your ActionNetwork account. Please make an ActionNetwork account if you don’t have one already, and include the associated email in your access request to us. - -**ControlShift**: Please limit your testing to pushing and pulling data in and out and do not use the account for sending mass texts. (The sandbox account has an associated phone number, but it is unnecessary for Parsons testing.) - -**Hustle**: No connector-specific guidance. - -**Mobilize**: No connector-specific guidance. - -**Strive**: No connector-specific guidance. - -.. _create-sandbox: - -####################### -Create Your Own Sandbox -####################### - -The following connectors are confirmed to have free accounts which can be used to make sandboxes. - -**Airtable**: You can create `free accounts `_ on the Airtable website. - -**Braintree**: You can create `free sandbox accounts `_ on the Braintree website. - -**Github**: You can create `free accounts `_ on the Github website. - -**Salesforce**: You can create `free developer accounts `_ directly on the Salesforce website, which you can use to `create a sandbox `_. - -**Twilio**: You can create a `free account `_ on the Twilio website which gets you access to their `test credentials `_. - ------------- -Finishing up ------------- - -^^^^^^^^^^^^^^^ -Testing locally -^^^^^^^^^^^^^^^ - -In order to test locally, you will need to install the version of Parsons that you have been working on. To do that, you will need to install in "editable" mode, which allows you to import your local Parsons code instead of the released code. - -To install Parsons in "editable" mode, run the following, where `` is the path to the root of the Parsons repository on your local machine. - -```bash -pip install -e -``` - -^^^^^^^^^^^^^^^^^^^^^^ -Adding automated tests -^^^^^^^^^^^^^^^^^^^^^^ - - * Add a folder *test_yourconnectorname* in parsons/test for your connector - * Add a file *test_yourconnectorname.py* to the *test_yourconnectorname* folder - * Use the code below as a starting point for your tests - * Add one `“Happy Path” `_ test per public method of your connector - * When possible mock out any external integrations, otherwise mark your test using the ``unittest.skipIf`` decorator (for an example, see test/test_s3.py) - - For a more detailed guide on writing unit tests, see :doc:`How to Write Tests for Parsons Connectors ` - -.. code-block:: python - - from parsons.yourconnector.yourconnector import YourConnector - import unittest - import requests_mock - - from parsons.yourconnector.yourconnector import YourConnector - import unittest - import requests_mock - - class TestYourConnector(unittest.TestCase): - - def setUp(self): - - # add any setup code here to run before each test - pass - - def tearDown(self): - - # add any teardown code here to run after each test - pass - - @requests_mock.Mocker() - def test_get_things(self, m): - - # Test that campaigns are returned correctly. - m.get('http://yourconnector.com/v1/things', json=[]) - yc = YourConnector() - tbl = yc.get_things() - - self.assertEqual(tbl.num_rows, 0) - -^^^^^^^^^^^^^^^^^^^^ -Adding documentation -^^^^^^^^^^^^^^^^^^^^ - - * Add *yourconnectorname.rst* to the parsons/docs folder. - * Use the parsons/docs/_template.rst file as a guide for the documentation for your connector. - * Add a reference to your connector’s doc file to the parsons/docs/index.rst - * You just need to add the filename without the .rst extension (ie *yourconnector*) - * Be sure to add *yourconnector* in alphabetical order - -^^^^^^^^^^^ -Final steps -^^^^^^^^^^^ - - * Add any new dependencies to the parsons/requirements.txt file - * Run the entire suite of Parsons unit tests using the `pytest -rf test` command - * Run the linter against Parsons using `flake8 --max-line-length=100 parsons` - * Double-check that you have committed all of your code changes to your branch, and that you have pushed your branch to your fork - * Open a pull request against the move-coop/parsons repository +The "building a new connector guide" has been moved to the Parsons website! You can find it `here `_. diff --git a/docs/contributing.rst b/docs/contributing.rst index a43a1f06d..a299f56f7 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -2,5 +2,5 @@ Contributing to Parsons ======================= -.. include:: ../CONTRIBUTING.md - :parser: myst_parser.sphinx_ \ No newline at end of file + +The contributing guide has been moved to the Parsons website! You can find it `here `_.