Package: datapackage
datapackage-pyA library for working withData Packages.[Important Notice]We have releasedFrictionless Framework. This framework provides improveddatapackagefunctionality extended to be a complete data solution. The change in not breaking for the existing software so no actions are required. Please read theMigration Guidefromdatapackageto Frictionless Framework.we continue to bug-fixdatapackage@1.xin thisrepositoryas well as it's available onPyPias it was beforeplease note thatfrictionless@3.xversion's API, we're working on at the moment, is not stablewe will releasefrictionless@4.xby the end of 2020 to be the first SemVer/stable versionFeaturesPackageclass for working with data packagesResourceclass for working with data resourcesProfileclass for working with profilesvalidatefunction for validating data package descriptorsinferfunction for inferring data package descriptorsContentsGetting StartedInstallationDocumentationIntroductionWorking with PackageWorking with ResourceWorking with GroupWorking with ProfileWorking with Foreign KeysWorking with validate/inferFrequently Asked QuestionsAPI ReferencecliPackageResourceGroupProfilevalidateinferDataPackageExceptionTableSchemaExceptionLoadErrorCastErrorIntegrityErrorRelationErrorStorageErrorContributingChangelogGetting StartedInstallationThe package use semantic versioning. It means that major versions  could include breaking changes. It's highly recommended to specifydatapackageversion range in yoursetup/requirementsfile e.g.datapackage>=1.0,<2.0.$pipinstalldatapackageOSX 10.14+If you receive an error about thecchardetpackage when installing datapackage on Mac OSX 10.14 (Mojave) or higher, follow these steps:Make sure you have the latest x-code by running the following in terminal:xcode-select --installThen go tohttps://developer.apple.com/download/more/and download thecommand line tools. Note, this requires an Apple ID.Then, in terminal, runopen /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkgYou can read more about these steps in thispost.DocumentationIntroductionLet's start with a simple example:fromdatapackageimportPackagepackage=Package('datapackage.json')package.get_resource('resource').read()Working with PackageA class for working with data packages. It provides various capabilities like loading local or remote data package, inferring a data package descriptor, saving a data package descriptor and many more.Consider we have some local csv files in adatadirectory. Let's create a data package based on this data using aPackageclass:data/cities.csvcity,location
london,"51.50,-0.11"
paris,"48.85,2.30"
rome,"41.89,12.51"data/population.csvcity,year,population
london,2017,8780000
paris,2017,2240000
rome,2017,2860000First we create a blank data package:package=Package()Now we're ready to infer a data package descriptor based on data files we have. Because we have two csv files we use glob pattern**/*.csv:package.infer('**/*.csv')package.descriptor#{ profile: 'tabular-data-package',#  resources:#   [ { path: 'data/cities.csv',#       profile: 'tabular-data-resource',#       encoding: 'utf-8',#       name: 'cities',#       format: 'csv',#       mediatype: 'text/csv',#       schema: [Object] },#     { path: 'data/population.csv',#       profile: 'tabular-data-resource',#       encoding: 'utf-8',#       name: 'population',#       format: 'csv',#       mediatype: 'text/csv',#       schema: [Object] } ] }Aninfermethod has found all our files and inspected it to extract useful metadata like profile, encoding, format, Table Schema etc. Let's tweak it a little bit:package.descriptor['resources'][1]['schema']['fields'][1]['type']='year'package.commit()package.valid# trueBecause our resources are tabular we could read it as a tabular data:package.get_resource('population').read(keyed=True)#[ { city: 'london', year: 2017, population: 8780000 },#  { city: 'paris', year: 2017, population: 2240000 },#  { city: 'rome', year: 2017, population: 2860000 } ]Let's save our descriptor on the disk as a zip-file:package.save('datapackage.zip')To continue the work with the data package we just load it again but this time using localdatapackage.zip:package=Package('datapackage.zip')# Continue the workIt was onle basic introduction to thePackageclass. To learn more let's take a look onPackageclass API reference.Working with ResourceA class for working with data resources. You can read or iterate tabular resources using theiter/readmethods and all resource as bytes usingrow_iter/row_readmethods.Consider we have some local csv file. It could be inline data or remote link - all supported byResourceclass (except local files for in-brower usage of course). But say it'sdata.csvfor now:city,location
london,"51.50,-0.11"
paris,"48.85,2.30"
rome,N/ALet's create and read a resource. Because resource is tabular we could useresource.readmethod with akeyedoption to get an array of keyed rows:resource=Resource({path:'data.csv'})resource.tabular# trueresource.read(keyed=True)# [#   {city: 'london', location: '51.50,-0.11'},#   {city: 'paris', location: '48.85,2.30'},#   {city: 'rome', location: 'N/A'},# ]resource.headers# ['city', 'location']# (reading has to be started first)As we could see our locations are just a strings. But it should be geopoints. Also Rome's location is not available but it's also just aN/Astring instead of PythonNone. First we have to infer resource metadata:resource.infer()resource.descriptor#{ path: 'data.csv',#  profile: 'tabular-data-resource',#  encoding: 'utf-8',#  name: 'data',#  format: 'csv',#  mediatype: 'text/csv',# schema: { fields: [ [Object], [Object] ], missingValues: [ '' ] } }resource.read(keyed=True)# Fails with a data validation errorLet's fix not available location. There is amissingValuesproperty in Table Schema specification. As a first try we setmissingValuestoN/Ainresource.descriptor.schema. Resource descriptor could be changed in-place but all changes should be commited byresource.commit():resource.descriptor['schema']['missingValues']='N/A'resource.commit()resource.valid# Falseresource.errors# [<ValidationError: "'N/A' is not of type 'array'">]As a good citiziens we've decided to check out recource descriptor validity. And it's not valid! We should use an array formissingValuesproperty. Also don't forget to have an empty string as a missing value:resource.descriptor['schema']['missingValues']=['','N/A']resource.commit()resource.valid# trueAll good. It looks like we're ready to read our data again:resource.read(keyed=True)# [#   {city: 'london', location: [51.50,-0.11]},#   {city: 'paris', location: [48.85,2.30]},#   {city: 'rome', location: null},# ]Now we see that:locations are arrays with numeric lattide and longitudeRome's location is a native JavaScriptnullAnd because there are no errors on data reading we could be sure that our data is valid againt our schema. Let's save our resource descriptor:resource.save('dataresource.json')Let's check newly-crateddataresource.json. It contains path to our data file, inferred metadata and ourmissingValuestweak:{"path":"data.csv","profile":"tabular-data-resource","encoding":"utf-8","name":"data","format":"csv","mediatype":"text/csv","schema":{"fields":[{"name":"city","type":"string","format":"default"},{"name":"location","type":"geopoint","format":"default"}],"missingValues":["","N/A"]}}If we decide to improve it even more we could update thedataresource.jsonfile and then open it again using local file name:resource=Resource('dataresource.json')# Continue the workIt was onle basic introduction to theResourceclass. To learn more let's take a look onResourceclass API reference.Working with GroupA class representing a group of tabular resources. Groups can be used to read multiple resource as one or to export them, for example, to a database as one table. To define a group add thegroup: <name>field to corresponding resources. The group's metadata will be created from the "leading" resource's metadata (the first resource with the group name).Consider we have a data package with two tables partitioned by a year and a shared schema stored separately:cars-2017.csvname,value
bmw,2017
tesla,2017
nissan,2017cars-2018.csvname,value
bmw,2018
tesla,2018
nissan,2018cars.schema.json{"fields":[{"name":"name","type":"string"},{"name":"value","type":"integer"}]}datapackage.json{"name":"datapackage","resources":[{"group":"cars","name":"cars-2017","path":"cars-2017.csv","profile":"tabular-data-resource","schema":"cars.schema.json"},{"group":"cars","name":"cars-2018","path":"cars-2018.csv","profile":"tabular-data-resource","schema":"cars.schema.json"}]}Let's read the resources separately:package=Package('datapackage.json')package.get_resource('cars-2017').read(keyed=True)==[{'name':'bmw','value':2017},{'name':'tesla','value':2017},{'name':'nissan','value':2017},]package.get_resource('cars-2018').read(keyed=True)==[{'name':'bmw','value':2018},{'name':'tesla','value':2018},{'name':'nissan','value':2018},]On the other hand, these resources defined with agroup: carsfield. It means we can treat them as a group:package=Package('datapackage.json')package.get_group('cars').read(keyed=True)==[{'name':'bmw','value':2017},{'name':'tesla','value':2017},{'name':'nissan','value':2017},{'name':'bmw','value':2018},{'name':'tesla','value':2018},{'name':'nissan','value':2018},]We can use this approach when we need to save the data package to a storage, for example, to a SQL database. There is themerge_groupsflag to enable groupping behaviour:package=Package('datapackage.json')package.save(storage='sql',engine=engine)# SQL tables:# - cars-2017# - cars-2018package.save(storage='sql',engine=engine,merge_groups=True)# SQL tables:# - carsWorking with ProfileA component to represent JSON Schema profile fromProfiles Registry:profile=Profile('data-package')profile.name# data-packageprofile.jsonschema# JSON Schema contentstry:valid=profile.validate(descriptor)exceptexceptions.ValidationErrorasexception:forerrorinexception.errors:# handle individual errorWorking with Foreign KeysThe library supports foreign keys described in theTable Schemaspecification. It means if your data package descriptor useresources[].schema.foreignKeysproperty for some resources a data integrity will be checked on reading operations.Consider we have a data package:DESCRIPTOR={'resources':[{'name':'teams','data':[['id','name','city'],['1','Arsenal','London'],['2','Real','Madrid'],['3','Bayern','Munich'],],'schema':{'fields':[{'name':'id','type':'integer'},{'name':'name','type':'string'},{'name':'city','type':'string'},],'foreignKeys':[{'fields':'city','reference':{'resource':'cities','fields':'name'},},],},},{'name':'cities','data':[['name','country'],['London','England'],['Madrid','Spain'],],},],}Let's check relations for ateamsresource:fromdatapackageimportPackagepackage=Package(DESCRIPTOR)teams=package.get_resource('teams')teams.check_relations()# tableschema.exceptions.RelationError: Foreign key "['city']" violation in row "4"As we could see there is a foreign key violation. That's because our lookup tablecitiesdoesn't have a city ofMunichbut we have a team from there. We need to fix it incitiesresource:package.descriptor['resources'][1]['data'].append(['Munich','Germany'])package.commit()teams=package.get_resource('teams')teams.check_relations()# TrueFixed! But not only a check operation is available. We could userelationsargument forresource.iter/readmethods to dereference a resource relations:teams.read(keyed=True,relations=True)#[{'id': 1, 'name': 'Arsenal', 'city': {'name': 'London', 'country': 'England}},# {'id': 2, 'name': 'Real', 'city': {'name': 'Madrid', 'country': 'Spain}},# {'id': 3, 'name': 'Bayern', 'city': {'name': 'Munich', 'country': 'Germany}}]Instead of plain city name we've got a dictionary containing a city data. Theseresource.iter/readmethods will fail with the same asresource.check_relationserror if there is an integrity issue. But only ifrelations=Trueflag is passed.Working with validate/inferA standalone function to validate a data package descriptor:fromdatapackageimportvalidate,exceptionstry:valid=validate(descriptor)exceptexceptions.ValidationErrorasexception:forerrorinexception.errors:# handle individual errorA standalone function to infer a data package descriptor.descriptor=infer('**/*.csv')#{ profile: 'tabular-data-resource',#  resources:#   [ { path: 'data/cities.csv',#       profile: 'tabular-data-resource',#       encoding: 'utf-8',#       name: 'cities',#       format: 'csv',#       mediatype: 'text/csv',#       schema: [Object] },#     { path: 'data/population.csv',#       profile: 'tabular-data-resource',#       encoding: 'utf-8',#       name: 'population',#       format: 'csv',#       mediatype: 'text/csv',#       schema: [Object] } ] }Frequently Asked QuestionsAccessing data behind a proxy server?Before thepackage = Package("https://xxx.json")call set these environment variables:importosos.environ["HTTP_PROXY"]='xxx'os.environ["HTTPS_PROXY"]='xxx'API Referenceclicli()Command-line interfaceUsage: datapackage [OPTIONS] COMMAND [ARGS]...

Options:
  --version  Show the version and exit.
  --help     Show this message and exit.

Commands:
  infer
  validatePackagePackage(self,descriptor=None,base_path=None,strict=False,unsafe=False,storage=None,schema=None,default_base_path=None,**options)Package representationArgumentsdescriptor (str/dict): data package descriptor as local path, url or objectbase_path (str): base path for all relative pathsstrict (bool): strict flag to alter validation behavior.
Setting it toTrueleads to throwing errors
on any operation with invalid descriptorunsafe (bool):
ifTrueunsafe paths will be allowed. For more inforamtionhttps://specs.frictionlessdata.io/data-resource/#data-location.
Default toFalsestorage (str/tableschema.Storage): storage name likesqlor storage instanceoptions (dict): storage options to use for storage creationRaisesDataPackageException: raises error if something goes wrongpackage.base_pathPackage's base pathReturnsstr/None: returns the data package base pathpackage.descriptorPackage's descriptorReturnsdict: descriptorpackage.errorsValidation errorsAlways empty in strict mode.ReturnsException[]: validation errorspackage.profilePackage's profileReturnsProfile: an instance ofProfileclasspackage.resource_namesPackage's resource namesReturnsstr[]: returns an array of resource namespackage.resourcesPackage's resourcesReturnsResource[]: returns an array ofResourceinstancespackage.validValidation statusAlways true in strict mode.Returnsbool: validation statuspackage.get_resourcepackage.get_resource(name)Get data package resource by name.Argumentsname (str): data resource nameReturnsResource/None: returnsResourceinstances or null if not foundpackage.add_resourcepackage.add_resource(descriptor)Add new resource to data package.The data package descriptor will be validated with newly added resource descriptor.Argumentsdescriptor (dict): data resource descriptorRaisesDataPackageException: raises error if something goes wrongReturnsResource/None: returns addedResourceinstance or null if not addedpackage.remove_resourcepackage.remove_resource(name)Remove data package resource by name.The data package descriptor will be validated after resource descriptor removal.Argumentsname (str): data resource nameRaisesDataPackageException: raises error if something goes wrongReturnsResource/None: returns removedResourceinstances or null if not foundpackage.get_grouppackage.get_group(name)Returns a group of tabular resources by name.For more information about groups seeGroup.Argumentsname (str): name of a group of resourcesRaisesDataPackageException: raises error if something goes wrongReturnsGroup/None: returns aGroupinstance or null if not foundpackage.inferpackage.infer(pattern=False)Infer a data package metadata.Argumentpatternworks only for local filesIfpatternis not provided only existent resources will be inferred
(added metadata like encoding, profile etc). Ifpatternis provided
new resoures with file names mathing the pattern will be added and inferred.
It commits changes to data package instance.Argumentspattern (str): glob pattern for new resourcesReturnsdict: returns data package descriptorpackage.commitpackage.commit(strict=None)Update data package instance if there are in-place changes in the descriptor.Examplepackage=Package({'name':'package','resources':[{'name':'resource','data':['data']}]})package.name# packagepackage.descriptor['name']='renamed-package'package.name# packagepackage.commit()package.name# renamed-packageArgumentsstrict (bool): alterstrictmode for further workRaisesDataPackageException: raises error if something goes wrongReturnsbool: returns true on success and false if not modifiedpackage.savepackage.save(target=None,storage=None,merge_groups=False,to_base_path=False,**options)Saves this data packageIt saves it to storage ifstorageargument is passed or
saves this data package's descriptor to json file iftargetarguments
ends with.jsonor saves this data package to zip file otherwise.ExampleIt creates a zip file intofile_or_pathwith the contents
of this Data Package and its resources. Every resource which content
lives in the local filesystem will be copied to the zip file.
Consider the following Data Package descriptor:{"name":"gdp","resources":[{"name":"local","format":"CSV","path":"data.csv"},{"name":"inline","data":[4,8,15,16,23,42]},{"name":"remote","url":"http://someplace.com/data.csv"}]}The final structure of the zip file will be:./datapackage.json
./data/local.csvWith the contents ofdatapackage.jsonbeing the same as
returneddatapackage.descriptor. The resources' file names are generated
based on theirnameandformatfields if they exist.
If the resource has noname, it'll be usedresource-X,
whereXis the index of the resource in theresourceslist (starting at zero).
If the resource hasformat, it'll be lowercased and appended to thename,
becoming "name.format".Argumentstarget (string/filelike):
the file path or a file-like object where
the contents of this Data Package will be saved into.storage (str/tableschema.Storage):
storage name likesqlor storage instancemerge_groups (bool):
save all the group's tabular resoruces into one bucket
if a storage is provided (for example into one SQL table).
Read more aboutGroup.to_base_path (bool):
save the package to the package's base path
using the "<base_path>/" routeoptions (dict):
storage options to use for storage creationRaisesDataPackageException: raises if there was some error writing the packageReturnsbool/Storage: on success return true or aStorageinstanceResourceResource(self,descriptor={},base_path=None,strict=False,unsafe=False,storage=None,package=None,**options)Resource represenationArgumentsdescriptor (str/dict): data resource descriptor as local path, url or objectbase_path (str): base path for all relative pathsstrict (bool):
strict flag to alter validation behavior.  Setting it totrueleads to throwing errors on any operation with invalid descriptorunsafe (bool):
ifTrueunsafe paths will be allowed. For more inforamtionhttps://specs.frictionlessdata.io/data-resource/#data-location.
Default toFalsestorage (str/tableschema.Storage): storage name likesqlor storage instanceoptions (dict): storage options to use for storage creationRaisesDataPackageException: raises error if something goes wrongresource.dataReturn resource dataresource.descriptorPackage's descriptorReturnsdict: descriptorresource.errorsValidation errorsAlways empty in strict mode.ReturnsException[]: validation errorsresource.groupGroup nameReturnsstr: group nameresource.headersResource's headersOnly for tabular resources (reading has to be started first or it'sNone)Returnsstr[]/None: returns data source headersresource.inlineWhether resource inlineReturnsbool: returns true if resource is inlineresource.localWhether resource localReturnsbool: returns true if resource is localresource.multipartWhether resource multipartReturnsbool: returns true if resource is multipartresource.nameResource nameReturnsstr: nameresource.packagePackage instance if the resource belongs to some packageReturnsPackage/None: a package instance if availableresource.profileResource's profileReturnsProfile: an instance ofProfileclassresource.remoteWhether resource remoteReturnsbool: returns true if resource is remoteresource.schemaResource's schemaOnly for tabular resourcesFor tabular resources it returnsSchemainstance to interact with data schema.
Read API documentation -tableschema.Schema.Returnstableschema.Schema: schemaresource.sourceResource's sourceCombination ofresource.sourceandresource.inline/local/remote/multipartprovides predictable interface to work with resource data.Returnslist/str: returnsdataorpathpropertyresource.tableReturn resource tableresource.tabularWhether resource tabularReturnsbool: returns true if resource is tabularresource.validValidation statusAlways true in strict mode.Returnsbool: validation statusresource.iterresource.iter(integrity=False,relations=False,**options)Iterates through the resource data and emits rows cast based on table schema.Only for tabular resourcesArgumentskeyed (bool):
    yield keyed rows in a form of `{header1: value1, header2: value2}`
    (default is false; the form of rows is `[value1, value2]`)

extended (bool):
    yield extended rows in a for of `[rowNumber, [header1, header2], [value1, value2]]`
    (default is false; the form of rows is `[value1, value2]`)

cast (bool):
    disable data casting if false
    (default is true)

integrity (bool):
    if true actual size in BYTES and SHA256 hash of the file
    will be checked against `descriptor.bytes` and `descriptor.hash`
    (other hashing algorithms are not supported and will be skipped silently)

relations (bool):
    if true foreign key fields will be checked and resolved to its references

foreign_keys_values (dict):
    three-level dictionary of foreign key references optimized
    to speed up validation process in a form of
    `{resource1: {(fk_field1, fk_field2): {(value1, value2): {one_keyedrow}, ... }}}`.
    If not provided but relations is true, it will be created
    before the validation process by *index_foreign_keys_values* method

exc_handler (func):
    optional custom exception handler callable.
    Can be used to defer raising errors (i.e. "fail late"), e.g.
    for data validation purposes. Must support the signature belowCustom exception handlerdefexc_handler(exc,row_number=None,row_data=None,error_data=None):'''Custom exception handler (example)# Arguments:exc(Exception):Deferred exception instancerow_number(int):Data row number that triggers exception excrow_data(OrderedDict):Invalid data row source dataerror_data(OrderedDict):Data row source data field subset responsible for the error, ifapplicable (e.g. invalid primary or foreign key fields). May beidentical to row_data.'''# ...RaisesDataPackageException: base class of any errorCastError: data cast errorIntegrityError: integrity checking errorUniqueKeyError: unique key constraint violationUnresolvedFKError: unresolved foreign key reference errorReturnsIterator[list]: yields rowsresource.readresource.read(integrity=False,relations=False,foreign_keys_values=False,**options)Read the whole resource and return as array of rowsOnly for tabular resources
It has the same API asresource.iterexcept forArgumentslimit (int): limit count of rows to read and returnReturnslist[]: returns rowsresource.check_integrityresource.check_integrity()Checks resource integrityOnly for tabular resourcesIt checks size in BYTES and SHA256 hash of the file
againstdescriptor.bytesanddescriptor.hash(other hashing algorithms are not supported and will be skipped silently).Raisesexceptions.IntegrityError: raises if there are integrity issuesReturnsbool: returns True if no issuesresource.check_relationsresource.check_relations(foreign_keys_values=False)Check relationsOnly for tabular resourcesIt checks foreign keys and raises an exception if there are integrity issues.Raisesexceptions.RelationError: raises if there are relation issuesReturnsbool: returns True if no issuesresource.drop_relationsresource.drop_relations()Drop relationsOnly for tabular resourcesRemove relations data from memoryReturnsbool: returns Trueresource.raw_iterresource.raw_iter(stream=False)Iterate over data chunks as bytes.Ifstreamis true File-like object will be returned.Argumentsstream (bool): File-like object will be returnedReturnsbytes[]/filelike: returns bytes[]/filelikeresource.raw_readresource.raw_read()Returns resource data as bytes.Returnsbytes: returns resource data in bytesresource.inferresource.infer(**options)Infer resource metadataLike name, format, mediatype, encoding, schema and profile.
It commits this changes into resource instance.Argumentsoptions:
options will be passed totableschema.infercall,
for more control on results (e.g. for settinglimit,confidenceetc.).Returnsdict: returns resource descriptorresource.commitresource.commit(strict=None)Update resource instance if there are in-place changes in the descriptor.Argumentsstrict (bool): alterstrictmode for further workRaisesDataPackageException: raises error if something goes wrongReturnsbool: returns true on success and false if not modifiedresource.saveresource.save(target,storage=None,to_base_path=False,**options)Saves this resourceInto storage ifstorageargument is passed or
saves this resource's descriptor to json file otherwise.Argumentstarget (str):
path where to save a resourcestorage (str/tableschema.Storage):
storage name likesqlor storage instanceto_base_path (bool):
save the resource to the resource's base path
using the "<base_path>/" routeoptions (dict):
storage options to use for storage creationRaisesDataPackageException: raises error if something goes wrongReturnsbool: returns true on success
Building index...
Started generating documentation...GroupGroup(self,resources)Group representationArgumentsResource[]: list of TABULAR resourcesgroup.headersGroup's headersReturnsstr[]/None: returns headersgroup.nameGroup nameReturnsstr: namegroup.schemaResource's schemaReturnstableschema.Schema: schemagroup.itergroup.iter(**options)Iterates through the group data and emits rows cast based on table schema.It concatenates all the resources and has the same API asresource.itergroup.readgroup.read(limit=None,**options)Read the whole group and return as array of rowsIt concatenates all the resources and has the same API asresource.readgroup.check_relationsgroup.check_relations()Check group's relationsThe same asresource.check_relationsbut without the optional
argumentforeign_keys_values.  This method will test foreignKeys of the
whole group at once otpimizing the process by creating the foreign_key_values
hashmap only once before testing the set of resources.ProfileProfile(self,profile)Profile representationArgumentsprofile (str): profile name in registry or URL to JSON SchemaRaisesDataPackageException: raises error if something goes wrongprofile.jsonschemaJSONSchema contentReturnsdict: returns profile's JSON Schema contentsprofile.nameProfile nameReturnsstr/None: name if availableprofile.validateprofile.validate(descriptor)Validate a data packagedescriptoragainst the profile.Argumentsdescriptor (dict): retrieved and dereferenced data package descriptorRaisesValidationError: raises if not validReturnsbool: returns True if validvalidatevalidate(descriptor)Validate a data package descriptor.Argumentsdescriptor (str/dict): package descriptor (one of):
- local path
- remote url
- objectRaisesValidationError: raises on invalidReturnsbool: returns true on validinferinfer(pattern,base_path=None)Infer a data package descriptor.Argumentpatternworks only for local filesArgumentspattern (str): glob file patternReturnsdict: returns data package descriptorDataPackageExceptionDataPackageException(self,message,errors=[])Base class for all DataPackage/TableSchema exceptions.If there are multiple errors, they can be read from the exception object:try:# lib actionexceptDataPackageExceptionasexception:ifexception.multiple:forerrorinexception.errors:# handle errordatapackageexception.errorsList of nested errorsReturnsDataPackageException[]: list of nested errorsdatapackageexception.multipleWhether it's a nested exceptionReturnsbool: whether it's a nested exceptionTableSchemaExceptionTableSchemaException(self,message,errors=[])Base class for all TableSchema exceptions.LoadErrorLoadError(self,message,errors=[])All loading errors.CastErrorCastError(self,message,errors=[])All value cast errors.IntegrityErrorIntegrityError(self,message,errors=[])All integrity errors.RelationErrorRelationError(self,message,errors=[])All relations errors.StorageErrorStorageError(self,message,errors=[])All storage errors.ContributingThe project follows theOpen Knowledge International coding standards.Recommended way to get started is to create and activate a project virtual environment.
To install package and development dependencies into active environment:$makeinstallTo run tests with linting and coverage:$maketestChangelogHere described only breaking and the most important changes. The full changelog and documentation for all released versions could be found in nicely formattedcommit history.v1.15WARNING: it can be breaking for some setups, please read the discussions belowFixed header management according to the specs:https://github.com/frictionlessdata/datapackage-py/pull/257https://github.com/frictionlessdata/datapackage-py/issues/256https://github.com/frictionlessdata/forum/issues/1v1.14Add experimental options for pick/skiping fileds/rowsv1.13Addunsafeoption to Package and Resource (#262)v1.12Usechardetfor encoding deteciton by default. Forcchardet:pip install datapackage[cchardet]v1.11resource/package.savenow accept ato_base_pathargument (#254)package.savenow returns aStorageinstance if availablev1.10Added an ability to check tabular resource's integrityv1.9Addedresource.packagepropertyv1.8Added support forgroups of resourcesv1.7Added support forcompression of resourcesv1.6Added support for custom request sessionv1.5Updated behaviour:Added support for Python 3.7v1.4New API added:addedskip_rowssupport to the resource descriptorv1.3New API added:propertypackage.base_pathis now publicly availablev1.2Updated behaviour:CLI command$ datapackage infernow outputs only a JSON-formatted data package descriptor.v1.1New API added:Added an integration betweenPackage/Resourceand thetableschema.Storage-https://github.com/frictionlessdata/tableschema-py#storage. It allows to load and save data package from/to different storages like SQL/BigQuery/etc.