{"id":13729513,"url":"https://github.com/xdevplatform/compliant-client","last_synced_at":"2025-04-05T21:33:07.632Z","repository":{"id":47100940,"uuid":"318421326","full_name":"xdevplatform/compliant-client","owner":"xdevplatform","description":"A set of Python scripts for the Tweet and User batch compliance endpoints. Includes an app that manages it all in one go. ","archived":false,"fork":false,"pushed_at":"2021-09-13T15:42:00.000Z","size":145,"stargazers_count":15,"open_issues_count":1,"forks_count":4,"subscribers_count":12,"default_branch":"main","last_synced_at":"2025-03-21T12:21:30.202Z","etag":null,"topics":["python","twitter","twitter-api","twitter-api-v2","twitter-compliance"],"latest_commit_sha":null,"homepage":"https://developer.twitter.com/en/docs/twitter-api/compliance/batch-compliance/introduction","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/xdevplatform.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-12-04T06:10:05.000Z","updated_at":"2025-03-10T18:27:58.000Z","dependencies_parsed_at":"2022-09-18T04:11:04.040Z","dependency_job_id":null,"html_url":"https://github.com/xdevplatform/compliant-client","commit_stats":null,"previous_names":["xdevplatform/compliant-client"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xdevplatform%2Fcompliant-client","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xdevplatform%2Fcompliant-client/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xdevplatform%2Fcompliant-client/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xdevplatform%2Fcompliant-client/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/xdevplatform","download_url":"https://codeload.github.com/xdevplatform/compliant-client/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247406076,"owners_count":20933803,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["python","twitter","twitter-api","twitter-api-v2","twitter-compliance"],"created_at":"2024-08-03T02:01:01.552Z","updated_at":"2025-04-05T21:33:07.342Z","avatar_url":"https://github.com/xdevplatform.png","language":"Python","readme":"# The Compliant (Python) client\n\n**tl;dr** This repository provides both simple scripts and a more elaborate *client* for working with the \"batch \nCompliance\" endpoints. There is a simple script for each of the 5 stages of managing a Job life-cycle, while the \nclient automates a Compliance Job's life-cycle, from creating a Job to downloading the results.\n\n+ [Introduction](#intro)\n  + [Simple scripts](#simple)\n  + [Example client](#client)\n+ [Getting Started](#starting)\n  + [Python packages](#packages)\n  + [Setting up authentication](#auth)  \n+ [Compliance Job attributes and lifecycles](#lifecycles)   \n  + [Example ID file](#id-file)\n+ [Simple scripts](#simple-details)\n+ [Example client](#client-details)\n  + [Example calls](#example-calls)\n  + [Compliance class](#compliance-class)\n  + [Core objects](#core-objects)    \n\n## Introduction \u003ca id=\"intro\" class=\"tall\"\u003e\u0026nbsp;\u003c/a\u003e\n\nThis repository contains Python code for working with the Twitter Batch Compliance endpoints. To learn more about these \nendpoints, check out the [Batch compliance documentation](https://developer.twitter.com/en/docs/twitter-api/compliance/batch-compliance/introduction).\n\n### Simple scripts \u003ca id=\"simple\" class=\"tall\"\u003e\u0026nbsp;\u003c/a\u003e\nThis repository hosts a set of simple Python scripts (in the ./scripts folder) for the Compliance endpoints. These \nscripts support a simple command line interface.  \n\nThese five scripts map to the fundamental methods that are called on the new Compliance endpoint:\n1) Create a Compliance Job: ```create_job.py``` \n2) Once Job is created, upload a set of Twitter Tweet IDs or User IDs to check for Compliance events \n   related to them: ```upload_ids.py```\n3) Request the status of a Job. Determine if a Job was created, whether it is in progress or completed: ```list_job.py```\n4) Request the status of all \"active\" Jobs: ```list_jobs.py``` \n5) Once a Job has the status of 'completed', download the results that indicate which Tweets have been deleted, which \n   User accounts have updates, or some other Compliance event such as geo-scrubbing: ```download_results.py``` \n\n**Some important notes!**\n  * Only one Job at a time can be running, and uploading an ID file triggers the start of procoessing.\n  * The provided upload URL expires in 15 minutes. If the upload URL expires before you get the IDs uploaded, you will \nneed to create a new Job.\n  * The download URL expires one week after the Job is created. Be sure to download all of your results within 7 days\nof creating the Job. \n\n### Example client \u003ca id=\"client\" class=\"tall\"\u003e\u0026nbsp;\u003c/a\u003e\n\nThere is also a more elaborate example 'compliant-client' script that helps manage Compliance Jobs and their lifecycles. \nFor example, the 'apps/compliant-client.py' script enables you to manage Jobs by name and not just ID. More interestingly, \nthis client code lets you provide all that is needed in one \"all\" command. The script creates a new Job, uploads\na specified User ID or Tweet ID file, checks on the Job status every 30 seconds, then downloads the results when the Job completes.  \n\nWhen making an 'all' command, you need to specify the Job type, a Job name, the path to the IDs file for uploading, and the path to \nfile where you want the results written. The Batch Compliance endpoints support two types of Compliance requests, one for Tweet Compliance \nevents, and one for User Compliance events.\n\nHere is an example command-line for creating a Job, uploading a Tweet ID file, monitoring a Job's progress, and writing the downloaded results to a local file:   \n\n```bash\n$python apps/compliant-client.py --all --type tweets --name \"Checking Tweets\" --ids-file \"../inbox/tweet_ids.txt\" --results-file \"../outbox/tweet_results.json\"\n```\nHere's an example client command-line for working with a User ID file:  \n\n```bash\n$python apps/compliant-client.py --all --type users --name \"Checking Users\" --ids-file \"../inbox/user_ids.txt\" --results-file \"../outbox/user_results.json\"\n```\n \n## Getting started \u003ca id=\"starting\" class=\"tall\"\u003e\u0026nbsp;\u003c/a\u003e\n\nThe first step when starting with the batch Compliance endpoint is establishing access and generating the authentication \ntoken needed to make requests. You will need to have an approved developer account and have access to the Twitter \nDeveloper Portal. You will need to have a Twitter App, and have its Bearer Token on-hand to start making requests. Bearer \nTokens can be generated in the Developer Portal (yay!). Authentication tokens are only displayed on the Developer Portal\nonce (when generated), so be ready to save those tokens in a secure place. \n\nThe simple scripts and the example client share common code that imports your Bearer Token from the local os \nenvironment/session (this client was developed on the MacOS. If you are on Windows you may want to update how Tokens are \nmanaged). See the \"Setting up authentication\" section below for more details.\n\nSo far, a package has not been generated for this project. To start working with the client code, the repository can be \ncloned in your environment. Currently, there is not any configuration file needed, and the only 'configuration' needed is \nsetting up of a \"BEARER_TOKEN\" environment variable. \n\n### Python packages \u003ca id=\"packages\" class=\"tall\"\u003e\u0026nbsp;\u003c/a\u003e\nThe scripts and example app import the following Python Packages:\n* requests\n* json\n* os\n* docopt (A package that converts simple header documentation into a set of command-line parameters, options, and switches.)\n\n... and that's it!\n\nOther steps for preparing to use the batch Compliance endpoint include: \n\n   + Preparing Tweet and User ID files. IDs should be in simple text with one ID per line. When uploading \n   the files, a 'Content-Type' header should be set to 'text/plain'. See below for an example. \n   + Build methods to import and update Tweet archives. Once the Compliance results are downloaded, code is needed to update \n     your archives accordingly. This may take the form of making database deletes, deleting stored JSON files, or \n     writing new file data files. \n\n### Setting up authentication \u003ca id=\"auth\" class=\"tall\"\u003e\u0026nbsp;\u003c/a\u003e\n\nTo set your enviornment variables in your terminal run the following lines to load your tokens into these environmental \nvariables. Note that there variables are session-specific, so if you stop and restart a terminal these will need to be \nreloaded unless you auto-load them or persist them somehow.\n\n```bash\nexport 'BEARER_TOKEN'='\u003cyour_bearer_token_key\u003e'\n```\n\nA quick way to test your authentication is to make a request for the current \"list Jobs.\"\n\n```bash\n$python ./scripts/list_jobs.py --type tweets\n```\n\n```bash\n$python ./apps/compliant-client.py --list --type tweets\n```\n\nThe example scripts and example client code includes this common code that loads these tokens in from the local environment:\n\n```python\nimport requests\nimport os\n\ndef bearer_oauth(self, r):\n    # To set your environment variables in your terminal run the following line:\n    # export 'BEARER_TOKEN'='\u003cyour_bearer_token\u003e'\n    bearer_token = os.environ.get(\"BEARER_TOKEN\")\n    r.headers['Authorization'] =  \"Bearer {}\".format(bearer_token)\n\n    return r\n\nURL = 'https://api.twitter.com/2/compliance/jobs'\nheaders = {}\nresponse = requests.get(f\"{URL}/{id}\", auth=bearer_oauth, headers=headers)\n\n```\n\n## Job attributes and lifecycles \u003ca id=\"lifecycles\" class=\"tall\"\u003e\u0026nbsp;\u003c/a\u003e\n \nCompliance Jobs have a lifecycle, from being created, having Twitter IDs assigned, a period of time while the results \nare generated, to having a file to download that contains JSON that describes Compliance events associated with submitted IDs. \n\nWhen a Job is created, URLs for uploading IDs and downloading results from are provided. When Twitter IDs are uploaded, \nthe process of checking each ID for Compliance events starts. This process will take many minutes (depending on the \nnumber of IDs submitted). After the job completes, the results can be downloaded for post-processing. The results have the \nform of JSON that describes the type of Compliance event that took place.  \n\nLet's dig into some of the details... \n\n* Job are created with an optional (and recommended) name. \n  \nThe 'create' process creates a new job with the following \n  attributes:\n \n```json\n{\n  \"created_at\": \"2021-08-25T00:21:54.000Z\",\n  \"download_expires_at\": \"2021-09-01T00:21:54.000Z\",\n  \"download_url\": \"https://storage.googleapis.com/twttr-tweet-compliance/1430324519596564483/delivery/992443111073660928_1430324519596564483?X-Goog-Algorithm=GOOG4-RSA-SHA256\u0026X-Goog-Credential=complianceapi-public-svc-acct%40twttr-compliance-public-prod.iam.gserviceaccount.com%2F20210825%2Fauto%2Fstorage%2Fgoog4_request\u0026X-Goog-Date=20210825T002154Z\u0026X-Goog-Expires=604800\u0026X-Goog-SignedHeaders=host\u0026X-Goog-Signature=4066eea9ff73d297d5f51ac6f1260540bd8656b473f33e2cc0925afe9c58c8bc66c6c8a501a059ee90bc3c78144c1b32ea774660a3672f33e44c0083f2c9da3ff7fcf6efd8499e158733b81fb9ad9e3f91144d988d903404f5e3718f37719627014fe34b1b4fd7af41ca76393e0a6564cdd03b1cb1aa3d385a639940f9e52f6b5f3d9e5d023a55811bbbed6e5b54e077a2d413a392afd5088b3906ce3d40162f4ca4f62b26e363f70a57ea252594b091e6a50480753f9a528f6bd1c7890883b66b55750220e45fff8aa64067cf08c390517b597d4d80d759c124be5352446e57f9b57dcf3c070bee913cd6140897485a6eabd92157faee46f857f1939931c0f9\",\n  \"id\": \"1430324519596564483\",\n  \"name\": \"Checking my stored Tweets\",\n  \"resumable\": false,\n  \"status\": \"created\",\n  \"type\": \"tweets\",\n  \"upload_expires_at\": \"2021-08-25T00:36:54.000Z\",\n  \"upload_url\": \"https://storage.googleapis.com/twttr-tweet-compliance/1430324519596564483/submission/992443111073660928_1430324519596564483?X-Goog-Algorithm=GOOG4-RSA-SHA256\u0026X-Goog-Credential=complianceapi-public-svc-acct%40twttr-compliance-public-prod.iam.gserviceaccount.com%2F20210825%2Fauto%2Fstorage%2Fgoog4_request\u0026X-Goog-Date=20210825T002154Z\u0026X-Goog-Expires=900\u0026X-Goog-SignedHeaders=content-type%3Bhost\u0026X-Goog-Signature=c20ecee2fea6e4ada2cb04f08b3350b039d9a608dd343b9c1ac2a003d2c26e6abac7546a5589bc3146d87b3e9e6023309c96bb9cddf96f8281e2a17fa63fdd8f711a997317c4be6dfead08d728b48381f4d95e515d01b91066aa4eb0c876bcd12195d2521ec2720c8e92d2830ae4ef17340c4fb92c58203f05bef9474d8d91404f48eff41b3b04adb662668eecd14b4ccc848d4d0e7df690a48e5befca081e0ce429a4387ba763a47bec7e88a3a57fdb2b97f7a2a04294aaafe102d9704dce62967e2a85c6c3170c689a8ba8f079afaf63ba850846aadd4ef7a99a7f67e0c05bf65a628809af79251b31051e8a785e262c28b81f2b3aa2839adaf1f5d078e9c2\"\n}\n```\nThese Job details include an URL for uploading your ID. There is also an expiration time for that URL. Once a Job is \ncreated the upload link is available for 15 minutes. If the link expires before you upload the IDs, a new Job will need \nto be created. \n \n* Tweet and User IDs are uploaded to a cloud file system. The IDs are written to a simple text file with one ID per line. \n  Below is an example for a set of Tweet IDs, and the format is identical for User Ids. \n\n#### Tweet ID file \u003ca id=\"id-file\" class=\"tall\"\u003e\u0026nbsp;\u003c/a\u003e\n\n```\n900145569397649408\n900145765250732032\n900148142313754624\n900148877004861440\n900149201455263746\n900149551985819648\n900149689252802560\n900149981465673732\n900150802534342657\n900152816081219584\n```\n\n* Uploaded IDs are checked for Compliance, a process that can take many minutes (and hours?) to complete. \n\n```json\n{\n  \"status\": \"in_progress\"\n}\n\n```\n\nThe Job will remain in the \"in_progress\" status until it finishes and enters a final \"completed\" status\n\n\n```json\n{\n  \"created_at\": \"2021-08-25T00:21:54.000Z\",\n  \"download_expires_at\": \"2021-09-01T00:21:54.000Z\",\n  \"download_url\": \"https://storage.googleapis.com/twttr-tweet-compliance/1430324519596564483/delivery/992443111073660928_1430324519596564483?X-Goog-Algorithm=GOOG4-RSA-SHA256\u0026X-Goog-Credential=complianceapi-public-svc-acct%40twttr-compliance-public-prod.iam.gserviceaccount.com%2F20210825%2Fauto%2Fstorage%2Fgoog4_request\u0026X-Goog-Date=20210825T002154Z\u0026X-Goog-Expires=604800\u0026X-Goog-SignedHeaders=host\u0026X-Goog-Signature=4066eea9ff73d297d5f51ac6f1260540bd8656b473f33e2cc0925afe9c58c8bc66c6c8a501a059ee90bc3c78144c1b32ea774660a3672f33e44c0083f2c9da3ff7fcf6efd8499e158733b81fb9ad9e3f91144d988d903404f5e3718f37719627014fe34b1b4fd7af41ca76393e0a6564cdd03b1cb1aa3d385a639940f9e52f6b5f3d9e5d023a55811bbbed6e5b54e077a2d413a392afd5088b3906ce3d40162f4ca4f62b26e363f70a57ea252594b091e6a50480753f9a528f6bd1c7890883b66b55750220e45fff8aa64067cf08c390517b597d4d80d759c124be5352446e57f9b57dcf3c070bee913cd6140897485a6eabd92157faee46f857f1939931c0f9\",\n  \"id\": \"1430324519596564483\",\n  \"name\": \"Checking my stored Tweets\",\n  \"resumable\": false,\n  \"status\": \"complete\",\n  \"type\": \"tweets\",\n  \"upload_expires_at\": \"2021-08-25T00:36:54.000Z\",\n  \"upload_url\": \"https://storage.googleapis.com/twttr-tweet-compliance/1430324519596564483/submission/992443111073660928_1430324519596564483?X-Goog-Algorithm=GOOG4-RSA-SHA256\u0026X-Goog-Credential=complianceapi-public-svc-acct%40twttr-compliance-public-prod.iam.gserviceaccount.com%2F20210825%2Fauto%2Fstorage%2Fgoog4_request\u0026X-Goog-Date=20210825T002154Z\u0026X-Goog-Expires=900\u0026X-Goog-SignedHeaders=content-type%3Bhost\u0026X-Goog-Signature=c20ecee2fea6e4ada2cb04f08b3350b039d9a608dd343b9c1ac2a003d2c26e6abac7546a5589bc3146d87b3e9e6023309c96bb9cddf96f8281e2a17fa63fdd8f711a997317c4be6dfead08d728b48381f4d95e515d01b91066aa4eb0c876bcd12195d2521ec2720c8e92d2830ae4ef17340c4fb92c58203f05bef9474d8d91404f48eff41b3b04adb662668eecd14b4ccc848d4d0e7df690a48e5befca081e0ce429a4387ba763a47bec7e88a3a57fdb2b97f7a2a04294aaafe102d9704dce62967e2a85c6c3170c689a8ba8f079afaf63ba850846aadd4ef7a99a7f67e0c05bf65a628809af79251b31051e8a785e262c28b81f2b3aa2839adaf1f5d078e9c2\"\n}\n```\n\n* After the job is 'completed', the results can be downloaded from a cloud file service. \n\n```json\n{\n    \"download_expires_at\": \"YYYY-MM-DDTHH:mm:ss.000Z\",\n    \"download_url\": \"https://storage.googleapis.com/twttr-tweet-compliance/12345678888888/delivery/...\"\n}\n```\n\n## Compliance results objects  \n\n\nCurrently, the batch compliance endpoints support the following compliance events:\n+ Tweet and User Deletes (a Twitter user deletes a Tweet or their account)\n+ Tweet Scrub Geos (a Twitter user removes geo data from their Tweets)\n+ Tweet and User Protects (a Twitter user protects their Tweets, ie “goes private”)\n+ Tweet and User Suspensions (a Twitter user is suspended, and their Tweets and account are no longer visible on the platform)\n\n  \n  Here is an example for a Tweet Compliance event:\n  \n  ```json\n  {\n  \"id\": \"906972198136631298\",\n  \"action\": \"delete\",\n  \"created_at\": \"2017-09-10T20:06:37.421Z\",\n  \"redacted_at\": \"2020-07-21T23:37:55.607Z\",\n  \"reason\": \"deleted\"\n  }\n ``` \n\nHere is an example for a User Compliance event:\n\n  ```json\n  {\n  \"id\": \"#######\",\n  \"action\": \"delete\",\n  \"created_at\": \"2013-03-26T02:46:15+00:00\",\n  \"reason\": \"protected\"\n}\n ``` \n\nOther reasons include: \"deleted\" and \"suspended\"\n\n\n## Simple scripts \u003ca id=\"simple-details\" class=\"tall\"\u003e\u0026nbsp;\u003c/a\u003e\n##### ./scripts\n\nThe /scripts folder contains a set of Python scripts for the compliance endpoints. These scripts can be used to create \nand manage Compliance Jobs and their lifecycles:\n\nThese scripts all support command-line arguments for passing in settings when creating a Job, or when listing Jobs. Here\nis an example for the list_job.py script. \n\n```python\nif __name__ == \"__main__\":\n\n    arguments = docopt(__doc__, version='v1.0')\n\n    job_details = list_job(arguments['--id'])\n\n    if len(job_details) == 0:\n        print(f\"Compliance Job not found or error occurred.\")\n    else:\n        print(f\"Job details for ID {job_details['id']}:\")\n        print(json.dumps(job_details, indent=4, sort_keys=True))\n```\nThere are five scripts:\n  1) **create_job.py** Creating a Job: ```python create_job.py --type tweets --name \"My new Compliance Job\"```\n  2) **list_jobs.py** Requesting a list of all existing Jobs: ```python list_jobs.py --type tweets```\n  3) **list_job.py** Checking on a specific Job status and retrieving its details: ```python list_jobs.py --id \u003cJOB_ID\u003e```\n  4) **upload_ids.py**Uploading a text file with Tweet IDs (one per line): ```python upload_ids.py --ids-file \u003cIDS_FILE\u003e --url \u003cUPLOAD_URL\u003e```\n  5) **download_results.py** Downloading results which consist of one JSON object for each Tweet that has had Compliance event (e.g. has been \n  deleted): ```python download_results.py --id \u003cJOB_ID\u003e --url \u003cDOWNLOAD_URL\u003e```\n\n## Example client \u003ca id=\"client-details\" class=\"tall\"\u003e\u0026nbsp;\u003c/a\u003e\n##### ./apps/compliant-client.py\n+ Command-line app for working with the Twitter API v2 compliance endpoint. \n\nThe commannd-line supports the following commands (these are displayed with the -h or --help command):\n\n```\ncompliant-client.py\n\nUsage:\n    compliant-client --all --type \u003ctype\u003e --name \u003cname\u003e --ids-file \u003cids-file\u003e --results-file \u003cresults-file\u003e\n    compliant-client --create --type \u003cjob-type\u003e --name \u003cname\u003e\n    #Client will return both Tweet and User jobs if type is not specified.\n    compliant-client --list [--type \u003ctype\u003e | --name \u003cname\u003e | --id \u003cid\u003e | --status \u003cstatus\u003e]\n    compliant-client --upload (--name \u003cname\u003e | --id \u003cid\u003e) --ids-file \u003cids-file\u003e\n    compliant-client --download (--name \u003cname\u003e | --id \u003cid\u003e) --results-file \u003cresults-file\u003e\n    compliant-client --help\n    compliant-client --version\n\nOptions:\n    -a --all\n    -c --create\n    -l --list\n    -s --status STATUS\n    -u --upload\n    -d --download\n    -t --type TYPE\n    -n --name NAME\n    -i --id ID\n    -f --ids-file IDSFILE\n    -r --results-file RESULTSFILE\n    -h --help\n    -v --version\n```    \n\n### Example calls \u003ca id=\"example-calls\" class=\"tall\"\u003e\u0026nbsp;\u003c/a\u003e\n\nHere are some example commands, and illustrate how to manage a Job from creation to downloading results.\n \nThis will create a new Tweets compliance Job, and apply the name \"MyTweetsJob.\" Assigning a name will enable you to \nmanage Jobs by that name instead of its ID. That can be a nice convenience. \n```bash\n$python compliant-client.py --create --type tweets --name \"Checking my stored Tweets\"\n``` \n\nThis will list the status of all Tweets Jobs.  \n```bash\n$python compliant-client.py --list --type tweets\n``` \n\nYou can also look up a Job status by name. \n```bash\n$python compliant-client.py --list --name \"Checking my stored Tweets\"\n``` \n\nThis command will upload the Tweet IDs for the Job named \"MyTweetsJob\".\n```bash\n$python compliant-client.py --upload --type tweets --name \"Checking my stored Tweets\" --ids-file \"./inbox/tweet_ids.txt\"\n``` \n\nWhen the Job is finished, this will download the results for the Job named \"MyTweetsJob\" to the file specified. \n```bash\n$python compliant-client.py --download --type tweets --name \"Checking my stored Tweets\" --results-file \"./oubox/results.txt\"\n``` \n \n**If you want to make a single 'all' call**, the script will manage the Job from creation to downloading the results: \n```bash\n$python compliant-client.py --all --name \"Checking my stored Tweets\" --ids-file \"../inbox/tweet_ids.txt\" --results-file \"../outbox/results.json\"\n```\n\n### Compliance-client class \u003ca id=\"compliance-class\" class=\"tall\"\u003e\u0026nbsp;\u003c/a\u003e\n\n#### compliant-client/compliance/compliance.py\n\nThe *compliance.py* class lives in a *../compliance folder*. The *../compliance/compliance.py* file defines a \n**compliance_client** class.\n\n```python\nimport compliance.compliance\n\ncompliance_client = compliance.compliance.compliance_client()  # Geez, that some odd looking syntax. \n\njob_details = compliance_client.create_compliance_job(settings['name'])\nresults = compliance_client.upload_ids(settings['ids-file'], job_details['upload_url'])\nresults = compliance_client.download_results(job_details['download_url'], settings['results-file'])\ncurrent_jobs = compliance_client.list_jobs()\njob_details = compliance_client.list_job(settings['id'])\n\n```\n  \n### Core objects \u003ca id=\"core-objects\" class=\"tall\"\u003e\u0026nbsp;\u003c/a\u003e\n\n#### Job details\n\nThis code works with a **job_details** object. When you call the 'create job' method of the Compliance class, it will return\na ```job_details``` object with all the attributes you need to manage the Job's lifecycle. \n\n```python\njob_details = compliance_client.create_compliance_job(type, name)\n```\nThe Batch compliance endpoint returns a JSON object with several attributes:\n\n```json\n{\n    \"download_expires_at\": \"2020-12-30T00:05:30.000Z\",\n    \"download_url\": \"https://storage.googleapis.com/twttr-tweet-compliance/1341535366134689792/delivery/...\",\n    \"id\": \"1341535366134689792\",\n    \"name\": \"80M Tweet test\",\n    \"status\": \"complete\",\n    \"type\": \"tweets\",\n    \"upload_expires_at\": \"2020-12-23T00:20:30.000Z\",\n    \"upload_url\": \"https://storage.googleapis.com/twttr-tweet-compliance/1341535366134689792/submission/...\"\n}\n```\n\nThe Python dictionary that encapsulates Job objects looks like:\n\n```python\n\njob_details = {}\njob_details['name']\njob_details['type']\njob_details['id']\njob_details['upload_url']\njob_details['download_url']\njob_details['status']\njob_details['upload_expires_at']\njob_details['download_expires_at']\n\n\n```\n\n","funding_links":[],"categories":["Libraries"],"sub_categories":["Python"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxdevplatform%2Fcompliant-client","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxdevplatform%2Fcompliant-client","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxdevplatform%2Fcompliant-client/lists"}