Repository: indeedlabs/indeed-python Branch: master Commit: 349dd1cfc172 Files: 6 Total size: 9.6 KB Directory structure: gitextract_lrj_60ia/ ├── .gitignore ├── README.md ├── indeed/ │ └── __init__.py ├── setup.py └── tests/ ├── test_jobs.py └── test_search.py ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ *.pyc ================================================ FILE: README.md ================================================ # indeed-python A client library for using the Indeed Jobsearch API ## Installation Install from PyPi using [pip](http://www.pip-installer.org/en/latest/), a package manager for Python. $ pip install indeed Don't have pip installed? Try installing it, by running this from the command line: $ curl https://raw.github.com/pypa/pip/master/contrib/get-pip.py | python ## API Credentials The Indeed API needs to be called with your Indeed publisher number. You must pass this to the `IndeedClient` constructor. ```python from indeed import IndeedClient client = IndeedClient(publisher = YOUR_PUBLISHER_NUMBER) ``` If you do not have a publisher number, you can receive one by heading to the [Indeed Publisher Portal](https://ads.indeed.com/jobroll/xmlfeed). ## Performing a Job Search ```python from indeed import IndeedClient client = IndeedClient('YOUR_PUBLISHER_NUMBER') params = { 'q' : "python", 'l' : "austin", 'userip' : "1.2.3.4", 'useragent' : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2)" } search_response = client.search(**params) ``` ## Retrieving Job Details ```python from indeed import IndeedClient client = IndeedClient('YOUR_PUBLISHER_NUMBER') job_response = client.jobs(jobkeys = ("5898e9d8f5c0593f", "c2c41f024581eae5")) ``` ## API Paramaters ### Job Search **q** - Query. By default terms are ANDed. To see what is possible, use our [advanced search](http://www.indeed.com/advanced_search) page to perform a search and then check the url for the q value. **l** - Location. Use a postal code or a "city, state/province/region" combination. **userip** - The IP number of the end-user to whom the job results will be displayed. *This field is required*. **useragent** - The User-Agent (browser) of the end-user to whom the job results will be displayed. This can be obtained from the "User-Agent" HTTP request header from the end-user. *This field is required*. **format** - Format. Which output format of the API you wish to use. The options are "xml" and "json.". Default is "json". The `IndeedClient` requests and parses a json repsonse by default. If you with to use the xml format, requests will be performed with the **raw** parameter set to `True`, see **raw**. **raw** - A boolean. Receive the raw json/xml response from the Indeed API. Use in addition with *format* to specify which response format you would like. Default is `False` **sort** - Sort by relevance or date. Default is relevance. **radius** - Distance from search location ("as the crow flies"). Default is 25. **start** - Start results at this result number, beginning with 0. Default is 0. **limit** - Maximum number of results returned per query. Default is 10, Maximum is 25 **fromage** - Number of days back to search. **highlight** - Setting this value to 1 will bold terms in the snippet that are also present in q. Default is 0. **filter** - Filter duplicate results. 0 turns off duplicate job filtering. Default is 1. **latlong** - If latlong=1, returns latitude and longitude information for each job result. Default is 0. **co** - Search within country specified. Default is *us*. ### Job Details **jobkeys** - Job keys. A list of job keys specifying the jobs to look up. *This parameter is required*. **format** - Format. Which output format of the API you wish to use. The options are "xml" and "json.". Default is "json". The `IndeedClient` requests and parses a json repsonse by default. If you with to use the xml format, requests will be performed with the **raw** parameter set to `True`, see **raw**. **raw** - A boolean. Receive the raw json/xml response from the Indeed API. Use in addition with *format* to specify which response format you would like. Default is `False` ================================================ FILE: indeed/__init__.py ================================================ import requests DEFAULT_FORMAT = "json" API_ROOT = "http://api.indeed.com/ads" API_SEARCH = {'end_point': "%s/apisearch" % API_ROOT, 'required_fields': ['userip', 'useragent', ['q', 'l']]} API_JOBS = {'end_point': "%s/apigetjobs" % API_ROOT, 'required_fields': ['jobkeys']} class IndeedClientException(Exception): pass class IndeedClient: def __init__(self, publisher, version = "2"): self.publisher = publisher self.version = version def search(self, **args): return self.__process_request(API_SEARCH.get('end_point'), self.__valid_args(API_SEARCH.get('required_fields'), args)) def jobs(self, **args): valid_args = self.__valid_args(API_JOBS.get('required_fields'), args) valid_args['jobkeys'] = ",".join(valid_args['jobkeys']) return self.__process_request(API_JOBS.get('end_point'), valid_args) def __process_request(self, endpoint, args): format = args.get('format', DEFAULT_FORMAT) raw = True if format == 'xml' else args.get('raw', False) args.update({'v': self.version, 'publisher': self.publisher, 'format': format}) r = requests.get(endpoint, params = args) return r.json() if not raw else r.content def __valid_args(self, required_fields, args): for field in required_fields: if type(field) is list: validation_list = [args.get(f) != None for f in field] if not (True in validation_list): raise IndeedClientException("You must provide one of the following %s" % ",".join(field)) elif not args.get(field): raise IndeedClientException("The field %s is required" % field) return args ================================================ FILE: setup.py ================================================ from distutils.core import setup setup( name = 'indeed', version = '0.0.4', description = 'Indeed Job Search Python Api Client', author = 'Indeed Labs', author_email = 'labs-team@indeed.com', packages = ['indeed'], install_requires=['requests==2.0.0'], url = "https://github.com/indeedlabs/indeed-python", ) ================================================ FILE: tests/test_jobs.py ================================================ from nose.tools import * import json from xml.dom.minidom import parseString from indeed import IndeedClient, IndeedClientException class TestJobs: def setup(self): self.client = IndeedClient("YOUR_PUBLISHER_NUMBER") self.params = { 'jobkeys' : ("5898e9d8f5c0593f", "c2c41f024581eae5"), } def teardown(self): self.client = None self.params = None @with_setup(setup, teardown) def test_jobs(self): jobs_response = self.client.jobs(**self.params) assert type(jobs_response) is dict @with_setup(setup, teardown) @raises(IndeedClientException) def test_missing_jobkeys(self): del self.params['jobkeys'] jobs_response = self.client.jobs(**self.params) @with_setup(setup, teardown) def test_raw_json(self): self.params['raw'] = True jobs_response = self.client.jobs(**self.params) assert isinstance(jobs_response, basestring) assert type(json.loads(jobs_response)) is dict @with_setup(setup, teardown) def test_raw_xml_with_paramter(self): self.params['format'] = "xml" self.params['raw'] = True jobs_response = self.client.jobs(**self.params) assert isinstance(jobs_response, basestring) assert parseString(jobs_response) @with_setup(setup, teardown) def test_raw_xml_without_paramter(self): self.params['format'] = "xml" jobs_response = self.client.jobs(**self.params) assert isinstance(jobs_response, basestring) assert parseString(jobs_response) ================================================ FILE: tests/test_search.py ================================================ from nose.tools import * import json from xml.dom.minidom import parseString from indeed import IndeedClient, IndeedClientException class TestSearch: def setup(self): self.client = IndeedClient("YOUR_PUBLISHER_NUMBER") self.params = { 'q' : "python", 'l' : "austin", 'userip' : "1.2.3.4", 'useragent' : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2)", } def teardown(self): self.client = None self.params = None @with_setup(setup, teardown) def test_search(self): search_response = self.client.search(**self.params) assert type(search_response) is dict @with_setup(setup, teardown) def test_missing_one_required(self): del self.params['l'] search_response = self.client.search(**self.params) assert type(search_response) is dict @with_setup(setup, teardown) @raises(IndeedClientException) def test_missing_both_required(self): del self.params['q'] del self.params['l'] search_response = self.client.search(**self.params) @with_setup(setup, teardown) @raises(IndeedClientException) def test_missing_userip(self): del self.params['userip'] search_response = self.client.search(**self.params) @with_setup(setup, teardown) @raises(IndeedClientException) def test_missing_useragent(self): del self.params['useragent'] search_response = self.client.search(**self.params) @with_setup(setup, teardown) def test_raw_json(self): self.params['raw'] = True search_response = self.client.search(**self.params) assert isinstance(search_response, basestring) assert type(json.loads(search_response)) is dict @with_setup(setup, teardown) def test_raw_xml_with_paramter(self): self.params['format'] = "xml" self.params['raw'] = True search_response = self.client.search(**self.params) assert isinstance(search_response, basestring) assert parseString(search_response) @with_setup(setup, teardown) def test_raw_xml_without_paramter(self): self.params['format'] = "xml" search_response = self.client.search(**self.params) assert isinstance(search_response, basestring) assert parseString(search_response)